 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Sat Aug 30, 2008 11:57 am Post subject: Crazy Scripting : ScreenCaptureToPNG 25L |
|
|
| Code: | ; ScreenCaptureToPNG 25L Forum Topic : www.autohotkey.com/forum/viewtopic.php?t=35242
; Author: SKAN - Suresh Kumar A N Created : 30-Aug-2008 | Modified : 31-Aug-2008
; Credit: Adapted from www.autohotkey.com/forum/viewtopic.php?p=97591#97591 by XavierGr
~PrintScreen::
~!PrintScreen::
If % SaveClipboardImageAs( (BMPF:=A_Temp "\screen.bmp") )
If % ConvertGraphicsFile( BMPF, (OUTF:=A_Temp "\screen.png") )
Runwait, Rundll32.exe %A_Windir%\system32\shimgvw.dll`,ImageView_Fullscreen %OUTF%
Return
SaveClipboardImageAs( tImg="" ) {
If ! DllCall("IsClipboardFormatAvailable",UInt,2)
Return 0
$:=ClipboardAll
NumPut(0x4D42,$,2), D:=NumGet($,36), NumPut(66+D,$,4), NumPut(0,$,8), NumPut(66,$,12)
If ( (Z:=DllCall("_lcreat",Str,tImg,UInt,0)) = -1
|| DllCall("_lwrite",UInt,Z,UInt,&$+2,UInt,66+D) = -1 || DllCall("_lclose",UInt,Z) = -1 )
Return 0
Return 1
}
ConvertGraphicsFile( Src, Trg, Ov=1 ) {
Static shlwapi,ShConvertGraphics ; www.autohotkey.com/forum/viewtopic.php?p=190227#190227
If ( D="" )
D:=DllCall("LoadLibrary",Str,"shlwapi.dll"),CG:=DllCall("GetProcAddress",UInt,D,Int,488)
VarSetCapacity(uSrc,(sSz:=StrLen(Src)*2+1)), DllCall("MultiByteToWideChar",Int,0,Int,0
,Str,Src,Int,-1,Str,uSrc,Int,sSz ), VarSetCapacity(uTrg,(tSz:=StrLen(Trg)*2+1))
DllCall("MultiByteToWideChar",Int,0,Int,0,Str,Trg,Int,-1,Str,uTrg,Int,tSz)
Return ! DllCall(CG,Str,uSrc,Str,uTrg,UInt,Ov)
} |
Tested and works fine for me in XP-SP2 with 16bit and 32bit screen color quality.
Preview is shown with Windows Picture and Fax Viewer which is convenient and offers many options.
Edit:
Images not saved properly at 16bit color quality.. now fixed
Code has been compacted from 33 lines to 25 lines _________________ Suresh Kumar A N
Last edited by SKAN on Mon Sep 01, 2008 11:05 am; edited 2 times in total |
|
| Back to top |
|
 |
Delusion
Joined: 16 Jul 2008 Posts: 117
|
Posted: Sat Aug 30, 2008 3:14 pm Post subject: |
|
|
Very Nice
Is it possible making it so that it automatically saves the file somewhere though? _________________ Movie Launcher |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Sat Aug 30, 2008 11:47 pm Post subject: |
|
|
Thanks.
It already saves screen.bmp in Temp folder which you may alter per your requirement.
 _________________ Suresh Kumar A N |
|
| Back to top |
|
 |
..:: Free Radical ::..
Joined: 20 Sep 2006 Posts: 47
|
Posted: Sun Aug 31, 2008 4:11 am Post subject: Another way through DLL call and GDI+ |
|
|
Here is another way.
Credit to Sean for posting this (Screen Capture with transparent windows)
http://www.autohotkey.com/forum/viewtopic.php?t=18146&start=0&postdays=0&postorder=asc
Adapted here with some modifications. Needs GDI+ helper.
The Function: Include this in your main script
| Code: |
; Screen Capture
CaptureScreen(aRect = 0, bCursor = False, sFile = "")
{
If !aRect
{
SysGet, Mon, Monitor, 1
nL := MonLeft
nT := MonTop
nW := MonRight - MonLeft
nH := MonBottom - MonTop
}
Else If aRect = 1
WinGetPos, nL, nT, nW, nH, A
Else If aRect = 2
{
WinGet, hWnd, ID, A
VarSetCapacity(rt, 16, 0)
DllCall("GetClientRect" , "Uint", hWnd, "Uint", &rt)
DllCall("ClientToScreen", "Uint", hWnd, "Uint", &rt)
nL := NumGet(rt, 0, "int")
nT := NumGet(rt, 4, "int")
nW := NumGet(rt, 8)
nH := NumGet(rt,12)
}
Else If aRect = 3
{
MouseGetPos, x1, y1
Sleep, 5000
MouseGetPos, x2, y2
nL := x1
nT := y1
nW := x2 - x1
nH := y2 - y1
}
Else
{
StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
nL := rt1
nT := rt2
nW := rt3 - rt1
nH := rt4 - rt2
znW := rt5
znH := rt6
}
mDC := DllCall("CreateCompatibleDC", "Uint", 0)
hBM := CreateDIBSection(mDC, nW, nH)
oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
hDC := DllCall("GetDC", "Uint", 0)
DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
If bCursor
CaptureCursor(mDC, nL, nT)
DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
DllCall("DeleteDC", "Uint", mDC)
If znW && znH
hBM := Zoomer(hBM, nW, nH, znW, znH)
If sFile = 0
SetClipboardData(hBM)
Else Convert(hBM, sFile), DllCall("DeleteObject", "Uint", hBM)
}
CaptureCursor(hDC, nL, nT)
{
VarSetCapacity(mi, 20, 0)
mi := Chr(20)
DllCall("GetCursorInfo", "Uint", &mi)
bShow := NumGet(mi, 4)
hCursor := NumGet(mi, 8)
xCursor := NumGet(mi,12)
yCursor := NumGet(mi,16)
VarSetCapacity(ni, 20, 0)
DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni)
xHotspot := NumGet(ni, 4)
yHotspot := NumGet(ni, 8)
hBMMask := NumGet(ni,12)
hBMColor := NumGet(ni,16)
If bShow
DllCall("DrawIcon", "Uint", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "Uint", hCursor)
If hBMMask
DllCall("DeleteObject", "Uint", hBMMask)
If hBMColor
DllCall("DeleteObject", "Uint", hBMColor)
}
Zoomer(hBM, nW, nH, znW, znH)
{
mDC1 := DllCall("CreateCompatibleDC", "Uint", 0)
mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
zhBM := CreateDIBSection(mDC2, znW, znH)
oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint", hBM)
oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", zhBM)
DllCall("SetStretchBltMode", "Uint", mDC2, "int", 4)
DllCall("StretchBlt", "Uint", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "Uint", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1)
DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2)
DllCall("DeleteDC", "Uint", mDC1)
DllCall("DeleteDC", "Uint", mDC2)
DllCall("DeleteObject", "Uint", hBM)
Return zhBM
}
Convert(sFileFr = "", sFileTo = "")
{
If sFileTo =
sFileTo := A_ScriptDir . "\screen.bmp"
SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo
If Not hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
Return sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)
If !sFileFr
{
DllCall("OpenClipboard", "Uint", 0)
If DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2))
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
DllCall("CloseClipboard")
}
Else If sFileFr Is Integer
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
Else DllCall("gdiplus\GdipLoadImageFromFile", "Uint", Unicode4Ansi(wFileFr,sFileFr), "UintP", pImage)
DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
Loop, %nCount%
{
If !InStr(Ansi4Unicode(NumGet(ci, 76 * (A_Index - 1) + 44)), "." . sExtTo)
Continue
pCodec := &ci + 76 * (A_Index - 1)
Break
}
If pImage
pCodec ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", 0) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pImage, "UintP", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)
DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
DllCall("FreeLibrary", "Uint", hGdiPlus)
}
CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
NumPut(VarSetCapacity(bi, 40, 0), bi)
NumPut(nW, bi, 4)
NumPut(nH, bi, 8)
NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
NumPut(0, bi,16)
Return DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}
SaveHBITMAPToFile(hBitmap, sFile)
{
DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
hFile:= DllCall("CreateFile", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16, "Uint", 6, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
DllCall("CloseHandle", "Uint", hFile)
}
SetClipboardData(hBitmap)
{
DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
pDIB := DllCall("GlobalLock", "Uint", hDIB)
DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
DllCall("GlobalUnlock", "Uint", hDIB)
DllCall("DeleteObject", "Uint", hBitmap)
DllCall("OpenClipboard", "Uint", 0)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
DllCall("CloseClipboard")
}
Unicode4Ansi(ByRef wString, sString)
{
nSize := DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wString, nSize * 2)
DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize)
Return &wString
}
Ansi4Unicode(pString)
{
nSize := DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int", 0, "Uint", 0, "Uint", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
Return sString
}
|
Set your hotkeys to execute these labels
| Code: |
CAPTURE:
Name=%A_Now%
CaptureScreen(0,0,"Screen.PNG")
FileMove, Screen.PNG,E:\My Documents\My Pictures\Screenshots\%Name%.PNG
Return
CAPTURE2:
CoordMode, Mouse, Screen
CaptureScreen(3,0,"Screen.PNG")
Name=%A_Now%
FileMove, Screen.PNG,E:\My Documents\My Pictures\Screenshots\%Name%.PNG
CoordMode, Mouse, Relative
Return
|
The first Capture mode is full screen capture.
In the second Capture mode, the screenshot will be between two coordinates which define top-left and bottom -right. Trigger the hotkey with the mouse at the top left position of the area you want to capture and move the mouse within 5 seconds to the bottom right of the area you want to capture.
Simply replace .PNG with .JPG or .BMP in the labels if you want that format and the function will capture to that format (sent as the sFile value).
You can easily adapt this to capture windows instead by changing the aRect value or whether you want the mouse to be captured or not through the bCursor value.
The name of each screenshot is the time of capture
The jpeg capture quality can be changed.
Refer to the discussion thread for details (link posted above) |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Sun Aug 31, 2008 3:38 pm Post subject: |
|
|
Update:
Image was not saved properly at 16bit color quality.. now bug fixed
Also, Code has been optimised/compacted from 33 lines to 25 lines
 _________________ Suresh Kumar A N |
|
| Back to top |
|
 |
ArchCarrier
Joined: 03 Jun 2008 Posts: 20
|
Posted: Wed Sep 03, 2008 11:00 am Post subject: |
|
|
If you think that last one is still 24 lines too big and you have IrfanView installed, you might like the one I always use:
| Code: | | ^PrintScreen::Run, "%A_ProgramFiles%\IrfanView\i_view32.exe" /capture=1 /convert=c:\PATH_TO\screenshot_$U(`%Y-`%m-`%d_`%H`%M`%S).png |
Pressing ctrl+PrintScreen will save a PNG file of the active window. Use /capture=0 or /capture=2 for saving other parts of the screen (I believe 0=fullscreen, 2=inside active window, but I might be wrong). |
|
| Back to top |
|
 |
BoBo² Guest
|
Posted: Wed Sep 03, 2008 4:17 pm Post subject: |
|
|
I like it! - have you thought about it to implement a thumbnail option (even nicer/harder, using a ratio parameter like "shrink image to 33% of its original scale").
Currently I've to use [Quick Thumbnail], and would be more than happy to get a local AHK! option as well.  |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Wed Sep 03, 2008 7:50 pm Post subject: |
|
|
| BoBo² wrote: | I like it!  |
Thanks BoBo
| Quote: | | have you thought about it to implement a thumbnail option |
Honestly, no... but yes! It is a good idea, but I am not interested in using GDI+ since these kind of short kode are being added to my always- running-script
Let me see if I can produce something creative
Edit: Thanks for the link  _________________ Suresh Kumar A N |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Thu Sep 04, 2008 12:16 pm Post subject: |
|
|
BoBo,
Try this: http://www.autohotkey.net/~goyyah/CrazyScripts/ScreenCaptureToPNG/SCTP-Ext1.ahk
After a screen shot / when in preview mode ( Windows Picture and Fax Viewer ),
Keep pressing R to Reduce Screen.bmp to 75% of the current size,
and once done, press C to Create Thumb.jpg
Not an elegant method, but it was fun doing it.  _________________ Suresh Kumar A N |
|
| Back to top |
|
 |
BoBo² Guest
|
Posted: Thu Sep 04, 2008 1:29 pm Post subject: |
|
|
Thx a mill SKAN
[Brainfart]
FYI. My current project: create a 'snapshoot-bundle'.
Capture a snapshoot and its thumbnail in one go.
Eg to save the original snapshoot first (I could live without showing it in the viewer), and create its assigned thumbnail, using a (variable but) preset aspect ratio, afterwards from that saved image.
[/Brainfart] |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1424
|
Posted: Sat Sep 06, 2008 8:32 pm Post subject: |
|
|
I think if you take a look youll find that the gdi+ library is much more flexible and powerful. This took a few minutes to write as a very simple example:
| Code: | #SingleInstance, Force
SetBatchLines, -1
#Include, Gdip.ahk
Size := 0.8
FileType = png
Font = Arial
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
Hotkey, ^PrintScreen, SaveScreen, On
Return
;####################################################################################
SaveScreen:
pBitmap := Gdip_BitmapFromScreen()
Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
PBitmapResized := Gdip_CreateBitmap(Round(Width*Size), Round(Height*Size)), G := Gdip_GraphicsFromImage(pBitmapResized)
Gdip_DrawImage(G, pBitmap, 0, 0, Round(Width*Size), Round(Height*Size), 0, 0, Width, Height)
Gdip_TextToGraphics(G, A_Hour ":" A_Min ":" A_Sec " " A_DD "/" A_MM "/" A_YYYY, "x0 y0 r4 cff000000 s5p", Font, Round(Width*Size), Round(Height*Size))
Gdip_SaveBitmapToFile(PBitmapResized, A_Now "." FileType)
Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmapResized)
Gdip_DisposeImage(pBitmap)
Return
;####################################################################################
Exit:
Gdip_Shutdown(pToken)
ExitApp
Return |
The above code will take a screenshot with ctrl+printscreen and save the file as the chosen filetype in the current folder with the time and date written on the screenshot, and will resize it to the currently chosen fraction of the original size ( 0.8 ) |
|
| Back to top |
|
 |
BoBo² Guest
|
Posted: Sun Sep 07, 2008 12:09 am Post subject: |
|
|
Thx tic,
what are the changes to get the active window (ALT+PrintScreen) instead of the whole screen (which I've got after testing your script)? |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1424
|
Posted: Sun Sep 07, 2008 12:30 am Post subject: |
|
|
| BoBo² wrote: | Thx tic,
what are the changes to get the active window (ALT+PrintScreen) instead of the whole screen (which I've got after testing your script)? |
Heh, I'm still up
I know I havent documented it but check out the line:
| Code: | | pBitmap := Gdip_BitmapFromScreen() |
That gets a gdi+ bitmap of the screen. passing 0 to it will get a bitmap of all available screens. passing a number will get a bitmap of that specific screen, and passing x|y|w|h will get a bitmap of that specific area
So you could do:
| Code: | WinGetPos, X, Y, W, H, A
pBitmap := Gdip_BitmapFromScreen(X "|" Y "|" W "|" H) |
But sorry to jack your thread SKAN! If you want to ask any more BoBo² then ask on the gdi+  |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7159
|
Posted: Sun Sep 07, 2008 7:24 am Post subject: |
|
|
| tic wrote: | | But sorry to jack your thread SKAN! |
Not at all, it is much related to the topic.  _________________ Suresh Kumar A N |
|
| Back to top |
|
 |
BoBo² Guest
|
Posted: Sun Sep 07, 2008 10:16 am Post subject: |
|
|
Thanks, SKAN + tic
mission accomplished.
I'll drop a cross reference post at the gdi+ thread.
Thx for your effort.
 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|