AutoHotkey Community

It is currently May 27th, 2012, 11:15 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: February 12th, 2012, 3:15 pm 
Offline

Joined: March 24th, 2007, 8:10 pm
Posts: 39
Hello everyone.

I recently had to capture some program windows for a tutorial and I wanted to use a dark background in PowerPoint but also wanted to print it with white background. You know the problem: capture just the client area or deal with semitransparent borders and shadows?

Then I remembered and interesting example in the ImageMagick documentation ("Background Removal using Two Backgrounds") and decided to wrap it with AutoHotkey. The script below is the result.

Putting it plainly, the script hides the desktop and takes two screenshots: one with a black background and another one with a white one. Then ImageMagick compares both images and builds an image with alpha channel (variable transparency) from them. Something like this:

Image + Image = Image

Notes
  • Requires ImageMagick (duh)
  • Tested only with AutoHotkey_L in Windows 7 x64 with Aero enabled and photographic wallpapers
  • You may need to adapt the values in the initial code block ("configuration")

Code:
; configuration
Delay = 100
StartButtonName = Start
ImageMagickPath = %A_ProgramFiles%\ImageMagick

; backup initial status: wallpaper, background color and desktop icon visibility
RegRead, WallpaperPath, HKEY_CURRENT_USER, Control Panel\Desktop, Wallpaper
SplitPath, WallpaperPath, WallpaperFilename
WallpaperBackupPath = %A_ScriptDir%\%WallpaperFilename%
FileCopy, %WallpaperPath%, %WallpaperBackupPath%
BackgroundColorBackup := DllCall("GetSysColor", Int, 1) ; see http://msdn.microsoft.com/ms724371.aspx
RegRead, HideIcons, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, HideIcons

OnExit, CleanUp

