psy4meuh
Messages postés23Date d'inscriptionjeudi 5 juin 2003StatutMembreDernière intervention23 août 2006
-
12 oct. 2005 à 08:44
jpthomasset
Messages postés95Date d'inscriptionsamedi 19 juin 2004StatutMembreDernière intervention20 avril 2010
-
14 oct. 2005 à 10:13
Bonjour à tous,
je suis en train de basculer un de mes anciens programes d'affichage d'icones en GDI+, et je suis face à un problème bizare :
Les parties complettement transparentes des icones sont OK, mais les transparences 'partielles' s'affichent en noir... alors que dans l'ancienne vesion (BitBlt...) tout était OK...
Pour mieux comprendre, une petite image vaut mieux qu'un grand discours :
Honnetement, je me demance si cela ne viendrais pas du fait que en GDI classique, pour utiliser l'alpha blending, il fallait prémultiplier les couleurs par l'alpha, alors qu'en GDI+ ce n'est pas le cas.
Une idée à creuser, est peut-etre de charger les icones directement depuis le fichier de resource dans GDI+ avec la fonction Image::FromStream, il est possible que dans ce cas tes icones soient extraites normalement : Perso j'utilise cette technique pour mes images, mais ce sont des PNG.
psy4meuh
Messages postés23Date d'inscriptionjeudi 5 juin 2003StatutMembreDernière intervention23 août 2006 12 oct. 2005 à 16:42
Peut être pas un bug, mais à mon avis le GDI+ ne gère pas le "24bppARGB",je vais essayer de transformer les icones en "32bppARGB"après lecture, mais il faut que je les lisent dirrectement... genre avec le hbmColor de ICONINFO...., j'vais essayer...
Vous n’avez pas trouvé la réponse que vous recherchez ?
jpthomasset
Messages postés95Date d'inscriptionsamedi 19 juin 2004StatutMembreDernière intervention20 avril 2010 12 oct. 2005 à 17:28
Ben, en fait les icones en 24bits plus un layer alpha sont équivalentes
à des images en 32bppARGB. La différence est (il me semble) dans
l'organisation des données (je crois que les icones ont un bitmap qui
contient uniquement les valeurs alpha et un autre pour les couleurs
24bits).
Normalement, GDI+ devrait donc créer un bitmap en 32bpp à partir de ton icone, mais il y a sans doute un bug...
jpthomasset
Messages postés95Date d'inscriptionsamedi 19 juin 2004StatutMembreDernière intervention20 avril 2010 12 oct. 2005 à 17:42
Petite correction les icones en 32 bits, contiennent en fait un bitmap
de 1bit qui sert de masque et un bitmap de 32 bits (24 pour les
couleurs et 8 pour l'alpha).
Il est probable que GDI+ utilise le bitmask au lieu de l'alpha.
psy4meuh
Messages postés23Date d'inscriptionjeudi 5 juin 2003StatutMembreDernière intervention23 août 2006 13 oct. 2005 à 08:55
Ok, ca marche... c bien ce que je pensait, le GDI+ ne gère pas bien le format de l'icone à cause du masque je pense, donc je prends la parie couleur(+alpha) de l'icone par 'GetIconInfo' et je crée un Bitmap GDI+ au format 32bppARGB... voilà mon code :
/**************************************************************************/
//hIcon loadé par un LoadImage ou ExtractIcon
PICONINFO ii = new ICONINFO;
GetIconInfo(hIcon, ii);
BOOL IsAlpha = false;
Color c1(0,0,0,0);
for (int y=0; y <= bmp.GetHeight()-1; y++) {
for (int x=0; x <= bmp.GetWidth()-1; x++) {
dstBitmap.GetPixel(x,y,&c1);
if (c1.GetA()>0 & c1.GetA()<255) IsAlpha=true;
}
}
bmp.UnlockBits(&bmData);
if (IsAlpha) {
graphics.DrawImage(&dstBitmap,0,0,Taille,Taille);
}
else {
Bitmap bmp2(hIcon);
graphics.DrawImage(&bmp2,0,0,Taille,Taille);
delete &bmp2;
}
/**************************************************************************/
Je vérifie au passage que l'icone contient bien de la transparence partielle (0<Alpha<255) sinon la transparence totale saute au passage.
Par contre j'aurai besoin d'un complément d'aide sur comment afficher cet icone sur une fenetre complètement transparente... j'ai essayé avec un SetLayeredWindowAttributes, mais on peut spécifier qu'une colorkey, donc encore une fois, la transparence complète est ok, mais pas la partielle... tu peux encore m'aider?
jpthomasset
Messages postés95Date d'inscriptionsamedi 19 juin 2004StatutMembreDernière intervention20 avril 2010 13 oct. 2005 à 10:02
Salut,
Effectivement, cela vient sans doute de la conversion dans GDI+. Dans
tes boucles for, je te conseille de sortir des boucles dès que IsAlpha
est vrai, ca t'evitera de parcourir tout les pixels si tu trouve une
valeur alpha dans les premiers pixels.
Je pense que tu aurais pu t'en sortir en regardant simplement le nombre
de bits par pixel de ii->hbmColor avec GetObject, a mon avis il doit
donner 32 dans le cas d'un image avec une valeur alpha.
Pour ton problème de fenetre transparente, il me semble que
SetLayeredWindowAttributes ne sert que si l'on veut une fenetre avec
des parties completement transparentes (avec une colorkey) ou alors si
on veut appliquer le même alpha à toute la fenetre (la valeur bAlpha).
Si tu veux une fenetre avec des valeurs alpha par pixel, il faut créer
ta fenetre avec les styles WS_EX_LAYERED et WS_EX_TRANSPARENT et
ensuite utiliser la fonction UpdateLayeredWindow qui fonctionne un peu
comme la fonction AlphaBlend. Je pense aussi qu'avec GDI+ on peut aussi
utiliser DrawImage avec une image en 32bppARGB au lieu de la fonction
UpdateLayeredWindow, mais c'est a vérifier.
psy4meuh
Messages postés23Date d'inscriptionjeudi 5 juin 2003StatutMembreDernière intervention23 août 2006 13 oct. 2005 à 15:40
Bon, j'suis carrément perdu dans l'histoire de fenetre avec alpha par pixel... je crée ma fenetre avec WS_EX_LAYERED et WS_EX_TRANSPARENT, par contre je comprends pas comment utiliser la fonction UpdateLayeredWindow... Voilà ce que j'ai fait :
Mais ca ne me donne rien, j'comprends pas... il faut bien spécifier à 'UpdateLayeredWindow' le HDC qu'on veut afficher dans la fenetre.Pour infos j'ai mis ca dans l'evenement PAINT de ma fenêtre... help me JP!!!!
jpthomasset
Messages postés95Date d'inscriptionsamedi 19 juin 2004StatutMembreDernière intervention20 avril 2010 14 oct. 2005 à 08:28
De mémoire, lorsque l'on utilise WS_EX_LAYERED, le message WM_PAINT
n'est plus envoyé, en fait le mécanisme de rafraichissement de la
fenetre est différent : lorsque tu utilise UpdateLayeredWindow tu donne
une image de la fenetre au système qui se charge de l'afficher, c'est a
toi de décider quand tu doit rafraichir cette image.