Page 2 of 2
Re: How to print window contents?
Posted: Wed Jan 20, 2010 11:35 pm
by jamirokwai
WilliamL wrote:@jamirokwai ยป Thanks for the effort. I appreciate it. Maybe I can repay you by getting an explanation of how the command works.
No prob, WilliamL.
As I said, I needed this command for my latest project, so I coded and posted it. I had the idea from the second post...
But I prefer native commands though since they should know, what they accomplish

Re: How to print window contents?
Posted: Wed Jan 20, 2010 11:37 pm
by luis
A couple of notes:
1) you wrote: DrawImage(ImageID(imageid),w,h)
please note the 2nd and 3th params are the starting positon, not width and height
2) as it is the code print only the client aerea of the window, because windowheight() and windowwidth() returns only that.
If I may... you should drop the habit to use .l for the vars unless it's really needed
see
http://www.purebasic.fr/blog/?p=42
See you around

Re: How to print window contents?
Posted: Thu Jan 21, 2010 6:36 pm
by WilliamL
Now that I have the window printed out I'm finding that the output, if in color, the grays are in rainbow colors and is unreadable, if I print out in grayscale the text is in waves of dark and light and just as unreadable.
@jamirokwai - Are you having this problem?
Do you think if the image data is scanned and a threshhold filter is used to turn the grays (or rainbows) to black would improve the output?
Of course, you would only use this filter for text and non-color and it wouldn't sharpen anything.
@luis - could this be converted into a threshhold filter?
Code: Select all
Procedure.l GrayscaleImage(image_no.l, method.l = #GrayscaleImage_Weighted) ; < note the .l definitions?
; ***************************************************************************
;
; Function: Converts an image to grayscale
;
; Returns: '1' if successful, otherwise '0'
;
; ***************************************************************************
Protected *mem.l, mem_size.l, mem_pos.l
Protected color.l, r.l, g.l, b.l
If IsImage(image_no) = 0
ProcedureReturn 0
EndIf
mem_size = ImageWidth(image_no) * ImageHeight(image_no) << 2
*mem = AllocateMemory(mem_size)
If *mem = 0
ProcedureReturn 0
EndIf
CopyImageToMemory(image_no, *mem)
For mem_pos = 0 To mem_size - 1 Step 4
color = PeekL(*mem + mem_pos)
r = FastRed(color)
g = FastGreen(color)
b = FastBlue(color)
Select method
Case #GrayscaleImage_Mean
color = (r + g + b) / 3
Case #GrayscaleImage_Weighted
color = 0.299 * r + 0.587 * g + 0.114 * b
Case #GrayscaleImage_Weighted2
color = 0.3086 * r + 0.6094 * g + 0.0820 * b
Default
ProcedureReturn 0
EndSelect
PokeL(*mem + mem_pos, FastRGB(color, color, color))
Next
CopyMemoryToImage(*mem, image_no)
FreeMemory(*mem)
ProcedureReturn 1
EndProcedure
Re: How to print window contents?
Posted: Thu Jan 21, 2010 9:11 pm
by luis
WilliamL wrote:Now that I have the window printed out I'm finding that the output, if in color, the grays are in rainbow colors and is unreadable, if I print out in grayscale the text is in waves of dark and light and just as unreadable.
If I try to print with the last code I posted looks good, probably it's a question of how good the printer driver is to map the color into greyscale.
WilliamL wrote:
@luis - could this be converted into a threshhold filter?
I read your pm, but this is not my code, original thread is this:
http://www.purebasic.fr/english/viewtop ... 12&t=38897
Certainly you can reduce the color of the original grabbed image to 8 or even 2 bits if you like, to compensate for a probably not exceptional printer driver.
If you reduce the color to only 2 bits (probably it's overkill) you would have to use some form of dithering too.
I would say if you reduce the image to greyscale and then print that, should be ok. I read you seem to have tried that, and the fact it's not working surprise me. But maybe again you relied on the printer driver to do that, so try to convert the image to greyscale before print it.
Code: Select all
Procedure.l GrayscaleImage(image_no.l, method.l = #GrayscaleImage_Weighted) ; < note the .l definitions?
Yes, I noted the .l definitions (so ... uh ?)
You can try with the code you just found, or try to look in the forum for greyscale conversion or something like that, or you can do it by yourself, simply reading the source pixel, adding the r g b components, dividing them by 3 and then storing the result in the same pixel. Refer to the code you posted for other "perceptual different" ways to do that.
Try that.
Re: How to print window contents?
Posted: Thu Jan 21, 2010 9:54 pm
by WilliamL
luis,
After much thought about the problem I think you are right about the printer driver being the problem. I don't think a threshhold filter would make any difference but printing in gray scale does help.
Oh, not your code? My mistake and my apologies. I copied the code some time ago and, for some reason, I attributed to you. Although I attributed the code incorrectly, I chose a good person to ask with my questions. Thanks for all your input.
My apologies Dreamland Fantasy - it was your code!
Re: How to print window contents?
Posted: Thu Jan 21, 2010 10:18 pm
by luis
You can try this: open a pb window you would like to print, capture the window and paste it into a photoshop-like program, try to print the image in color and see if the problem is still present printing from that program too. Then convert the image using the same program to grayscale and print that. If the problem disappear you know you should convert the image to grayscale in your pb program too and than you can concentrate on that.
Bye!
Re: How to print window contents?
Posted: Mon Aug 13, 2012 12:02 am
by WilliamL
Well, this code worked up to 4.61 but it doesn't work in 4.71. I suppose there is a bug here or maybe something works differently. Any ideas?
Code: Select all
#wndw=1
#gadget1=1
#gadget2=2
Procedure PrintWindow(wndid)
Define imageid
w=WindowWidth(wndid)
h=WindowHeight(wndid)
If CreateImage(imageid,w,h)
If StartDrawing(WindowOutput(wndid))
imageid = GrabDrawingImage(#PB_Any,0,0,w,h)
StopDrawing()
EndIf
EndIf
If PrintRequester()
If StartPrinting("Print window")
If StartDrawing(PrinterOutput())
DrawImage(ImageID(imageid),w,h)
StopDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndProcedure
w=200
h=200
If OpenWindow(#wndw,0,0,w,h+64, "test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#gadget2, 10, 10, 100, 30, "print")
ListViewGadget(#gadget1,4,210,w-8,50)
AddGadgetItem(#gadget1,-1,"Line 1")
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
If EventGadget() = #gadget2
PrintWindow(#wndw)
EndIf
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
End
Re: How to print window contents?
Posted: Mon Aug 13, 2012 4:59 am
by wilbert
For Cocoa, the easiest way with CocoaMessage is like this
Code: Select all
#wndw=1
#gadget1=1
#gadget2=2
w=200
h=200
If OpenWindow(#wndw,0,0,w,h+64, "test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#gadget2, 10, 10, 100, 30, "print")
ListViewGadget(#gadget1,4,210,w-8,50)
AddGadgetItem(#gadget1,-1,"Line 1")
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
If EventGadget() = #gadget2
CocoaMessage(0, WindowID(#wndw), "print:", #nil)
EndIf
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
End
Re: How to print window contents?
Posted: Mon Aug 13, 2012 8:16 am
by Fred
Looks like a bug with GrabDrawingImage() and WindowOutput(), feel free to open a bug report
Re: How to print window contents?
Posted: Mon Aug 13, 2012 5:10 pm
by WilliamL
Thanks wilbert! I tried it and it works fine.
I will post my example on the bugs forum for Fred to look at.
Re: How to print window contents?
Posted: Tue Aug 14, 2012 3:05 am
by WilliamL
Hey wilbert,
How do I grab the window into an image?
Re: How to print window contents?
Posted: Tue Aug 14, 2012 5:31 am
by wilbert
WilliamL wrote:How do I grab the window into an image?
Unfortunately there's not a simple Cocoa method to do so.
The window has a method to output itself or part of it into pdf data.
The pdf data then can be used to create an image.
If Fred fixes the GrabDrawingImage problem, that is most likely the easiest way.
Re: How to print window contents?
Posted: Tue Aug 14, 2012 5:46 am
by J. Baker
WilliamL wrote:Hey wilbert,
How do I grab the window into an image?
Code: Select all
RunProgram("screencapture", "-iW " + GetHomeDirectory() + "Desktop/screen.jpg", "")
-S In window capture mode, capture the screen instead of the window.
-W Start interaction in window selection mode.
-c Force screen capture to go to the clipboard.
-i Capture screen interactively, by selection or window. The con-
trol key will cause the screen shot to go to the clipboard. The
space key will toggle between mouse selection and window selec-
tion modes. The escape key will cancel the interactive screen
shot.
-m Only capture the main monitor, undefined if -i is set.
-s Only allow mouse selection mode.
-w Only allow window selection mode.
-x Do not play sounds.
-C Capture the cursor as well as the screen. Only allowed in non-
interactive modes.
-t <format> Image format to create, default is png.
file where to save the screen capture