; Win+PrtScr hotkey
#PrintScreen::

   ; hide desktop icons if visible
   If (HideIcons = 0) {
      ControlGet, HWND, Hwnd,, SysListView321, ahk_class Progman
      If HWND =
         ControlGet, HWND, Hwnd,, SysListView321, ahk_class WorkerW
      WinHide, ahk_id %HWND%
   }

   ; hide desktop taskbar and Start button (locale dependant)
   WinHide ahk_class Shell_TrayWnd
   WinHide %StartButtonName% ahk_class Button

   ; black background capture
   DllCall("SetSysColors", Int, 1, IntP, 1, UIntP, 0x000000) ; see http://msdn.microsoft.com/ms724940.aspx
   DllCall("SystemParametersInfo", UInt, 0x14, UInt, 0, Str, "", UInt, 0x03) ; see http://msdn.microsoft.com/ms724947.aspx
   Sleep, %Delay%
   Send, {Printscreen}
   Sleep, %Delay%
   RunWait, %ImageMagickPath%\convert clipboard:myimage black_screen_capture.png, , Hide

   ; white background capture
   DllCall("SetSysColors", Int, 1, IntP, 1, UIntP, 0xFFFFFF)
   Sleep, %Delay%
   Send, {Printscreen}
   Sleep, %Delay%
   RunWait, %ImageMagickPath%\convert clipboard:myimage white_screen_capture.png, , Hide

   ; restore original wallpaper and background color
   DllCall("SetSysColors", Int, 1, IntP, 1, UIntP, BackgroundColorBackup)
   FileCopy, %WallpaperBackupPath%, %WallpaperPath%
   DllCall("SystemParametersInfo", UInt, 0x14, UInt, 0, Str, WallpaperPath, UInt, 0x03)

   ; show desktop taskbar and Start button
   WinShow ahk_class Shell_TrayWnd
   WinShow %StartButtonName% ahk_class Button

   ; show desktop icons if previously hidden
   If (HideIcons = 0) {
      ControlGet, HWND, Hwnd,, SysListView321, ahk_class Progman
      If HWND =
         ControlGet, HWND, Hwnd,, SysListView321, ahk_class WorkerW
      WinShow, ahk_id %HWND%
   }

   ; combine black and white captures
   RunWait, %ImageMagickPath%\convert black_screen_capture.png white_screen_capture.png -alpha off ( -clone 0`,1 -compose difference -composite -negate ) ( -clone 0`,2 +swap -compose divide -composite ) -delete 0`,1 +swap -compose Copy_Opacity -composite -trim transparent_screen_capture_%A_Now%.png, , Hide
   FileDelete, black_screen_capture.png
   FileDelete, white_screen_capture.png

return

CleanUp:
FileDelete, %WallpaperBackupPath%
ExitApp

Examples
Image Image Image

I'd love to get feedback from other users, especially if they have different configurations than mine. I'd also appreciate any suggestion to improve the code.

_________________
Regards,
Antonio


Last edited by atnbueno on February 20th, 2012, 8:57 am, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 8:44 pm 
Hi,

nice idea.

I use Win XP 32 bit ServicPack 3 with an windowblind theme. And two monitors with different resolutions.

I installed ImageMagick-6.7.5-5-Q16.

But it does not seem to work.

Image


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 9:56 pm 
Offline

Joined: March 24th, 2007, 8:10 pm
Posts: 39
Mmmm. I hadn't even considered the case of two monitors. Is the 2194x1050 I see in the included capture the resolution of your primary monitor or is it lower?

I have no idea where those black bars come from. If not for them it would probably work as expected (the -trim option at the end of the script is there to crop the unnecesary transparent pixels around the captured window/s, but it would get confused by those bars).

Do you have any always-on widget in your desktop?

_________________
Regards,
Antonio


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 10:26 pm 
My primary monitor has a resolution of 1600x1050 and my secondary a resolution of 1280x1024.

Because of this difference he replace nonexistent pixel with this black bars.

Maybe there is a way, to always cut these areas out.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 10:58 pm 
Offline

Joined: March 24th, 2007, 8:10 pm
Posts: 39
So PrtScr captures both monitors at the same time? Interesting.

I see the bars are 1280px wide, with 24px the top one and just 2px the bottom one. If they always appear in the same place, you could paint them white when doing the white background capture (IIRC it would need two additional ImageMagick commands, -fill and -draw, in the second RunWait).

If you post the black and white captures (comment the FileDeletes at the end of the script to avoid deleting them after combining them) I'll tell you the exact ImageMagick command to use.

Thanks for the feedback!

_________________
Regards,
Antonio


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 11:09 pm 
Yes PrtScr captures both screens.

Here are the three pictures:

black:
Image

white:
Image

transparent:
Image

Thank you for your efforts.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 11:33 pm 
Offline

Joined: March 24th, 2007, 8:10 pm
Posts: 39
Try the following: Change the line
Code:
RunWait, %ImageMagickPath%\convert clipboard:myimage white_screen_capture.png, , Hide

for this one
Code:
RunWait, %ImageMagickPath%\convert clipboard:myimage -fill white -draw "rectangle 1600`,0 2959`,23" -draw "rectangle 1600`,1048 2959`,1049" white_screen_capture.png, , Hide

That should do the trick for your setup :)

_________________
Regards,
Antonio


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2012, 11:41 pm 
Thank you, it works now for me, too.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 19th, 2012, 8:27 pm 
Offline

Joined: March 24th, 2007, 8:10 pm
Posts: 39
Hello again.

I'm glad it works.

A few self-comments:
  • I've been playing with the script and there are some minor advantages on doing the screenshots via DllCall instead of Sending {PrintScreen}, but at the cost of making the script more complicated.
  • I've mimicked the PrtScr and Alt+PrtScr combo with Ctrl+PrtScr (instead of Win+PrtScr) and Alt+PrtScr for full screen and active window capture.
  • I've also used ImageMagickObject instead of using the command line. It saves having to specify ImageMagick path but it requires enabling a non-default option during the installation. It also makes it less portable.
  • Speaking of portable, it's not necessary to install the full ImageMagick package. For this script it's enough to use the convert.exe from the portable (zipped) version of ImageMagick (1.7MB when UPX'd). If size is an issue it can be brought down to 1.3MB with the following (UPX'd) files from the standard installation: convert.exe, CORE_RL_bzlib_.dll, CORE_RL_lcms_.dll, CORE_RL_magick_.dll, CORE_RL_ttf_.dll, CORE_RL_wand_.dll, CORE_RL_zlib_.dll, vcomp100.dll, X11.dll
  • I've also been able to determine the Start Menu button name in a bit of a hackish way (MouseMove, Click middle and WinGetActiveTitle) but, again, at the cost of complicating the script for somewhat trivial details.


P.S. I've also added a bit of an explanation on how the script works in the OP.

_________________
Regards,
Antonio


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 20th, 2012, 12:30 am 
Offline

Joined: October 13th, 2009, 10:09 pm
Posts: 1389
Nice idea! I wish windows would be able to do this through an API.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: nomissenrojb, Rajat and 53 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group