Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Screen Capture and Save to file without opening MS Paint?


  • Please log in to reply
15 replies to this topic
Danz16
  • Guests
  • Last active:
  • Joined: --
I've been trying to build a script that will do a printscreen capture and save to file without the user being interrupted or noticing it happening. Is that possible?

Thanks!

Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
<!-- m -->http://www.autohotke... ... turescreen<!-- m -->
:)

Danz16
  • Guests
  • Last active:
  • Joined: --
Thanks for the reply. I was trying to find something a little more simpler (can't figure out how to use that). Is there any reason why something this simple doesn't work?
#space::
send keys {PrintScreen}
Fileappend %clipboard%, C:\test.bmp
return


engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
yes, that will not work. Fileappend appends text data. the clipboard contains an image, so nothing will be appended.

if his script is in the same folder as yours, try this code
#include ScreenCapture.ahk

return

#c::
CaptureScreen(0, false, "C:\test.bmp")
return

run it, then hit Windows + C to copy the desktop to that file.

There are many other options you can use if you want, but that is the basic function.

poo_noo
  • Members
  • 251 posts
  • Last active: Jan 28 2015 08:33 PM
  • Joined: 08 Dec 2006
This works for me (from <!-- m -->http://www.autohotke... ... turescreen<!-- m --> )

;############# RegionCapture Code is below ########################################################
/* CaptureScreen(aRect, bCursor, sFileTo)
1) If the optional parameter bCursor is True, captures the cursor too.
2) If the optional parameter sFileTo is 0, set the image to Clipboard.
   If it is omitted or "", saves to screen.bmp in the script folder,
   otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
3) If aRect is 0/1/2, captures the screen/active window/client area of active window.
4) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
   In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.
Build date is 20-12-2007
Example:
CaptureScreen(0)
CaptureScreen(1)
CaptureScreen(2)
CaptureScreen("100, 100, 200, 200")
CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed
*/

/* Convert(sFileFr, sFileTo)
Convert("C:\image.bmp", "C:\image.jpg")
Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/
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
	{
		StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
		nL := rt1
		nT := rt2
		nW := rt3 - rt1
		nH := rt4 - rt2
		znW := rt5
		znH := rt6
	}

	hDC := DllCall("GetDC", "Uint", 0)
	mDC := DllCall("CreateCompatibleDC", "Uint", hDC)
	hBM := DllCall("CreateCompatibleBitmap", "Uint", hDC, "int", nW, "int", nH)
	oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
	DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
	If	bCursor
		CaptureCursor(mDC, nL, nT)
	DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
	DllCall("DeleteDC", "Uint", mDC)
	If	znW && znH
		hBM := Zoomer(hDC, hBM, nW, nH, znW, znH)
	If	sFile = 0
		SetClipboardData(hBM)
	Else	Convert(hBM, sFile)
	DllCall("DeleteObject", "Uint", hBM)
	DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
}

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(hDC, hBM, nW, nH, znW, znH)
{
	mDC1 := DllCall("CreateCompatibleDC", "Uint", hDC)
	mDC2 := DllCall("CreateCompatibleDC", "Uint", hDC)
	zhBM := DllCall("CreateCompatibleBitmap", "Uint", hDC, "int", znW, "int", 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 := %imagesavename%
	SplitPath, sFileTo, , , sExtTo
	hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
	VarSetCapacity(si, 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)
	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	!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)

	If	pImage
		DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", 0), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)

	DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
	DllCall("FreeLibrary", "Uint", hGdiPlus)
}

SetClipboardData(hMem, nFormat = 2)
{
	DetectHiddenWindows, On
	Process, Exist
	WinGet, hAHK, ID, ahk_pid %ErrorLevel%
	DllCall("OpenClipboard", "Uint", hAHK)
	DllCall("EmptyClipboard")
	DllCall("SetClipboardData", "Uint", nFormat, "Uint", hMem)
	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
}


	#space::
	imagesavename=C:\test.bmp
	; call the screencapture function
	CaptureScreen(0,false,imagesavename)
Return
Edit 1 . Engunneer beat me....
Paul O

Jiashern
  • Guests
  • Last active:
  • Joined: --
I have used the screen capture script, it is simply fantastic.
However, I just wish that it can be improved by letting us save multiple file instead of rewriting file, is it possible?


For example, instead of rewriting test.bmp,
it can save as test01.bmp,test02.bmp, test03bmp..

Very sorry, I am very noob on Autohotkey.....

and many thanks :D

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Just add a counter to the hotkey that calls the function:

#space::
counter++
imagesavename=C:\test%counter%.bmp
; call the screencapture function
CaptureScreen(0,false,imagesavename)
Return

You probably want some zero padding to help keep captures in order:

#space::
counter++
count = 000%counter%
stringright, count, count, 4
imagesavename=C:\test%count%.bmp
; call the screencapture function
CaptureScreen(0,false,imagesavename)
Return

"Anything worth doing is worth doing slowly." - Mae West
Posted Image

jiashern1
  • Guests
  • Last active:
  • Joined: --
Thank you very much for helping me out in this!! It is working! and I have tried to modify it to assign different hotkey to different screen capture result,

but i failed to make it work...

Could point out what is wrong??


counter++
count = 000%counter%
stringright, count, count, 4
imagesavename=\%A_desktop%\test%count%.jpg

Printscreen::
	CaptureScreen(0,false,imagesavename)

^Printscreen::
   CaptureScreen(2,false,imagesavename)
   
+Printscreen::
  CaptureScreen("0,0,1680,1050",false,imagesavename)
return



Razlin
  • Members
  • 454 posts
  • Last active: Feb 05 2014 06:21 PM
  • Joined: 05 Nov 2007
I wrote one of these a long time ago.

http://www.autohotke...pic.php?t=31889

alt printscreen saves current window only
printscreen alone takes desktop.
files are saves as picture 1.jpg
picture 2.jpg
picture 3.jpg
and so on.

Must have irfanview installed.
Irfanview is free.

my 2 bits.
-=Raz=-

metacumbia
  • Members
  • 56 posts
  • Last active: Oct 16 2008 06:15 PM
  • Joined: 02 Aug 2008
the sean's code works perfectly

but, how can it save to desktop??

imagesavename=\%A_desktop%\test.bmp

doesnt work!

Razlin
  • Members
  • 454 posts
  • Last active: Feb 05 2014 06:21 PM
  • Joined: 05 Nov 2007
%a_desktop% = C:\Documents and Settings\...\Desktop

therfore

imagesavename=%A_desktop%\test.bmp

remove first \
-=Raz=-

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Jiashern, try this:

Printscreen::
gosub, imagename
CaptureScreen(0,false,imagesavename)
return

^Printscreen::
gosub, imagename
CaptureScreen(2,false,imagesavename)
return
   
+Printscreen::
gosub, imagename
CaptureScreen("0,0,1680,1050",false,imagesavename)
return

imagename:
setformat, float, 04.0 ; a better way to add zero padding
count+=1.
imagesavename=%A_desktop%\test%count%.jpg
return

"Anything worth doing is worth doing slowly." - Mae West
Posted Image

metacumbia
  • Members
  • 56 posts
  • Last active: Oct 16 2008 06:15 PM
  • Joined: 02 Aug 2008

%a_desktop% = C:\Documents and Settings\...\Desktop

therfore

imagesavename=%A_desktop%\test.bmp

remove first \


yes, it works
thx

Jiashern1
  • Guests
  • Last active:
  • Joined: --
Many thanks, it works perfect now. I also learn what gosub is, thanks again!

TalkieToaster
  • Members
  • 15 posts
  • Last active: Oct 24 2010 05:06 PM
  • Joined: 17 Mar 2008
Thanks all for this thread, saved my day, will be using that code almost every day :)

Very Greatfull thanks all!