Comment Prendre la valeur de l'Alpha sur une Image 32 Bit

Programmation d'applications complexes
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Comment Prendre la valeur de l'Alpha sur une Image 32 Bit

Message par Thyphoon »

Vu les problèmes de compatibilités multiplatforme (windows/linux/macOsx) pour les icons des menus j'ai réussi a trouvé un code que j'ai modifié pour convertir a la volé mes images PNG 32 Bit en icon pour la version windows
ça marche tres bien ...sauf pour la transparence que je ne sais pas comment trouver dans une Image vu que Drawingbuffer ne marche pas avec ImageOutput() et que point(x,y) ne retourne que la couleur :(

Si quelqu'un a une idée...car là ça fait plusieur jour que je cherche en vain sur tout les forums ...

Voici le code qui me sert pour transformer une image en .ico

Code : Tout sélectionner

Procedure  convert2ico(image.l)

ResizeImage(image,16,16)
Debug ImageDepth(image)
hauteur=ImageHeight(image)
largeur=ImageWidth(image)
;saveicon(filename$,hauteur,largeur, ColorKey)
buffer=AllocateMemory(10000)
If buffer
;-------------------------------ICONDIR structure
      offset=poke(buffer,offset,0,1)                  ;reserved must be 0                (WORD)0
      offset=poke(buffer,offset,1,1)                  ;ressource type icon=1               (WORD)2
      offset=poke(buffer,offset,1,1)                  ;how many images 1                  (WORD)4
      ;-------------------------------ICONDIR ENTRY
      offset=poke(buffer,offset,largeur,0)      ;width in pixel of the picture         (BYTE)6
      offset=poke(buffer,offset,hauteur,0)      ;height in pixel of the picture         (BYTE)7
      offset=poke(buffer,offset,0,0)                  ;#color in image 0 if >8bpp          (BYTE)8
      offset=poke(buffer,offset,0,0)                  ;reserved must be 0                (BYTE)9
      offset=poke(buffer,offset,1,1)                  ;color planes                      (WORD)10
      offset=poke(buffer,offset,32,1)                  ;bit per pixel                     (WORD)12
      bytecount=((largeur*hauteur)*4);x,y*4 bytes
      offset=poke(buffer,offset,bytecount+40+(largeur*hauteur)/8,2)   ;how many bytes in this ressource      (DWORD)14
      offset=poke(buffer,offset,offset+4,2)            ;where in the file is the bitmap data   (DWORD)18
      ;--------------------------------DIB header
      offset=poke(buffer,offset,40,2)                  ;lenght of the header               (DWORD)22
      offset=poke(buffer,offset,largeur,2)      ;width in pixel of the picture         (DWORD)26
      offset=poke(buffer,offset,hauteur*2,2)      ;width in pixel of the picture      (DWORD)30
      offset=poke(buffer,offset,1,1)                  ;color planes 1 in most case         (WORD)34
      offset=poke(buffer,offset,32,1)                  ;bit per pixel                     (WORD)36
      offset=poke(buffer,offset,0,2)                  ;compression value                  (DWORD)38
      offset=poke(buffer,offset,bytecount,2)            ;pixeldata size                     (DWORD)42
      offset=poke(buffer,offset,0,2)                  ;ppm                           (DWORD)46
      offset=poke(buffer,offset,0,2)                  ;ppm                           (DWORD)50
      offset=poke(buffer,offset,0,2)                  ;number of color 0=max                  (DWORD)54
      offset=poke(buffer,offset,0,2)                  ;number of color indice importants 0=max(DWORD)58


StartDrawing(ImageOutput(image))
  For y=0 To Hauteur -1       
    For x=0 To Largeur -1               
      a=Point(x,y)
      ;Read a.l
       b=(a <<8)>>24
       g=(a <<16)>>24
       r=(a <<24)>>24
      Alpha=50;Alpha(a)
       ;If RGB(r, g, b) = ColorKey: Alpha = 0: Else: Alpha = 255: EndIf
      
       offset=poke(buffer,offset,B,0)
          offset=poke(buffer,offset,G,0)
          offset=poke(buffer,offset,R,0)
          offset=poke(buffer,offset,Alpha,0)
    Next x         
  Next Y
 StopDrawing()           
EndIf
   For a=1 To bytecount/8
      offset=poke(buffer,offset,0,0)
   Next
   CatchImage(image,buffer)
  ;sav=OpenFile(0,filename$)
  ;WriteData(0,buffer,offset)
  ;CloseFile(0)
  FreeMemory(buffer)
EndProcedure
Procedure poke(mem,offset,value,typ)
Select typ
   Case 0;byte
      PokeB(mem+offset,value):offset=offset+1
   Case 1;word
      PokeW(mem+offset,value):offset=offset+2
   Case 2;long
      PokeL(mem+offset,value):offset=offset+4
EndSelect
ProcedureReturn offset
EndProcedure
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

point(x,y) ne retourne que la couleur
Une image 32 bits est en fait une image 24 bits de couleurs + 8 bits (de poids fort) qui, JE CROIS, servent a l'alpha. Mais ca ne s'utilise pas (ou pas facilement) sous PB (enfin la, je dis nimporte koi).

Un point (x,y) sur une image 32 bits te retourne :
<8 bits (alpha?)> <8 bits RED> <8 bits GREEN> <8 bits BLUE>
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

SPH a écrit :
point(x,y) ne retourne que la couleur
Une image 32 bits est en fait une image 24 bits de couleurs + 8 bits (de poids fort) qui, JE CROIS, servent a l'alpha. Mais ca ne s'utilise pas (ou pas facilement) sous PB (enfin la, je dis nimporte koi).

Un point (x,y) sur une image 32 bits te retourne :
<8 bits (alpha?)> <8 bits RED> <8 bits GREEN> <8 bits BLUE>
j'ai déjà essayé ! j'ai jamais reussi ! j'ai testé plein de code et ça ne fonctionne pas ! :(point retourne que sur 24bit
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tu devrais pouvoir adapter ce code pour t'écrire une fonction alpha()

Code : Tout sélectionner

; English forum: http://purebasic.myforums.net/viewtopic.php?t=8736&highlight=
; Author: Danilo (updated for PB3.93 by ts-soft)
; Date: 14. December 2003

; 
; Bitmap Bits Test 
; Danilo, 10.04.2003 

Structure myBITMAPINFO 
  bmiHeader.BITMAPINFOHEADER 
  bmiColors.RGBQUAD[1] 
EndStructure 

Structure s_pixel
  B.b
  V.b
  R.b
  A.b
EndStructure

hBmp = CreateImage(1,300,100) 
hDC  = StartDrawing(ImageOutput(1)) 
  ImageWidth  = ImageWidth(1) 
  ImageHeight = ImageHeight(1) 
  mem = AllocateMemory(ImageWidth*ImageHeight*4) 
  bmi.myBITMAPINFO 
  bmi\bmiHeader\biSize   = SizeOf(BITMAPINFOHEADER) 
  bmi\bmiHeader\biWidth  = ImageWidth 
  bmi\bmiHeader\biHeight = ImageHeight 
  bmi\bmiHeader\biPlanes = 1 
  bmi\bmiHeader\biBitCount = 32 
  bmi\bmiHeader\biCompression = #BI_RGB 
  If GetDIBits_(hDC,hBmp,0,ImageHeight(1),mem,bmi,#DIB_RGB_COLORS) <> 0 
    ; Fill 
    *pixels.s_pixel = mem 
    For a = 1 To ImageWidth*(ImageHeight/3) 
      *pixels\R = $FF
      *pixels\V = $FF 
      *pixels\B = $00
      *pixels\A = $00 ; on peut lire la valeur alpha ici au lieu de l'écrire
      *pixels + 4 
    Next a 
    
    ; Copy back 
    If SetDIBits_(hDC,hBmp,0,ImageHeight(1),mem,bmi,#DIB_RGB_COLORS) <> 0 
      StopDrawing() 
      OpenWindow(0,0,0,ImageWidth,ImageHeight,"Image",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
        CreateGadgetList(WindowID(0)) 
        ButtonImageGadget(0,0,0,ImageWidth,ImageHeight,hBmp) 
      Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
    Else 
      StopDrawing() 
    EndIf 
  EndIf
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

comtois a écrit :tu devrais pouvoir adapter ce code pour t'écrire une fonction alpha()
super ! merci je vais regarder ça !:P
ça utlise les APIs windows mais bon je crois qu'il n'y a pas vraiment d'autre solution :(
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

Je n'ai pas capté un truc :

Code : Tout sélectionner

      *pixels\A = $00 ; on peut lire la valeur alpha ici au lieu de l'écrire 
Tu ecris l'alpha avec ca non ?
Pkoi tu dis qu'on le LIS ? Faute ?

Sinon, j'anticipe une question de Typhoon (je pense) :
Alpha 00 = alpha FF !! PKOI ?

Moi, je pense que l'alpha n'est "trifouillable" que par des moteurs 3D et autres logiciels pro style photoshop (mais peut etre que je me trompe)
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

SPH a écrit :Je n'ai pas capté un truc :

Code : Tout sélectionner

      *pixels\A = $00 ; on peut lire la valeur alpha ici au lieu de l'écrire 
Tu ecris l'alpha avec ca non ?
Pkoi tu dis qu'on le LIS ? Faute ?
je dis qu'il faut adapter le code pour faire une lecture plutôt qu'une écriture.
Et encore pour choisir le pixel.

tu es obligé de travailler sur des images ou sur un sprite ça ferait l'affaire ?
avec les sprites tu as les commandes dispo dans PB
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Heu !!! non,non Alpha FF et Alpha 00 c'est pas du tout pareille. dans un cas c'est opaque et dans l'autre c'est totalement transparent.

Non, L'alpha n'est pas beaucoup plus compliqué a travaillé que les composante rouge, vert, bleu. D'ailleur avec SDL c'est un vrai jeu d'enfant de modifier la transparence d'un pixel. Je ne sais pas trop pourquoi dans Purebasic c'est si compliqué... J'éspère que ça s'améliorera dans le futur.

Ici le problème c'est que les fonction 2D ne travaille que sur 24 bits ...
d'où ma demande sur le forum anglais
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

Thyphoon a écrit :Heu !!! non,non Alpha FF et Alpha 00 c'est pas du tout pareille. dans un cas c'est opaque et dans l'autre c'est totalement transparent.

Non, L'alpha n'est pas beaucoup plus compliqué a travaillé que les composante rouge, vert, bleu. D'ailleur avec SDL c'est un vrai jeu d'enfant de modifier la transparence d'un pixel. Je ne sais pas trop pourquoi dans Purebasic c'est si compliqué... J'éspère que ça s'améliorera dans le futur.

Ici le problème c'est que les fonction 2D ne travaille que sur 24 bits ...
d'où ma demande sur le forum anglais
Tu n'as pas (semble t'il) compris :

Essaye ca et fait un screenshoot :

Code : Tout sélectionner

      *pixels\R = $bb
      *pixels\V = $66 
      *pixels\B = $00 
      *pixels\A = $00 ; on peut lire la valeur alpha ici au lieu de l'écrire 
Ensuite, essaye ca et fait un screenshoot :

Code : Tout sélectionner

      *pixels\R = $bb
      *pixels\V = $66 
      *pixels\B = $00 
      *pixels\A = $ff ; on peut lire la valeur alpha ici au lieu de l'écrire 
Compare tes 2 screenshoots ! Les memes !! (chez moi en tout cas)... Preuve que l'alpha n'est pas specialement reglable sous PB...
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Bon je suis pas loin de réussir (enfin je crois)
Mais j'ai un problème a mon avis avec mon calcul pour trouver le pixel en mémoire
*pixels.s_pixel = mem+x*4+y*largeur

si quelqu'un a une idée ...
et voici une image pour tester

Image

Code : Tout sélectionner

Structure myBITMAPINFO
  bmiHeader.BITMAPINFOHEADER
  bmiColors.RGBQUAD[1]
EndStructure

Structure s_pixel
  B.b
  V.b
  R.b
  A.b
EndStructure

Declare poke(mem,offset,value,typ)
         Procedure Alpha(color)
    ProcedureReturn PeekB(@color+3)&$FF
  EndProcedure  
Procedure  convert2ico(image.l)

ResizeImage(image,32,32)
Debug ImageDepth(image)
hauteur=ImageHeight(image)
largeur=ImageWidth(image)
;saveicon(filename$,hauteur,largeur, ColorKey)
buffer=AllocateMemory(10000)
If buffer
;-------------------------------ICONDIR structure
      offset=poke(buffer,offset,0,1)                  ;reserved must be 0                (WORD)0
      offset=poke(buffer,offset,1,1)                  ;ressource type icon=1               (WORD)2
      offset=poke(buffer,offset,1,1)                  ;how many images 1                  (WORD)4
      ;-------------------------------ICONDIR ENTRY
      offset=poke(buffer,offset,largeur,0)      ;width in pixel of the picture         (BYTE)6
      offset=poke(buffer,offset,hauteur,0)      ;height in pixel of the picture         (BYTE)7
      offset=poke(buffer,offset,0,0)                  ;#color in image 0 if >8bpp          (BYTE)8
      offset=poke(buffer,offset,0,0)                  ;reserved must be 0                (BYTE)9
      offset=poke(buffer,offset,1,1)                  ;color planes                      (WORD)10
      offset=poke(buffer,offset,32,1)                  ;bit per pixel                     (WORD)12
      bytecount=((largeur*hauteur)*4);x,y*4 bytes
      offset=poke(buffer,offset,bytecount+40+(largeur*hauteur)/8,2)   ;how many bytes in this ressource      (DWORD)14
      offset=poke(buffer,offset,offset+4,2)            ;where in the file is the bitmap data   (DWORD)18
      ;--------------------------------DIB header
      offset=poke(buffer,offset,40,2)                  ;lenght of the header               (DWORD)22
      offset=poke(buffer,offset,largeur,2)      ;width in pixel of the picture         (DWORD)26
      offset=poke(buffer,offset,hauteur*2,2)      ;width in pixel of the picture      (DWORD)30
      offset=poke(buffer,offset,1,1)                  ;color planes 1 in most case         (WORD)34
      offset=poke(buffer,offset,32,1)                  ;bit per pixel                     (WORD)36
      offset=poke(buffer,offset,0,2)                  ;compression value                  (DWORD)38
      offset=poke(buffer,offset,bytecount,2)            ;pixeldata size                     (DWORD)42
      offset=poke(buffer,offset,0,2)                  ;ppm                           (DWORD)46
      offset=poke(buffer,offset,0,2)                  ;ppm                           (DWORD)50
      offset=poke(buffer,offset,0,2)                  ;number of color 0=max                  (DWORD)54
      offset=poke(buffer,offset,0,2)                  ;number of color indice importants 0=max(DWORD)58


  hDC=StartDrawing(ImageOutput(image))
  hBmp=ImageID(image)
  mem = AllocateMemory(largeur*hauteur*4)
  bmi.myBITMAPINFO
  bmi\bmiHeader\biSize   = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth  = largeur
  bmi\bmiHeader\biHeight = hauteur
  bmi\bmiHeader\biPlanes = 1
  bmi\bmiHeader\biBitCount = 32
  bmi\bmiHeader\biCompression = #BI_RGB

If GetDIBits_(hDC,hBmp,0,hauteur,mem,bmi,#DIB_RGB_COLORS) <> 0
   
    
  For y=0 To Hauteur -1       
    For x=0 To Largeur -1   
      *pixels.s_pixel = mem+x*4+y*largeur
                  
      a=Point(x,y)
       
       b=*pixels\B;(a <<8)>>24
        ;Debug Str(b)+" "+Str((a <<8)>>24)
       g=*pixels\V;(a <<16)>>24
       r=*pixels\R;(a <<24)>>24
      Alpha=*pixels\A;
       ;If RGB(r, g, b) = ColorKey: Alpha = 0: Else: Alpha = 255: EndIf
      
       offset=poke(buffer,offset,B,0)
          offset=poke(buffer,offset,G,0)
          offset=poke(buffer,offset,R,0)
          offset=poke(buffer,offset,Alpha,0)
    Next x         
  Next Y
 EndIf 
 StopDrawing()  
 FreeMemory(mem)         
EndIf
   For a=1 To bytecount/8
      offset=poke(buffer,offset,0,0)
   Next
   CatchImage(image,buffer)
  ;sav=OpenFile(0,filename$)
  ;WriteData(0,buffer,offset)
  ;CloseFile(0)
  FreeMemory(buffer)
EndProcedure
Procedure poke(mem,offset,value,typ)
Select typ
   Case 0;byte
      PokeB(mem+offset,value):offset=offset+1
   Case 1;word
      PokeW(mem+offset,value):offset=offset+2
   Case 2;long
      PokeL(mem+offset,value):offset=offset+4
EndSelect
ProcedureReturn offset
EndProcedure


UsePNGImageDecoder()
NomFichier$ = OpenFileRequester("choisir une image PNG avec couche alpha", FichierParDefaut$, "*.png", 0)
If LoadImage(0,NomFichier$)
convert2ico(0)
Else
  Debug "error"
EndIf
If OpenWindow(0,0,0,320,200,"Image",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
        CreateGadgetList(WindowID(0))
        ButtonImageGadget(0,0,0,ImageWidth(0),ImageHeight(0),ImageID(0))
      Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Thyphoon a écrit :Bon je suis pas loin de réussir (enfin je crois)
Mais j'ai un problème a mon avis avec mon calcul pour trouver le pixel en mémoire
*pixels.s_pixel = mem+x*4+y*largeur



; color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )

Case #PB_PixelFormat_32Bits_RGB : PF=4

ça me semble bon ce que tu as fait :)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Dobro a écrit :
Thyphoon a écrit :Bon je suis pas loin de réussir (enfin je crois)
Mais j'ai un problème a mon avis avec mon calcul pour trouver le pixel en mémoire
*pixels.s_pixel = mem+x*4+y*largeur



; color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )

Case #PB_PixelFormat_32Bits_RGB : PF=4

ça me semble bon ce que tu as fait :)
Merci Dobro ... Currieux.... j'ai mon image qui une fois convertit, qui n'est pas bonne comme si il y avait un décalage de ligne.
Lolllllll j'aurais préféré que tu me dise que je suis un gros nul et qu'il y avait une erreur lollllllll :lol:
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

Thyphoon a écrit :Bon je suis pas loin de réussir (enfin je crois)
Mais j'ai un problème a mon avis avec mon calcul pour trouver le pixel en mémoire
*pixels.s_pixel = mem+x*4+y*largeur

si quelqu'un a une idée ...
OULA MALHEUREUX !!!!
On en a parlé et reparlé et presque pêrsonne n'était daccord :wink:

http://www.purebasic.fr/french/viewtopi ... sc&start=0

Et ma conclusion etait celle la donc :
SPH a écrit :Merci a tous.

Juste une derniere chose pour finir avec le passage d'un tableau en une seule fois. Cela ne semble maintenant plus possible de le faire; sauf si DrawingBufferPitch()/4 = largeur de la fenetre ouverte.

Si les 2 lignes a l'ecran restent fixes, bravo, le passage en une seule fois d'un tableau dans la memvideo a reussi :

Code : Tout sélectionner

InitSprite()
InitKeyboard()

dw=1280 ;;;  essayez differentes resolutions
dh=1024
dc=32

If OpenScreen(dw,dh,dc,"")=0
End
EndIf

Dim p(dh-1,dw-1)

For i=0 To dh-1
p(i,i)=RGB(0,0,255) ; ligne diagonale partant de 0,0
Next

For i=0 To dh-1
p(dh-1-i,dw-1-i)=RGB(255,0,0) ; ligne diagonale partant de dw,dh
Next


;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;

Repeat

StartDrawing(ScreenOutput()) 

If Random(1) ;>>> ici on va basculer aleatoirement entre un tracage ligne par ligne
MemVideo = DrawingBuffer() 
For u=0 To dh-1
CopyMemory(@p(u,0), MemVideo+DrawingBufferPitch()*u,dw*4)
Next
Else ;>>> et un tracage en envoyant un tableau en une fois dans la memvideo
MemVideo = DrawingBuffer() 
CopyMemory(@p(), MemVideo,dw*dh*4)
EndIf

StopDrawing() 
FlipBuffers()
Delay(1)
ExamineKeyboard()

Until KeyboardPushed(#PB_Key_Escape)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

currieux ton truc ...
Et vous en avez parlé sur le forum anglais ?
je comprends pas bien pourquoi ça fait ça .... c'est du a quoi ?
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

Thyphoon a écrit :currieux ton truc ...
Et vous en avez parlé sur le forum anglais ?
Moi nan, peut etre les autres...
Thyphoon a écrit :je comprends pas bien pourquoi ça fait ça .... c'est du a quoi ?
A un virus qu'on appelle gastroantherite... FOUT TA CAGOULE, FOUT TA CAGOULE..........
.......heu......... :wink:
je vais parler pour mon compte : c'est dut a de l'illogique qui veux que la largeur de la memoire de la carte graphique ne prend pas la meme largeur que le screen open... Alors, il faut bizzarement jongler avec l'inconnu...
Un seul mec pourrait te repondre, car il est tres tres doué lui (nous disait il haut et fort)
look :
poshu a écrit :ce qui est bien, c'est que j'étais venu avec l'envie d'aider et une petite partie des compétences pour y arriver, et après avoir lu comme SPH est doué et que toute le reste de la communauté est débile, je m'en vais.
:idea:
Répondre