Page 1 sur 1

[ok] Screen to Image

Publié : ven. 12/juin/2015 17:59
par blendman
salut

j'essaie d'enregistrer ce que j'affiche sur mon screen sur une image. J4ai donc pensé utilisé drawingbuffer(), mais ça m'enregistre une image toute noire.

Je ne sais pas trop d'où vient le bug ^^.

Si vous avez une idée, ça me serait très utile :).

Code : Tout sélectionner





W = 1024
H = 768
UsePNGImageDecoder()
UsePNGImageEncoder()
file$ = OpenFileRequester("Open Image", "","png|*.png",0)
If file$ <> ""
LoadImage(0,file$)

OpenWindow(0, 0, 0, W,H, "Screen to Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
InitSprite()
OpenWindowedScreen( WindowID(0),0,0,W,H)

ClearScreen(RGB(200,200,200))
If StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawAlphaImage(ImageID(0),0,0)
  StopDrawing()
EndIf

; FlipBuffers()
 
W = ScreenWidth()
H = ScreenHeight()
Dim ColorR(W*H)
Dim ColorG(W*H)
Dim ColorB(W*H)


If StartDrawing(ScreenOutput())
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)

  Buffer = DrawingBuffer()
  
  If Buffer <> 0
    
    pixelFormat = DrawingBufferPixelFormat()
    lineLength = DrawingBufferPitch();Longueur d'une ligne
    
    ;If pixelFormat = #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY
    
    For i = 0 To W - 1       
      For j = 0 To H - 1 
        
        ColorR(i*j) = PeekA(Buffer + 4 * i + j * lineLength)    
        ColorG(i*j) = PeekA(Buffer + 4 * i + j * lineLength + 1)
        ColorB(i*j) = PeekA(Buffer + 4 * i + j * lineLength + 2) 
        
      Next j      
    Next i
    
    ;EndIf
  EndIf
  
  StopDrawing()
EndIf

CreateImage(1,W,H,32,#PB_Image_Transparent)

If StartDrawing(ImageOutput(1))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  Buffer = DrawingBuffer()
  
  If Buffer <> 0
    
    pixelFormat = DrawingBufferPixelFormat()
    
    lineLength = DrawingBufferPitch()
    
    If pixelFormat = #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY
      
      For i = 0 To W - 1 
        
        For j = 0 To H - 1           
          PokeA(Buffer + 4 * i + j * lineLength,      ColorB(i*j))
          PokeA(Buffer + 4 * i + j * lineLength + 1,  ColorG(i*j))
          PokeA(Buffer + 4 * i + j * lineLength + 2,  ColorR(i*j))            
        Next j
        
      Next i
      
    EndIf
  EndIf
  
  StopDrawing()
EndIf

savefile$ = SaveFileRequester("Save image","", "png|*.png",0)
If savefile$ <> ""
  If SaveImage(1,savefile$,#PB_ImagePlugin_PNG)
  EndIf
EndIf

Repeat
  Event = WaitWindowEvent()
    
Until Event = #PB_Event_CloseWindow

EndIf


Re: Screen to Image

Publié : ven. 12/juin/2015 20:08
par G-Rom
Tu confonds index d'un tableau , offset pour la mémoire , et par dessus la marché tu oublie la couche alpha sur ton résultat :mrgreen:
je te laisse regardé le code :

Code : Tout sélectionner


W = 1024
H = 768
UsePNGImageDecoder()
UsePNGImageEncoder()
file$ = OpenFileRequester("Open Image", "","png|*.png",0)
If file$ <> ""
LoadImage(0,file$)

OpenWindow(0, 0, 0, W,H, "Screen to Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
InitSprite()
OpenWindowedScreen( WindowID(0),0,0,W,H)

ClearScreen(RGB(200,200,200))
If StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawAlphaImage(ImageID(0),0,0)
  StopDrawing()
EndIf

; FlipBuffers()

W = ScreenWidth()
H = ScreenHeight()
Dim ColorR.a(W*H)
Dim ColorG.a(W*H)
Dim ColorB.a(W*H)

Dim *Pixel( W*H*4 )

If StartDrawing(ScreenOutput())
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)

  Buffer = DrawingBuffer()
  
  If Buffer <> 0
    
;     pixelFormat = DrawingBufferPixelFormat()
;     lineLength = DrawingBufferPitch();Longueur d'une ligne
    
    ;If pixelFormat = #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY
    
    For j = 0 To H - 1
      For i = 0 To W - 1 
      
          
       
        
        index.l         = i + W * j
        memory_offset  = (i*4) + W * (j*4)
        
        ColorR(index) = PeekA( (Buffer + memory_offset) + 0)
        ColorG(index) = PeekA( (Buffer + memory_offset) + 1)
        ColorB(index) = PeekA( (Buffer + memory_offset) + 2)
       
        
      Next      
    Next
    
    ;EndIf
  EndIf
  
  StopDrawing()
EndIf

CreateImage(1,W,H,32,#PB_Image_Transparent)

If StartDrawing(ImageOutput(1))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  Buffer = DrawingBuffer()
  
  If Buffer <> 0
    
    pixelFormat = DrawingBufferPixelFormat()
    
;     lineLength = DrawingBufferPitch()
    
  ; If pixelFormat = #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY
    
    For j = 0 To H - 1 
      For i = 0 To W - 1 
             
          
        index.l = i + W * j
        memory_offset  = (i*4) + W * (j*4)
          
          PokeA(Buffer + memory_offset + 0,  ColorR(index))
          PokeA(Buffer + memory_offset + 1,  ColorG(index))
          PokeA(Buffer + memory_offset + 2,  ColorB(index)) 
          PokeA(Buffer + memory_offset + 3,  255) ; et l'alpha ? 
          
          
        Next
        
      Next
      
;     EndIf
  EndIf
  
  StopDrawing()
EndIf

savefile$ = SaveFileRequester("Save image","", "png|*.png",0)
If savefile$ <> ""
  If SaveImage(1,savefile$,#PB_ImagePlugin_PNG)
  EndIf
EndIf

Repeat
  Event = WaitWindowEvent()
    
Until Event = #PB_Event_CloseWindow

EndIf
Ca me sort une image inversé , je te laisse corrigé cela ^^


Edit :

un index du style W*H , ne peu pas être bon , en pixel 2x2 , tu a accès à l'index 4 , au pixel 1x4 aussi et au 4x1 aussi , pas bon donc ;)

Re: Screen to Image

Publié : sam. 13/juin/2015 12:27
par blendman
salut

Merci pour ta correction et les explications.
Je ne maitrise pas du tout le drawingbuffer() et effectivement, j'avais vu que je m'étais trompé avec l'index et le reste ^^ (mais je ne savais pas trop comment corrigé).
En tout cas, tel quel ça peut servir pour faire un miroir horizontal d'une image ^^ (j'ai corrigé pour la sortie normale).

Re: Screen to Image

Publié : dim. 14/juin/2015 13:29
par Micoute
Merci beaucoup, monsieur Spock.

Re: Screen to Image

Publié : dim. 14/juin/2015 13:40
par blendman
Merci M. Spock :)
avec pb 5.30, j'ai une ima à la ligne 63.

Cela dit, en utilisant grabsprite() et savesprite(), ça marche aussi pour sauvegarder l'écran (c'est finalement ce que j'ai décidé d'utiliser) ;).

