SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

Post your working scripts, libraries and tools
User avatar
SKAN
Posts: 391
Joined: 29 Sep 2013, 16:58

SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

04 Sep 2019, 13:54

SavePicture( hBM, sFile )

Note: This function offers limited functionality: JPEG quality is fixed at 75% and transparency will not be preserved for PNG.
Saved file will be a BMP if you pass any file extension other than: BMP, JPG, JPEG, GIF, PNG, TIF, TIFF

Code: Select all

SavePicture(hBM, sFile) {                                            ; By SKAN on D293 @ bit.ly/2krOIc9
Local V,  pBM := VarSetCapacity(V,16,0)>>8,  Ext := LTrim(SubStr(sFile,-3),"."),  E := [0,0,0,0]
Local Enc := 0x557CF400 | Round({"bmp":0, "jpg":1,"jpeg":1,"gif":2,"tif":5,"tiff":5,"png":6}[Ext])
  E[1] := DllCall("gdi32\GetObjectType", "Ptr",hBM ) <> 7
  E[2] := E[1] ? 0 : DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr",hBM, "UInt",0, "PtrP",pBM)
  NumPut(0x2EF31EF8,NumPut(0x0000739A,NumPut(0x11D31A04,NumPut(Enc+0,V,"UInt"),"UInt"),"UInt"),"UInt")
  E[3] := pBM ? DllCall("gdiplus\GdipSaveImageToFile", "Ptr",pBM, "WStr",sFile, "Ptr",&V, "UInt",0) : 1
  E[4] := pBM ? DllCall("gdiplus\GdipDisposeImage", "Ptr",pBM) : 1
Return E[1] ? 0 : E[2] ? -1 : E[3] ? -2 : E[4] ? -3 : 1  
}
  • ErrorLevel


SavePicture() requires GDI+ initialized prior to calling it.
GDI+ can be Start.Shut with GDIP("Startup") and GDIP("Shutdown")
Thanks to @tmplinshi for a bug report. Now fixed.

Code: Select all

GDIP(C:="Startup") {                                      ; By SKAN on D293 @ bit.ly/2krOIc9
  Static SI:=Chr(!(VarSetCapacity(Si,24,0)>>16)), pToken:=0, hMod:=0, Res:=0, AOK:=0
  If (AOK := (C="Startup" and pToken=0) Or (C<>"Startup" and pToken<>0))  {
      If (C="Startup") {
               hMod := DllCall("LoadLibrary", "Str","gdiplus.dll", "Ptr")
               Res  := DllCall("gdiplus\GdiplusStartup", "PtrP",pToken, "Ptr",&SI, "UInt",0)
      } Else { 
               Res  := DllCall("gdiplus\GdiplusShutdown", "Ptr",pToken)
               DllCall("FreeLibrary", "Ptr",hMod),   hMod:=0,   pToken:=0
   }}  
Return (AOK ? !Res : Res:=0)    
}

Usage example

The cryptic nested NumPut explained

The following script will automatically Save picture (JPEG) when PrintScreen / Alt+PrintScreen is used for screen capture.

Code: Screen capture demo
tmplinshi
Posts: 1557
Joined: 01 Oct 2013, 14:57

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

07 Sep 2019, 00:29

Hi, just a bug report for 64-bit AutoHotkey:

The return type of LoadLibrary function should be Ptr, otherwise the calling to FreeLibrary function would be fail.

Code: Select all

MsgBox % DllCall("FreeLibrary", "Ptr",hMod) ? "success" : "fail"
User avatar
SKAN
Posts: 391
Joined: 29 Sep 2013, 16:58

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

07 Sep 2019, 03:11

Thank you @tmplinshi :)
Fixed.
User avatar
danrevella
Posts: 9
Joined: 27 Jan 2016, 05:08

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 09:41

Hi,
please excuse for boring, I have look at your tool (and also another in fact this post is replicate over), but I am in search of a script who let me capture and save a full windows who is larger then my desktop: f.e my desktop is 1920*1080 but the window I need to capture is 9400*9200, so if i use PrintScreen or Alt-Printscreen, I obtain an image who only show 1920*1080 instead of 9400*9200.
Does exist a possibility to get the full capture window?
Many thanks
User avatar
SKAN
Posts: 391
Joined: 29 Sep 2013, 16:58

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 10:50

danrevella wrote:
03 Jan 2020, 09:41
f.e my desktop is 1920*1080 but the window I need to capture is 9400*9200
I don't understand how this is possible?
If I try to resize a given window to be larger than desktop, the window is resized only to the size of desktop.
For example, with single monitor setup sized 1366x768, I am not able to resize notepad window to 6000x4000 ?!

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force

