Screen To Image

Just starting out? Need help? Post your questions and find answers here.
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Screen To Image

Post by [blendman] »

Hi

For my 2D painting application, I wouls like to save the screen to an image.

I have tried to use DrawingBuffer(), but I think I have an error, but I don't know how to resolv it :

Code: Select all




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
Do you know How I can save my screen to an image with drawing buffer ? (I have found some code with API, but I would like to save only the Screen opened with OpenWindowedScreen, not my entire desktop ^^)
Thank you.
Alex777
User
User
Posts: 49
Joined: Sun Nov 16, 2008 12:47 am
Location: Cayman Is.
Contact:

Re: Screen To Image

Post by Alex777 »

This works for me:

Code: Select all

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

Spr.i = GrabSprite(#PB_Any, 0, 0, ScreenWidth(), ScreenHeight())                      ; <-----------------------

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

Img.i = CatchImage(#PB_Any, @Spr)                                                                ; <------------------------

; 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(Img,savefile$,#PB_ImagePlugin_PNG)
  EndIf
EndIf

Repeat
  Event = WaitWindowEvent()
   
Until Event = #PB_Event_CloseWindow

EndIf

But you might as well use SaveSprite(#Sprite, Filename$ [, ImagePlugin [, Flags]]).
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: Screen To Image

Post by [blendman] »

Hi
Thank you for your answer.

YEp, I have tried GrabSprite() and SaveSprite() and as you say, it's the solution I'm looking for (I have used that for the screenshot of my previous game (arkeos), but I have forgotten thos commands ^^).
When my document is > screensize, I save all the parts of my image in several parts and recompose all those parts in a big image, save it and all is fine.
Thanks again.
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Screen To Image

Post by infratec »

Hi,

a bit more easier (no need for CatchImage())

Code: Select all

EnableExplicit


Procedure.i SaveScreen()
  
  Protected.i Result, Sprite
  Protected SaveFile$
  
    
  Sprite = GrabSprite(#PB_Any, 0, 0, ScreenWidth(), ScreenHeight())
  If Sprite
    SaveFile$ = SaveFileRequester("Save image", "", "png|*.png", 0)
    If SaveFile$ <> ""
      If LCase(Right(SaveFile$, 3)) <> "png"
        SaveFile$ + ".png"
      EndIf
      If SaveSprite(Sprite, SaveFile$, #PB_ImagePlugin_PNG)
        Result = #True
      EndIf
    EndIf
    FreeSprite(Sprite)
  EndIf
  
  ProcedureReturn Result
  
EndProcedure




Define.i Event, Exit, W, H
Define File$

UsePNGImageDecoder()
UsePNGImageEncoder()

InitSprite()
InitKeyboard()

File$ = OpenFileRequester("Open Image", "", "png|*.png",0)
If File$ <> ""
  
  W = 1024
  H = 768
  
  If LoadImage(0, file$)
    
    OpenWindow(0, 0, 0, W, H, "Screen to Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    OpenWindowedScreen(WindowID(0), 0, 0, W, H)
    
    Repeat
      Repeat
        Event = WindowEvent()
        Select Event
          Case #PB_Event_CloseWindow
            Exit = #True
        EndSelect
      Until Event
      
      ExamineKeyboard()
      
      If KeyboardReleased(#PB_Key_Escape)
        Exit = #True
      ElseIf KeyboardReleased(#PB_Key_Space)
        SaveScreen()
      EndIf
      
      FlipBuffers()
      
      If IsScreenActive()
        ClearScreen(RGB(200,200,200))
        If StartDrawing(ScreenOutput())
          DrawAlphaImage(ImageID(0), 0, 0)
          StopDrawing()
        EndIf
      EndIf
      
    Until Exit
    
  EndIf
  
EndIf
Bernd
Post Reply