Page 1 sur 1

Transparence avec AlphaBlend_()

Publié : lun. 21/août/2006 15:20
par Anonyme2
Voici un peti bout de code qui affiche une image de complètement transparente à totalement opaque pendant un petit laps de temps.

C'est plus l'application de l'API windows AlphaBlend_() qu'un truc.

Le code serait peut-être mieux si on redessinait dans une callback, mais c'est fait sans.

Le principe de cette API est de dessiner par dessus l'image existante (via le dc), en surimpression (dans le code, les images se supperposent). Elle permet de modifier la couche alpha globale (pour tous les pixels) dans le mode que j'ai utilisé (l'élément AlphaFormat de la structure BLENDFUNCTION vaut 0 --> a couche alpha source est ignorée et remplacée pour chaque pixel par la valeur du membre SourceConstantAlpha de cette même structure, les valeurs de la couche alpha évoluant de 0 (totament transparent) à 255 (totalement opaque).

Le code est ici (il trop long pour le forum à cause de l'image que j'ai convertie en data)

Publié : lun. 21/août/2006 15:39
par Dr. Dri
Le code a planté chez moi, il faut mettre des StopDrawing avant chaque ProcedureReturn. Sinon j'ai testé avec XP et ca marche, je vais essayer de voir pk ca passe pas avec windows 98

Dri

Publié : lun. 21/août/2006 16:56
par Anonyme2
Merci Dri,

j'ai corrigé le zip (Mis le stopDrawing() oublié du 1er procedurereturn et testé que stardrawing n'a pas échoué au préalable)

Normalement il me semble que AlphaBlend est supporté par WIn98

Publié : jeu. 24/août/2006 20:24
par Anonyme2
Tu as trouvé le problème avec Win98 ?
Requirements
Windows NT/2000/XP: Included in Windows 2000 and later.
Windows 95/98/Me: Included in Windows 98 and later.
Header: Declared in Wingdi.h; include Windows.h.
Library: Included as a resource in Msimg32.dll.
Si je comprend bien, ça devrait tourner sous 98

Publié : jeu. 24/août/2006 22:43
par Dr. Dri
J'ai testé sur mon PC où y'a XP c'est nickel ^^
Sur ce PC y'a également un windows 98 et dessus ca tourne

Je suis donc revenu tester sur ce PC et c'est nickel ^^
Pourtant quand j'avais ajouté les stopdrawing et recompilé ca ne marchait pas.

Enfin bon plus de problème ^^

Dri

Publié : ven. 25/août/2006 3:59
par Anonyme2
Merci :D

Publié : mer. 23/janv./2008 11:06
par Niffo
Euh ... à quoi sert la déclaration et le remplissage de la structure bmi.BITMAPINFO dans cet exemple précis ?

Publié : mer. 23/janv./2008 15:21
par Anonyme2
A rien :D

c'est un reste des mes essais, tu peux supprimer et mettre la taille correspondante de l'image pour le CallFunctionFast

voici le code modifié mais sans les datas que tu ajouteras (ne passe pas sur le forum, trop long)


Code : Tout sélectionner

EnableExplicit

Enumeration
     #MainWindow
     #ImageGadget = 0
     #ImageOrigine ; l'image chargée qui ne change pas
     #Image        ; l'image qui va évoluer
EndEnumeration


#AC_SRC_OVER = 0
#AC_SRC_ALPHA = 1
#Erreur = -1

Global i.l, j.l

Global bf.BLENDFUNCTION ; structure pour la couche alpha


