Transparence avec AlphaBlend_()

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Transparence avec AlphaBlend_()

Message 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)
Dernière modification par Anonyme2 le lun. 21/août/2006 17:43, modifié 1 fois.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci :D
Niffo
Messages : 108
Inscription : dim. 29/août/2004 15:51

Message par Niffo »

Euh ... à quoi sert la déclaration et le remplissage de la structure bmi.BITMAPINFO dans cet exemple précis ?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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
Niffo
Messages : 108
Inscription : dim. 29/août/2004 15:51

Message 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.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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
Répondre