Run Notepad
Winwait ahk_class Notepad
WinMove,,, 0, 0, 6000, 4000
User avatar
danrevella
Posts: 9
Joined: 27 Jan 2016, 05:08

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 11:26

It is possible: try this an give any resolution you want to a (resizable) window


; [^ = Ctrl] [+ = Shift] [! = Alt] [# = Win]
;WIN+t hotkey

#t::
WinGet, window, ID, A
InputBox, width, Resize window, Enter width:, , 170, 130
if (width != "")
{
InputBox, height, Resize Window, Enter height:, , 170, 130
}
WinGetTitle, Title, A
MsgBox, The active window is "%Title%".

WinGet, id, , %Title%
Result := DllCall("SetWindowPos", "uint", id, "uint", HWND_TOP, "Int", 0, "Int", 0, "Int", width, "Int", height, "UInt", 0x400)

return

User avatar
SKAN
Posts: 391
Joined: 29 Sep 2013, 16:58

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 14:12

danrevella wrote:
03 Jan 2020, 11:26
It is possible: try this an give any resolution you want to a (resizable) window
Thanks. Nice test code. Nitpick: You haven't defined the constant HWND_TOP which should be 0.

Your snippet doesn't work for all apps though. Maybe those apps have message handlers to override the resize.
Works when tested with Notepad and AutoHotkey help. AutoHotkey spy reveals the window size correctly.

I tried resizing AutoHotkey help to 2000x2000 (My screen is 1366x768) and took a snaphot with hBM := hWnd_to_hBmp( WinExist("A") )
and saved it with SavePicture().
The function is unable to blit the title bar correctly, in Windows 7. Yet to try in Windows 10.
Please refer the attachment
Attachments
ahk.jpg
ahk.jpg (211.7 KiB) Viewed 579 times
guest3456
Posts: 2992
Joined: 09 Oct 2013, 10:31

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 14:13

danrevella wrote:
03 Jan 2020, 11:26
It is possible: try this an give any resolution you want to a (resizable) window


; [^ = Ctrl] [+ = Shift] [! = Alt] [# = Win]
;WIN+t hotkey

#t::
WinGet, window, ID, A
InputBox, width, Resize window, Enter width:, , 170, 130
if (width != "")
{
InputBox, height, Resize Window, Enter height:, , 170, 130
}
WinGetTitle, Title, A
MsgBox, The active window is "%Title%".

WinGet, id, , %Title%
Result := DllCall("SetWindowPos", "uint", id, "uint", HWND_TOP, "Int", 0, "Int", 0, "Int", width, "Int", height, "UInt", 0x400)

return

does not work for me. i tried resizing notepad to 9000 width, and it only resized to approx 4800 width, which spanned my two monitors.

you could try PrintWindow() to get the screenshot

User avatar
danrevella
Posts: 9
Joined: 27 Jan 2016, 05:08

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 15:22

SKAN wrote:
03 Jan 2020, 14:12
danrevella wrote:
03 Jan 2020, 11:26
It is possible: try this an give any resolution you want to a (resizable) window
Thanks. Nice test code. Nitpick: You haven't defined the constant HWND_TOP which should be 0.

Your snippet doesn't work for all apps though. Maybe those apps have message handlers to override the resize.
Works when tested with Notepad and AutoHotkey help. AutoHotkey spy reveals the window size correctly.

I tried resizing AutoHotkey help to 2000x2000 (My screen is 1366x768) and took a snaphot with hBM := hWnd_to_hBmp( WinExist("A") )
and saved it with SavePicture().
The function is unable to blit the title bar correctly, in Windows 7. Yet to try in Windows 10.
Please refer the attachment
As I told you, I'm a total beginner in AHK, so please may you post your example with a full working code (also with the necessary dependences?
Many thanks
User avatar
danrevella
Posts: 9
Joined: 27 Jan 2016, 05:08

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

03 Jan 2020, 15:24

guest3456 wrote:
03 Jan 2020, 14:13

does not work for me. i tried resizing notepad to 9000 width, and it only resized to approx 4800 width, which spanned my two monitors.

you could try PrintWindow() to get the screenshot
As I told I'm a newbie, may you gentle tell me about PrintWindow(), is it a native function, or is it a library, may you be so kind to give me the necessary code?
Thanks
User avatar
SKAN
Posts: 391
Joined: 29 Sep 2013, 16:58

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

04 Jan 2020, 03:04

I have to test this in Windows 10.
I'm leaving city and will be back on Monday.
User avatar
danrevella
Posts: 9
Joined: 27 Jan 2016, 05:08

Re: SavePicture() : Save hBitmap as BMP, JPG, GIF, PNG, TIF

04 Jan 2020, 05:48

you told me:
Thanks. Nice test code. Nitpick: You haven't defined the constant HWND_TOP which should be 0.

So may you give me the correction to my code?
See you next week

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 43 guests