Procedure DrawTransparentGlobal(Niveau.l)
     
     Protected hdcSource.l           ; handle du DC à créer qui est le source pour AlphaBlend
     Protected hdc_Image_evolue.l    ; handle du DC de l'image qui va évoluer
     Protected Addresse_AlphaBlend.l ; l'adresse de l'API AlphaBlend_()
     
           If OpenLibrary(0, "Msimg32.dll")
                Addresse_AlphaBlend = GetFunction(0, "AlphaBlend")
                
                If IsImage(#Image) And IsImage (#ImageOrigine)
                     
                     hdc_Image_evolue = StartDrawing(ImageOutput(#Image))
                     hdcSource = CreateCompatibleDC_(hdc_Image_evolue)
                     If hdcSource = 0
                          ProcedureReturn #Erreur
                     EndIf
                          
                     ; on sélectionne l'image d'origine dans le DC, celle de référence
                     SelectObject_(hdcSource, ImageID(#ImageOrigine))
                     ; on attribue la nouvelle valeur de transparence à l'élément de la structure
                     If Niveau < 0
                          Niveau = 0
                     ElseIf Niveau > 255
                         Niveau = 255
                     EndIf
                     
                     bf\SourceConstantAlpha = Niveau
                          
                     ; on exécute l'API AlphaBlend_()
                     If Addresse_AlphaBlend
                          If (CallFunctionFast(Addresse_AlphaBlend, hdc_Image_evolue, 0, 0,ImageWidth(#Image),ImageHeight(#Image), hdcSource, 0, 0,ImageWidth(#Image),ImageHeight(#Image), PeekL( @bf)) = #False)
                               StopDrawing()
                               DeleteDC_(hdcSource)
                               CloseLibrary(0)
                               MessageRequester("Erreur", "l'API AlphaBlend_() a échoué  ", 16)
                               ProcedureReturn
                          EndIf
                     EndIf
                StopDrawing()
                DeleteDC_(hdcSource)
                InvalidateRect_(GadgetID(#ImageGadget), 0, #True)
                CloseLibrary(0)
           EndIf
EndIf

EndProcedure


;/ ////////////////////////
;- programme principal
;/ ////////////////////////
; initialisation des éléments de la transparence
; ----------------------------------------------
; bf\BLENDFUNCTION ; structure pour la couche alpha
; bf\BlendOp = #AC_SRC_OVER --> toujours, voir doc
bf\BlendOp = #AC_SRC_OVER
bf\BlendFlags = 0 ; toujours à 0, voir doc
; bf\SourceConstantAlpha, c'est le niveau de transparence de l'image
; si bf\AlphaFormat = 0, la transparence de chaque pixel est ignorée,
; la transparence (couche alpha) appliquée est celle de bf\SourceConstantAlpha
; bf\SourceConstantAlpha varie de 0 (totalement transparent à 255, totalement opaque
bf\SourceConstantAlpha = 0 ; totalement tranbsparent au début
bf\AlphaFormat = 0 ; la couche alpha source est ignorée et remplacée pour chaque pixel
; par bf\SourceConstantAlpha

If CatchImage(#ImageOrigine, ?Logo) And CreateImage(#Image, ImageWidth(#ImageOrigine), ImageHeight(#ImageOrigine), 32)
      ; #Image va évoluer et a la couleur du fond de la fenêtre au début
      If StartDrawing(ImageOutput(#Image))
                For i = 0 To ImageWidth(#Image) - 1
                     For j = 0 To ImageHeight(#Image) - 1
                          Plot(i, j, GetSysColor_(#COLOR_BTNFACE))
                     Next j
                Next i
           StopDrawing()
      EndIf
      
      If OpenWindow(#MainWindow, 0, 0, 450 , 180, " PureBasic 4.00 - Transparence - Couche ALPHA Globale", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
           If CreateGadgetList(WindowID(#MainWindow))
                ImageGadget(#ImageGadget, (WindowWidth(#MainWindow) / 4) - 5, 50 - 32, (WindowWidth(#MainWindow) / 2) + 4, (WindowHeight(#MainWindow) / 2) + 5, ImageID(#Image), #PB_Image_Border)
                
                For i = 1 To 100
                     DrawTransparentGlobal((i/3))
                     UpdateWindow_(GadgetID(#ImageGadget))
                     Delay(55)
                Next i
                DrawTransparentGlobal(255)
                
                Repeat
                     If WaitWindowEvent() = #PB_Event_CloseWindow
                          Break
                     EndIf
                ForEver
           EndIf
      EndIf
EndIf
End

Publié : mer. 23/janv./2008 17:39
par Niffo
Denis a écrit :A rien :D

c'est un reste des mes essais, tu peux supprimer et mettre la taille correspondante de l'image pour le CallFunctionFast
J'avais rectifié de moi-même ;)

Merci pour cet exemple en tout cas.
En fait, il n'y a que 3 pov' fonctions dans cette msimg32.dll (AlphaBlend, GradientFill et TransparentBlit) : sans doute pour rattraper un peu le retard de gdi32.

Pour mes besoins, ça sera donc GDI+ (merci à je ne sais plus qui pour le boulot fourni à ce sujet sur le forum d'ailleurs !)
Ca manque cruellement à PB ça des fonctions bitmap (lib 2D) puissantes et surtout rapides et indépendantes de l'OS.

Publié : mer. 23/janv./2008 17:41
par Anonyme2
Niffo a écrit :Pour mes besoins, ça sera donc GDI+ (merci à je ne sais plus qui pour le boulot fourni à ce sujet sur le forum d'ailleurs !)
Ca manque cruellement à PB ça des fonctions bitmap (lib 2D) puissantes et surtout rapides et indépendantes de l'OS.
C'est moi :D