HBITMAP avec transparence

CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 - 21 avril 2004 à 10:41
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 - 22 avril 2004 à 23:13
Est ce que quelqu'un sait mettre en transparence une couleur d'un HBITMAP (en l'occurence RGB(255,0,255)) ?

J'ai cherché une demi heure dans le MSDN sans succès... (en tout cas rien pour une simple bitmap)

CyberP,
Celui qui dit que toute question a une réponse

25 réponses

cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
21 avril 2004 à 12:13
bah en fait cela est possible.
Il suffit de faire BitBlit avec l'option non pas COPY mais AND ou XOR, et ta transparence doit etre de couleur noir

Bon en gros tu reflefhis un peut sur les oprerations logiques AND XOR OR ..., et ca devrai marche.
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 13:06
Je ne peux pas utiliser BitBlt parce que dans mon script, j'insère un HBITMAP dans un RichEdit... Je ne peux que modifier le HBITMAP avant de l'insérer

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
21 avril 2004 à 13:42
Récupère la couleur de fond du richedit, et applique cette couleur à tes pixels de couleurs RGB(255,0,255)...

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 13:45
Oui j'ai déjà eu l'idée, mais je ne trouve rien non plus pour modifier la couleur (à moins de changer manuellement, mais je ne sais pas comment faire pour récupérer la taille ou les bits)

CyberP,
Celui qui dit que toute question a une réponse
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
21 avril 2004 à 14:00
Tu peux récupèrer le tableau de bits de l'image avec la fonction GetDIBits (à ce moment là, il faut créer au préalable un DC !) puis faire tes modifications dans ce tableau.

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 14:36
Merci, ca commence à marcher

CyberP,
Celui qui dit que toute question a une réponse
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 18:35
Non ca ne marche toujours pas...

Mon code est :

CBitmap tmpbmp;
tmpbmp.LoadBitmap(smile);
HBITMAP hBitmap = (HBITMAP)tmpbmp;
BITMAPINFO bitMapInfo;
GetDIBits(GetDC(), hBitmap, 0, 20, NULL, &bitMapInfo, DIB_RGB_COLORS);
int rred = bitMapInfo.bmiColors[0].rgbRed;
int ggreen = bitMapInfo.bmiColors[0].rgbGreen;
int bblue = bitMapInfo.bmiColors[0].rgbBlue;
for (int i = 0; i < 324/*bitMapInfo.bmiHeader.biHeight * bitMapInfo.bmiHeader.biWidth*/; i++) {
  if (bitMapInfo.bmiColors[i].rgbRed == rred && bitMapInfo.bmiColors[i].rgbGreen == ggreen && bitMapInfo.bmiColors[i].rgbBlue == bblue) {
    bitMapInfo.bmiColors[i].rgbRed = 0;//GetRValue(WinUtil::bgColor);
    bitMapInfo.bmiColors[i].rgbGreen = 0;//GetGValue(WinUtil::bgColor);
    bitMapInfo.bmiColors[i].rgbBlue = 128;//GetBValue(WinUtil::bgColor);
  }
}
SetDIBits(GetDC(), hBitmap, 0, 20, NULL, &bitMapInfo, DIB_RGB_COLORS);
CImageDataObject::InsertBitmap(ctrlClient.GetOleInterface(), hBitmap);


les 3 premières lignes ainsi que la dernière "fonctionnent"
la couleur de fond est rgb(0,0,128)
là où j'ai mis des commentaires pour tester (normalement ce n'est pas des commentaires)
le GetDC() fonctionne car il y a un morceau de code planqué quelque part (je modifie un programme existant) qui fait que ca revienne à hWnd.GetDC()

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
21 avril 2004 à 18:50
Il faut renseigner la taille de la structure BITMAPINFOHEADER :

bitmapinfo.bmiHeader.biSize = sizeof(bitmapinfo);

De même, il faut renseigner la hauteur et la largeur de ton bitmap dans ton bitmapinfo :
bitMapInfo.bmiHeader.biHeight et bitMapInfo.bmiHeader.biWidth

Enfin, je ne vois pas trop comment tu fais pour modifier tes bits comme cà... J'ai toujours récupèrer le tableau de bits du bitmap puis traiter ce tableau directement. Apparement, ce n'est pas ce que tu fais... je ne sais pas si on peux faire directement comme tu fais ! Il faudrait quelqu'un qui s'y connaissent mieux en C que moi, car mes connaissances sont bien faibles en C !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 19:35
Oui mais le problème est que je ne sais pas comment récupérer la taille de mes bitmap (ils n'ont pas tous la même taille)

Sinon je trouve un peu idiot qu'il faille déjà "compléter les informations" alors qu'on récupère des données

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
21 avril 2004 à 19:48
C'est comme pour les fonctions manipulant les chaînes de caractères : il faut leur indiquer où ca s'arrête avec le caractère '\0', ben ici, il faut leur indiquer la taille du bitmap...

Sinon, essaye avec la fonction GetBitmapBits, cette fonction devrait être banie sur des systèmes 32 bits, mais elle est plus simple à utiliser, et en plus, elle est toujours présente sous Win32 !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
21 avril 2004 à 20:03
Non mais je trouve idiot de créer un objet, de récupérer des données sur un bitmap à l'intérieur et qu'il faille soi même définir la taille de l'image, alors que la fonction devrait pouvoir la renvoyer..

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
21 avril 2004 à 20:05
Je n'ai jamais dit le contraire que c'était idiot, mais c'est comme cà ! ;-)

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
22 avril 2004 à 00:39
pour récupérer la taille d'un bitmap (attention c'est bien BITMAP la structure et par HBITMAP) :
BITMAP info;
GetObject(hBitmap, sizeof(BITMAP), &info);

