Page 1 sur 1

lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 17:13
par Thyphoon
pfff encore un truc pourtant simple sur le quel je bloque !
je veux juste lire la valeur alpha d'un pixel sur une image mais ça ne marche pas

voici l'image qui va avec le code
http://www.thyphoon.com/tmp_download/dirt3.png

vous remarquerez une fonction (qui n'a rien a voir avec le problème) qui permet de copier une image sur un sprite ! (chose bien pratique dans certain cas)
Edit: petit correction pour l'affichage de la valeur mais qui ne change rien au problème

Code : Tout sélectionner

InitSprite()
InitSprite3D()
InitKeyboard()
InitMouse()
UsePNGImageDecoder()

Procedure Image2Sprite(Image,Sprite)
   Protected Pitch,Width,Height,SourceLineLen,X,Y,DestY,Format
   Protected *ImageBuffer,*SpriteBuffer,*SourcePixel.LONG,*DestPixel.LONG
   
   Macro BGRA2RGBA(Pixel)
      (Pixel & $FF00FF00) | (Pixel & $FF) << 16 | ((Pixel >> 16) & $FF)
   EndMacro
   
   #PB_PixelFormat_32Bits_BGR_ReversedY = #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY
   #PB_PixelFormat_32Bits_RGB_ReversedY = #PB_PixelFormat_32Bits_RGB | #PB_PixelFormat_ReversedY
   
   StartDrawing(ImageOutput(Image))
   *ImageBuffer = DrawingBuffer()
   Format = DrawingBufferPixelFormat()
   StopDrawing()
   
   StartDrawing(SpriteOutput(Sprite))   
   *SpriteBuffer = DrawingBuffer()
   Pitch = DrawingBufferPitch()   
   Width = OutputWidth()
   Height = OutputHeight()
   SourceLineLen = Width * 4

   Select Format
      Case #PB_PixelFormat_32Bits_BGR
      If Pitch = SourceLineLen
         CopyMemory(*ImageBuffer,*SpriteBuffer,SourceLineLen * Height)
      Else
         Height - 1
         
         For Y = 0 To Height
            CopyMemory(*ImageBuffer + (SourceLineLen * Y),*SpriteBuffer + (Pitch * Y),SourceLineLen)
         Next
      EndIf
      
      Case #PB_PixelFormat_32Bits_RGB
      Height - 1
      Width - 1      
      *SourcePixel = *ImageBuffer
      
      For Y = 0 To Height
         *DestPixel = *SpriteBuffer + (Pitch * Y)
         
         For X = 0 To Width
            *DestPixel\l = BGRA2RGBA(*SourcePixel\l)
            *SourcePixel + 4
            *DestPixel + 4
         Next
      Next
      
      Case #PB_PixelFormat_32Bits_BGR_ReversedY
      Height - 1
      DestY = Height

      For Y = 0 To Height
         CopyMemory(*ImageBuffer + (SourceLineLen * Y),*SpriteBuffer + (Pitch * DestY),SourceLineLen)
         DestY - 1
      Next
      
      Case #PB_PixelFormat_32Bits_RGB_ReversedY   
      Height - 1
      Width - 1
      *SourcePixel = *ImageBuffer
      DestY = Height
      
      For Y = 0 To Height
         *DestPixel = *SpriteBuffer + (Pitch * DestY)
         
         For X = 0 To Width
            *DestPixel\l = BGRA2RGBA(*SourcePixel\l)
            *SourcePixel + 4
            *DestPixel + 4
         Next
         
         DestY - 1
      Next      
      
      Default
      StopDrawing()
      ProcedureReturn 0
   EndSelect
   
   StopDrawing()
EndProcedure

If OpenWindow(0,0,0,800,600,"Artillery",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)
EndIf

#Spr_background=0
LoadImage(#Spr_background,"dirt3.png")
ResizeImage(#Spr_background,800,600)
;je decoupe dans l'image une partie
StartDrawing(ImageOutput(#Spr_background))
;DrawingMode(#PB_2DDrawing_AlphaChannel);<<mon ancienn façon d'effacer la partie de l'image
DrawingMode(#PB_2DDrawing_AllChannels);<<la nouvelle façon, ça affect aussi la couche rgb alors qu'avant non !
y=300
  For x= 0 To 799
    y=y+Random(2)-1
    LineXY(x, y, x, 0,RGBA(0,0,0,0))
    
  Next x
  StopDrawing()
  CreateSprite(#Spr_background,800,600,#PB_Sprite_Texture|#PB_Sprite_AlphaBlending)
  ;je copie l'image sur un sprite!! :o)
Image2Sprite(#Spr_background,#Spr_background)
CreateSprite3D(#Spr_background,#Spr_background)

Repeat
  Event.l = WindowEvent()     
  ExamineKeyboard()
  ExamineMouse()
  FlipBuffers()       ; Inverse the buffers (the back become the front (visible)... and we can do the rendering on the back
  ClearScreen(#Blue)
  
  ;lecture de l'alpha sur l'image 
  StartDrawing(ImageOutput(#Spr_background))
  a=Alpha(Point(MouseX(),MouseY()))
  StopDrawing()
  ;j'affiche l'image mais en version sprite plus rapide
  Start3D()
  DisplaySprite3D(#Spr_background,0,0)
  Stop3D()
  ;affichage 
  StartDrawing(ScreenOutput())
  ;DrawAlphaImage(ImageID(#Spr_background),0,0)
  Circle(MouseX(),MouseY(),3,#Red) ;affichage du curseur
  DrawText(20,20,"alpha:"+Str(a)) ;affichage de l'alpha
  StopDrawing()

  Delay(1)
  
Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

End  

Re: lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 19:59
par Thyphoon
déjà en changeant le DrawingMode(#PB_2DDrawing_AlphaChannel ) part DrawingMode(#PB_2DDrawing_AllChannels )

Code : Tout sélectionner

DrawingMode(#PB_2DDrawing_AllChannels )
y=300
  For x= 0 To 799
    y=y+Random(2)-1
    LineXY(x, y, x, 0,RGBA(0,0,0,0))
    
  Next x
  StopDrawing()
ça permet avec un point(x,y) derécupéré la valeur 0 là ou j'ai effacé !!!
mais bon dans l'image il peut y avoir d'autre pixel avec la valeur 0 là ou pourtant du sol ... c'est pour ça que ça serait quand même mieux de récupérer l'alpha ! personne n'a d'idée ?

Re: lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 20:58
par blendman
salut

un petit code très rapide :

Code : Tout sélectionner

UsePNGImageDecoder()

LoadImage(0,"dirt3.png")

If OpenWindow(0, 300,300, 600,400, "lire alpha png", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_WindowCentered)  
  ImageGadget(0,0,0,100,100,ImageID(0))
EndIf



Repeat
  event= WaitWindowEvent()
  StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  If event= #PB_Event_Gadget ; il suffit que tu cliques pour avoir l'alpha    
    color =Point(WindowMouseX(0),WindowMouseY(0))
  EndIf  
  StopDrawing()
  
  SetWindowTitle(0,"Alpha ="+Str(Alpha(color))+" / Color = "+Str(color))

Until event = #PB_Event_CloseWindow
End
Teste avec cette image-ci, tu récupères bien l'alpha ;).
Image

Le carré à gauche : alpha = 0
le sol : alpha = 255
le carré à droite : alpha = 131

J'espère que ça pourra t'aider ;)

Tu dois peut être changer ça :

Code : Tout sélectionner

StartDrawing(ImageOutput(#Spr_background))
  a=Alpha(Point(MouseX(),MouseY()))
  StopDrawing()
en ça :

Code : Tout sélectionner

StartDrawing(ImageOutput(#Spr_background))
DrawingMode(#PB_2DDrawing_AlphaChannel)
  a=Alpha(Point(MouseX(),MouseY()))
  StopDrawing()

Re: lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 21:16
par Thyphoon
haaaaaaaarg blendman ! tu es trop fort ! :mrgreen:
pfffffffff je savais bien que ça serait a cause d'un truc tout simple ... et pourtant j'en est fait des tests !
Un grand merci !
Bon ba j'ai plus qu'a rajouter la petite ligne qui manque dans mon code !!

Re: lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 21:35
par blendman
Thyphoon a écrit :haaaaaaaarg blendman ! tu es trop fort ! :mrgreen:
ah non, merci à toi, parce que justement j'ai aussi cherché il y a quelques jours sans comprendre comment faire ce genre de chose. Et là, en testant vite fait, j'ai compris comment ça marchait :D.

Alors, c'est cool de t'avoir aider, car ça m'a aussi aidé en retour :mrgreen:

Re: lecture de la valeur Alpha d'un point sur une image

Publié : mar. 12/juil./2011 21:50
par Thyphoon
c'est souvent en laissant un problème et en y revenant plus tard qu'on le trouve du premier coup ! mais pour moi ça n'avait pas marché
alors que finalement la reponse est très logique pourtant on se prend la tête sur des trucs ...

donc content d'avoir pu s'entre aidé alors ! ;)