Re: Screen to Image

Publié : dim. 14/juin/2015 15:03
par Marc56
IMA ? je me suis demandé aussi, mais c'est peut-être Invalid Memory Access ?

J'ai ça aussi:

Waiting for executable to start...
Executable type: Windows - x64 (64bit, Unicode)
Executable started.
[ERROR] SaveScreen.pb (Line: 63)
[ERROR] Invalid memory access. (read error at address 192544771)

(ligne 63: If SaveImage(#Image2,savefile$,#PB_ImagePlugin_PNG))

PB 5.31 x64 / Windows 8.1
pareil en 5.24 LTS x86

"Spock! Do something!" :o (please)

Re: Screen to Image

Publié : dim. 14/juin/2015 16:56
par Marc56
Même message avec cette nouvelle version :?

Attente du démarrage du programme...
Type d'exécutable: Windows - x64 (64bit, Unicode)
Exécutable démarré.
[ERREUR] Ligne: 60
[ERREUR] Accès mémoire invalide. (erreur de lecture à l'adresse 187236352)

(ligne 60: pixel() = Point(x,y))

Pour la version précédente, même message sous XP Pro (mais dans une VM vitrualbox, donc pas significatif) :roll:

Après un tas d'essais, le plantage mémoire semble arriver à cause de GrabDrawingImage, car si je change la taille de l'image capturée avec par exemple ça:

If GrabDrawingImage(#Image2, 0, 0, ScreenWidth()-1, ScreenHeight()-1 ) <> 0

Ça ne plante pas :D (mais l'image est complètement bizarre) :|

Je laisse blendman dire ce que ça fait pour lui.
(Je ne n'ai pas encore beaucoup exploité le domaine graphique de PB)

(Merci Spock) :wink:

Edit: Je me demande maintenant s'il n'y a pas un paramètre dans la configuration du compilateur PB qui influence cela ? Les problèmes d'accès mémoire sont toujours difficiles à debbuger :?

Re: Screen to Image

Publié : dim. 14/juin/2015 17:45
par Micheao
hello Mr spock

le code ne marche pas sur mon pc : Windows 8.1 et PB version 5.31

l'image apparait bien dans la fenetre mais à la sauvegarde ça plante impossible de fermer la fenetre ensuite rien est sauvegarder

Re: Screen to Image

Publié : dim. 14/juin/2015 18:17
par Ar-S
Salut Spock, bug ou pas j'ai testé ton code sous Linux PB5.31x64
Il ne plante pas mais génère une image complètement transparente, sans trace de l'originale.

Re: Screen to Image

Publié : dim. 14/juin/2015 19:34
par G-Rom
GrabDrawingImage() est buggé, ca ne marche pas en x86 & x64 sous win7.

Re: Screen to Image

Publié : dim. 14/juin/2015 19:43
par blendman
je confirme que GrabDrawingImage() est bien bugué, c'est l'ima (invalid memory access) que j'avais aussi.

Re: Screen to Image

Publié : lun. 15/juin/2015 9:43
par Micheao
je comfirme aussi j'ai essayé de teste sur seven 64 ça plante pareil

à tout hasard Dobro as tu testé le code sur l'ide original de PB et pas avec ton EPB ?

Re: Screen to Image

Publié : lun. 15/juin/2015 11:53
par blendman
à priori, ça a été posté sur le forum anglais, dans la partie bug - windows.

http://www.purebasic.fr/english/viewtop ... =4&t=62417

Mais comme indiqué, peut-être tout simple qu'on ne peut pas faire un GrabDrawingImage() avec un screenoutput(), auquel cas, il faudrait juste le noter dans l'aide ^^.

Re: Screen to Image

Publié : lun. 15/juin/2015 16:14
par Micheao
j'ai testé le code avec EPB ça plante pareil