ensuite, pour récupérer les pixels du bitmap, il faut remplir une structure BITMAPINFO :
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = info.bmWidth;
bi.bmiHeader.biHeight = info.bmHeight;
bi.bmiHeader.biPlanes = info.bmPlanes;
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biCompression = BI_RGB;

(en ce qui concerne biPlanes, ca sera plus facile d'accéder aux bits si on force à 24 bits par pixel la récup, cependant, je ne sais pas si on peut mettre une valeur différente de info.bmBitCount).

allocation mémoire pour récupérer les pixels
attention : la largeur d'une ligne en mémoire doit être multiple de 4 octets, avec bourrage si nécessaire
DWORD dwWidthBytes = (3*info.bmWidth+3)/4;
DWORD dwImageSize = dwWidthBytes*info.bmHeight;
LPBYTE lpBits = new BYTE[dwImageSize];

récupération:
HDC hdc = GetDC(NULL);
GetDIBits(hdc, hBitmap, 0, info.bmHeight, &lpBits, &bi, DIB_RGB_COLORS);

accès au pixel de coordonnées (x, y)
attention : les bitmap sont des bottom-up, ie la ligne 0 est en bas et croit en montant (sauf si la taille du bitmap est négative).

RED = lpBits[y*dwWidthBytes+3*x];
GREEN = lpBits[y*dwWidthBytes+3*x+1];
BLUE = lpBits[y*dwWidthBytes+3*x+2];

si le bitmap a une pronfondeur autre que 24 bits par pixels, l'accès n'est pas le même (ma source Paint donne les formule pour 1, 2, 4 et 8 bits par pixel avec une palette de couleur)

pour information, le tableau bmiColors de la structure BITMAPINFO donne la palette de couleur du bitmap pour 1, 2, 4 ou 8 bits par pixel.
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
22 avril 2004 à 09:20
Merci beaucoup !

Là ca plante au moment du GetDIBits mais là il faut que je voie moi même...

CyberP,
Celui qui dit que toute question a une réponse
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
22 avril 2004 à 10:40
Au fait tant que j'y suis : quelqu'un sait comment redimensionner mon HBITMAP ?

CyberP,
Celui qui dit que toute question a une réponse
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
22 avril 2004 à 11:45
sorry, j'ai fait une erreur pour la largeur en octet du bitmap :

dwWidthBytes = 4*((3*info.bmWidth+3)/4);

pour redimensionner ton HBITMAP, tu en crée un nouveau et tu recopie l'ancien avec StrechBlt :

// création nouveau
HDC hdc = GetDC(NULL);
HDC hBmpDC1 = CreateCompatibleDC(hdc);
HBITMAP hNewBitmap = CreateCompatibleBitmap(hdc, newcx, newcy);
HBITMAP hOldBmpDC1 = (HBITMAP) SelectObject(hBmpDC1, hNewBitmap);

// sélection ancien dans un DC
HDC hBmpDC2 = CreateCompatibleDC(hdc);
HBITMAP hOldBmpDC2 = (HBITMAP) SelectObject(hBmpDC2, hBitmap);

// recopie avec mise à l'échelle
StretchBlt(hBmpDC1, 0, 0, newcx, newcy, hBmpDC2, 0, 0, oldcx, oldcy, SRCCOPY);

// libération ressources
SelectObject(hBmpDC1, hOldBmpDC1);
SelectObject(hBmpDC2, hOldBmpDC2);
DeleteDC(hBmpDC1);
DeleteDC(hBmpDC2);
ReleaseDC(NULL, hdc);
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
22 avril 2004 à 15:14
Aaaahhhh d'accord je ne comprenais pas le /4 !

Bon ca plante encore... c'est assez bizarre
Sinon le redimensionnement marche, merci

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
22 avril 2004 à 15:19
Heu... le "+3" dans 4*((3*info.bmWidth+3)/4); sert à quoi ? J'aurais plutôt mis : 4*((3*info.bmWidth)/4);
... à tester !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
CyberP Messages postés 283 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 4 juillet 2007 2
22 avril 2004 à 15:46
3*info.bmWidth+3 = 3*(info.bmWidth+1) je pense qu'il a ajouté 1 pour une valeur null

Sinon je me suis souvenu de TransparentBlt qui marche comme StretchBlt (mais je ne savais pas comment faire juste avec un hBitmap) je suis en train de tester

CyberP,
Celui qui dit que toute question a une réponse
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
22 avril 2004 à 15:49
Oui, transparentBlt peut faire l'affaire mais attention : elle est incompatible avec Windows 95/98, ce qui limite pas mal le déploirement !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
Rejoignez-nous