[Solved] Capture window as an image

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

[Solved] Capture window as an image

Post by Fangbeast »

Is there a way for a running program to take a graphic snapshot of one of its windows and all objects on it as an image?
Last edited by Fangbeast on Fri Jun 02, 2017 6:31 am, edited 1 time in total.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
RSBasic
Moderator
Moderator
Posts: 1228
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Capture window as an image

Post by RSBasic »

Image
Image
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Capture window as an image

Post by Bisonte »

hm my idea with GrabDrawingImage and WindowOutPut don't work .... the text of the button have another color ....

Code: Select all

OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(1, 20, 20, 100, 20, "Go")
ImageGadget(2, 20, 50, 640, 480, 0)
AddKeyboardShortcut(0, #PB_Shortcut_1, 2)

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit = #True
    Case #PB_Event_Menu
      Select EventMenu()
        Case 2
          If StartDrawing(WindowOutput(0))
            GrabDrawingImage(1, 0, 0, OutputWidth(), OutputHeight())
            StopDrawing()
            SetGadgetState(2, ImageID(1))
          EndIf
      EndSelect      
  EndSelect
Until Quit
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Capture window as an image

Post by Fangbeast »

Thanks for that you two, this gives me some new, useful ideas to play with. Woohoo, PB is fun!
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Capture window as an image

Post by Fangbeast »

I've combined RSBASIC's code and a printrequester example to send the image to the printer but the resulting image is only slightly larger than a postage stamp?

Anyone have an idea? I thought \right, \bottom were the correct image size grabbed?

Code: Select all

Procedure PrintMyStuffNow()
  Protected Handle
  Protected hDC
  Protected RECT.RECT
  Protected hPrinterDC
  Handle  = GetForegroundWindow_()
  hDC     = GetWindowDC_(Handle)
  GetWindowRect_(Handle, @RECT.RECT)
  With RECT
    \right - \left
    \bottom - \top
    ImageHandle.i = CreateImage(#PB_Any, \right, \bottom)
    hPrinterDC    = StartDrawing(ImageOutput(ImageHandle.i))
    If hPrinterDC
      BitBlt_(hPrinterDC, 0, 0, \right, \bottom, hDC, 0, 0, #SRCCOPY)
      StopDrawing()
    EndIf
   ;EndWith
    ReleaseDC_(Handle,  hDC)
    If PrintRequester()
      If StartPrinting("Print window")
        If StartDrawing(PrinterOutput())
          DrawImage(ImageID(ImageHandle.i), \right, \bottom)
          StopDrawing()
        EndIf
        StopPrinting()
      EndIf
    EndIf
  EndWith
  ;SetClipboardImage(ImageHandle.i)
EndProcedure

  
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Capture window as an image

Post by Olliv »

Hi Fangbeast,

I ask myself if a 'output image format getting' and then a resizing could solve,
inserting these 3 lines in the drawing job.

Code: Select all

Width =  OutputWidth()
Height = OutputHeight()
ResizeImage(ImageHandle, Width, Height)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4995
Joined: Sun Apr 12, 2009 6:27 am

Re: Capture window as an image

Post by RASHAD »

Hi
You are using \right, \bottom as x & y not as width and height

Code: Select all

DrawImage(ImageID, x, y [, Width, Height]) 
Better use

Code: Select all

        If StartVectorDrawing(PrinterOutput(#PB_Unit_Millimeter)
            MovePathCursor(x.d, y.d [, Flags])
            DrawVectorImage(ImageID [, Alpha [, Width.d, Height.d]])
          StopDrawing()
        EndIf
Last edited by RASHAD on Thu Jun 01, 2017 12:16 pm, edited 1 time in total.
Egypt my love
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Capture window as an image

Post by Bisonte »

or change your Print Routine with this

Code: Select all

    If PrintRequester()
      If StartPrinting("Print window")
        Factor.f = PrinterPageWidth() / ImageWidth(ImageHandle)
        If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
          MovePathCursor(0, 0)
          DrawVectorImage(ImageID(ImageHandle), 255, ImageWidth(ImageHandle)*Factor, ImageHeight(ImageHandle)*Factor)
          StopVectorDrawing()
        EndIf
        StopPrinting()
      EndIf
    EndIf
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Capture window as an image

Post by Fangbeast »

Ouch, shows how dumb I am. But it's getting better:)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Capture window as an image

Post by Fangbeast »

Tested the print results in landscape mode using my PDF printer and they look great except for some thin black borders on both sides part of the way. Other than that, pretty damned good.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: [Solved] Capture window as an image

Post by Fangbeast »

Just doing about 20 prints and I have finally realised that it isn't just grabbing the foreground window but part of the background wallpaper?
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
idle
Always Here
Always Here
Posts: 6035
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: [Solved] Capture window as an image

Post by idle »

Have you tried PrintWindow_ ?
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

__________________________________________________
URL tags added
06.06.2017
RSBasic
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: [Solved] Capture window as an image

Post by Fangbeast »

idle wrote:Have you tried PrintWindow_ ?
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
"The requested page could not be found".

I went looking for it but don't know how to use it. The code below works but grabs a tiny slice of the background that it's on as well.

Code: Select all

  Protected Handle
  Protected hDC
  Protected RECT.RECT
  Protected hPrinterDC
  Handle  = GetForegroundWindow_()
  hDC     = GetWindowDC_(Handle)
  GetWindowRect_(Handle, @RECT.RECT)
  With RECT
    \right - \left
    \bottom - \top
    ImageHandle.i = CreateImage(#PB_Any, \right, \bottom)
    hPrinterDC    = StartDrawing(ImageOutput(ImageHandle.i))
    \If hPrinterDC
      BitBlt_(hPrinterDC, 0, 0, \right, \bottom, hDC, 0, 0, #SRCCOPY)
      StopDrawing()
    EndIf
    ReleaseDC_(Handle,  hDC)
    If PrintRequester()
      If StartPrinting("MyStuff Record Print")
        Factor.f = PrinterPageWidth() / ImageWidth(ImageHandle)
        If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
          MovePathCursor(0, 0)
          DrawVectorImage(ImageID(ImageHandle), 255, ImageWidth(ImageHandle) * Factor, ImageHeight(ImageHandle) * Factor)
          StopVectorDrawing()
        EndIf
        StopPrinting()
      EndIf
    EndIf 
  EndWith
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4995
Joined: Sun Apr 12, 2009 6:27 am

Re: [Solved] Capture window as an image

Post by RASHAD »

Hi Fang
All you need is the Handle of the requested Window
(It is not OK all the times but you can copy any window even if it is in the back)

Code: Select all

Prototype.i ptPrintWindow(hWnd, hdc, flags)

OpenLibrary(0, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(0, "PrintWindow")

ID = RunProgram("Notepad.exe","","",#PB_Program_Open)
Delay(100)
Repeat
  hWnd = FindWindow_(0,"Untitled - Notepad")
Until hWnd

SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) | #WS_CLIPSIBLINGS)
SetWindowPos_(hWnd, #HWND_BOTTOM, -1, -1, -1, -1, #SWP_NOSIZE | #SWP_NOMOVE)

GetWindowRect_(hWnd,r.RECT)
 ww = r\right-r\left
 wh = r\bottom-r\top
  If CreateImage(1, ww,wh, 24)
    hdc = StartDrawing(ImageOutput(1))
    If hdc
      PrintWindow(hWnd, hdc,0)
      StopDrawing()
    EndIf
  EndIf
  
SaveImage(1,GetHomeDirectory()+"Test.bmp")
KillProgram(ID)
CloseLibrary(0)

Egypt my love
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: [Solved] Capture window as an image

Post by Fangbeast »

Hi RASHAD, just tried your solution. It's still printing black borders from the window underneath it. But thinner than before.

I have massaged your code into MyStuff and it works.

Code: Select all

Procedure PrintThisStuffFromRecord()
  
  ; 
  
  HideGadget(#Gadget_Datasheet_cControl, #True)
  
  ResizeWindow(#Window_Datasheet, #PB_Ignore, #PB_Ignore, 1000, 645)
  
  ; Test function from RASHAD to print window image without side bars from wallpaper
  
  OpenLibrary(0, "User32.dll")                                                                           ; 
  
  PrintWindow.ptPrintWindow = GetFunction(0, "PrintWindow")                                             ; 
  
  WindowHandle.i = WindowID(#Window_Datasheet)
  
  SetWindowLongPtr_(WindowHandle.i, #GWL_STYLE, GetWindowLongPtr_(WindowHandle.i, #GWL_STYLE) | #WS_CLIPSIBLINGS)
  
  SetWindowPos_(WindowHandle.i, #HWND_BOTTOM, -1, -1, -1, -1, #SWP_NOSIZE | #SWP_NOMOVE)
  
  GetWindowRect_(WindowHandle.i, r.RECT)
  
  WindowsWidth.i = r\right  - r\left
  
  WindowsHeight.i = r\bottom - r\top
  
  PrintableImage.i = CreateImage(#PB_Any, WindowsWidth.i, WindowsHeight.i, 24)
  
  If PrintableImage.i
    
    DeviceContextHandle.i = StartDrawing(ImageOutput(PrintableImage.i))
    
    If DeviceContextHandle.i
      
      PrintWindow(WindowHandle.i, DeviceContextHandle.i, 0)
      
      StopDrawing()
      
    EndIf
    
    ;SaveImage(PrintableImage.i,"D:\Test.jpg", #PB_ImagePlugin_PNG)
    
    If PrintRequester()
      
      If StartPrinting("MyStuff Record Print")
        
        Factor.f = PrinterPageWidth() / ImageWidth(PrintableImage.i)
        
        If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
          
          MovePathCursor(0, 0)
          
          DrawVectorImage(ImageID(PrintableImage.i), 255, ImageWidth(PrintableImage.i) * Factor, ImageHeight(PrintableImage.i) * Factor)
          
          StopVectorDrawing()
          
        Else
          
          ; Could not print to the requested output
          
        EndIf
        
        StopPrinting()
        
      Else
        
        ; Vector printer failed to start
        
      EndIf
      
    Else
      
      ; Print requester failed
      
    EndIf 
    
  Else
    
    ; No image generated, could not print
    
  EndIf  
  
  ;
  
  CloseLibrary(0)

  ; 
  
  HideGadget(#Gadget_Datasheet_cControl, #False)
  
  ResizeWindow(#Window_Datasheet, #PB_Ignore, #PB_Ignore, 1000, 750)
  
  ; 
  
EndProcedure
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Post Reply