GrabDrawingImage()

Just starting out? Need help? Post your questions and find answers here.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

GrabDrawingImage()

Post by IdeasVacuum »

I know how to capture an image using Windows API, but I thought I'd try GrabDrawingImage() as it is cross-platform:

Code: Select all

UsePNGImageEncoder()

Enumeration
#Wn
#Image
EndEnumeration

     If OpenWindow(#Wn,0,0,200,200,"Win",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)

            SetWindowColor(#Wn,RGB(0,96,96))

             If StartDrawing(WindowOutput(#Wn))
             
                         ;CreateImage(#Image, 200, 200, 24)
                   GrabDrawingImage(#Image, 0, 0, 200, 200)
                           StopDrawing()
             
                             SaveImage(#Image, "C:\Image.png", #PB_ImagePlugin_PNG)
             EndIf
             
             Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

     EndIf

End
Result is a blank image?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Michael Vogel
Addict
Addict
Posts: 2806
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: GrabDrawingImage()

Post by Michael Vogel »

I fear, the window gets invalidated, when GrabDrawingImage gets called. When pressing the button (see code below), you get the colored background but not the lines. I've tried to insert some WaitEvents to allow painting the lines before grabbing the content with no changes in the result.

Code: Select all

UsePNGImageEncoder()

Enumeration
	#Wn
	#Image
EndEnumeration

If OpenWindow(#Wn,0,0,400,200,"Win",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
	ButtonGadget(33,0,0,200,20,"Hi")
	CreateImage(#Image,200,200,32)
	ImageGadget(99,200,0,200,200,ImageID(#Image))

	SetWindowColor(#Wn,RGB(0,96,96))

	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			quit=#True
		Case #PB_Event_Gadget
			If StartDrawing(WindowOutput(#Wn))
				LineXY(50,50,150,150,#Red)
				LineXY(150,50,50,150,#Yellow)
				GrabDrawingImage(#Image,0,0,200,200)
				StopDrawing()
			EndIf
			SetGadgetState(99,ImageID(#Image))
		EndSelect

	Until quit

EndIf
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: GrabDrawingImage()

Post by luis »

IdeasVacuum wrote:Result is a blank image?
Yes.


I'll add something else to the reply :wink:

1) you should wait for all messages to be processed before capturing the window or some pieces could be missing

2) the grabbed image is 32 bit and the alpha is set to fully transparent for the background so you have to set it to fully opaque or you will get the blank image you are reporting (since in your example the window contained background only).

Code: Select all

UsePNGImageEncoder()

Enumeration
#Wn
#Image
#btn
EndEnumeration

Procedure GetIt()
StartDrawing(WindowOutput(#Wn))
 GrabDrawingImage(#Image, 0, 0, 200, 200)
StopDrawing()

StartDrawing(ImageOutput(#Image))
 DrawingMode(#PB_2DDrawing_AlphaChannel)
 Box(0,0,200,200,RGBA(0,0,0,255))    
StopDrawing()

SaveImage(#Image, "C:\Image.png", #PB_ImagePlugin_PNG)       
EndProcedure

If OpenWindow(#Wn,0,0,200,200,"Win",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)

    SetWindowColor(#Wn,RGB(0,96,96))
    ButtonGadget(#btn, 10, 10, 180, 30, "Hello")
        
     
    Repeat 
        iEvent = WaitWindowEvent() 
    Until iEvent = #PB_Event_CloseWindow
    
    GetIt()    

EndIf

"Have you tried turning it off and on again ?"
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: GrabDrawingImage()

Post by BasicallyPure »

@luis,
Hmmm, I don't see how putting GrabDrawingImage before you actually draw on the image demonstrates the GrabDrawingImage function.
It looks to me like your code only saves the image that you drew, not the image that you grabbed.

I tried but was unsuccessful in using GrabDrawingImage directly from a window.
I did discover that if you use drawingmode #PB_2DDrawing_XOr the lines are visible in the grabbed image using Michael Vogel's code.

GrabDrawingImage seems to work correctly when used with another image and presumably screen and canvas would work as well. It seems that it fails only when used directly from a window.

Code: Select all

;
Enumeration
   #ImageGadget_01
   #ImageGadget_02
   #Image_01
   #Image_02
   #ButtonDraw
   #ButtonGrab
EndEnumeration

If OpenWindow(0,0,0,434,240,"Win",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
   SetWindowColor(0,RGB(0,96,96))
   
   ButtonGadget(#ButtonDraw,010,5,80,20,"Draw")
   ButtonGadget(#ButtonGrab,220,5,80,20,"Grab")
   CreateImage(#Image_01,200,200)
   CreateImage(#Image_02,200,200)
   ImageGadget(#ImageGadget_01,010,30,200,200,ImageID(#Image_01),#PB_Image_Border)
   ImageGadget(#ImageGadget_02,220,30,200,200,ImageID(#Image_02),#PB_Image_Border)
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_CloseWindow
            quit = #True
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #ButtonDraw
                  If StartDrawing(ImageOutput(#Image_01))
                     Box(040,75,50,50,Random($FFFFFF))
                     Box(110,75,50,50,Random($FFFFFF))
                     StopDrawing()
                     SetGadgetState(#ImageGadget_01,ImageID(#Image_01))
                  EndIf
               Case #ButtonGrab
                  If StartDrawing(ImageOutput(#Image_01))
                     GrabDrawingImage(#Image_02,0,0,200,200)
                     StopDrawing()
                     SetGadgetState(#ImageGadget_02,ImageID(#Image_02))
                  EndIf
            EndSelect
      EndSelect
   Until quit
   
EndIf
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: GrabDrawingImage()

Post by luis »

Hi!
BasicallyPure wrote: Hmmm, I don't see how putting GrabDrawingImage before you actually draw on the image demonstrates the GrabDrawingImage function.
I didn't draw on the image, I changed the alpha channel (#PB_2DDrawing_AlphaChannel).
BasicallyPure wrote: It looks to me like your code only saves the image that you drew, not the image that you grabbed.
No. GrabDrawingImage did already transfer the content of the window client area to the image. What GrabDrawingImage grabbed (the pixels) wasn't changed. The problem is the image is transparent and you have to do something about it.
Did you look at the saved image by the way ? Does it looks like a box to you ? So how can be what I drawn (a black box) when it does contain the window with the button ? :)
BasicallyPure wrote: GrabDrawingImage seems to work correctly when used with another image and presumably screen and canvas would work as well. It seems that it fails only when used directly from a window.
And that was the point of the original question. Using it with windowoutput(). Using the two steps demonstrated above the image was grabbed and saved successfully even if GrabDrawingImage behave differently in this context.
"Have you tried turning it off and on again ?"
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: GrabDrawingImage()

Post by IdeasVacuum »

the grabbed image is 32 bit and the alpha is set to fully transparent
That I did not know - I expected it to be 24bit RGB - would be good to mention in the Help.

I think my example was a bad choice! :?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: GrabDrawingImage()

Post by BasicallyPure »

@luis,
Thanks for the clarification.
Now I think I finally understand.
Not being familiar with how alpha channels work I was confused by your code.
I did some modification to the code to make sure I understood.
IdeasVacuum wrote:would be good to mention in the Help
I second that.

Code: Select all

; demonstration of how to use GrabDrawingImage() with Window as source
;
Enumeration
   #Wn
   #Image
   #btn
   #ImgGad
EndEnumeration

Procedure GetIt()
   ;grab image directly from window
   ;grabbed image is 32 bit and alpha is fully transparent
   StartDrawing(WindowOutput(#Wn))
      GrabDrawingImage(#Image, 0, 0, 200, 200)
   StopDrawing()
   
   ;adjust the image alpha channel to opaque
   StartDrawing(ImageOutput(#Image))
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0,0,200,200,RGBA(0,0,0,255))
   StopDrawing()
EndProcedure

If OpenWindow(#Wn,0,0,400,200,"Win",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
   
   SetWindowColor(#Wn,RGB(0,96,96))
   ButtonGadget(#btn, 10, 10, 180, 30, "Grab and display")
   ImageGadget(#ImgGad,200,0,200,200,0)
   
   ;draw something on the window
   StartDrawing(WindowOutput(#Wn))
   LineXY(50,50,150,150,#Red)
   LineXY(150,50,50,150,#Yellow)
   StopDrawing()
   
   Repeat
      iEvent = WaitWindowEvent() 
      If iEvent = #PB_Event_Gadget And EventGadget() = #btn
         GetIt()
         SetGadgetState(#ImgGad,ImageID(#Image)) ;display the grabbed image
      EndIf
   Until iEvent = #PB_Event_CloseWindow
   
EndIf

BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
skywalk
Addict
Addict
Posts: 4217
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: GrabDrawingImage()

Post by skywalk »

Is there a cross platform way to also grab the window title and borders?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: GrabDrawingImage()

Post by luis »

@BasicallyPure

Yup, please note only what it has been drawn directly on the background (and the background itself) is fully transparent.
The gadgets, for example, are visible (opaque).
If you comment from your last code the alpha filling, the button is still visible.
:?
"Have you tried turning it off and on again ?"
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: GrabDrawingImage()

Post by IdeasVacuum »

... yeah, done a few experiments and understand it now. The 'problem' is, it does what it is designed to do, rather than what I thought it would do :mrgreen:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply