Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Capture Screenshot to JPG


  • Please log in to reply
50 replies to this topic
EveOnline001
  • Members
  • 27 posts
  • Last active: Nov 02 2009 11:49 PM
  • Joined: 23 Mar 2009
I couldn't find a script, so I put this together. It runs in System Tray.
Press Win + PrtScr to capture screenshot as a JPG.


What happens when you press the hot-key?

1. Folder PrintScreen is created (in the same folder as location of
the ahk script).
2. In this folder, screenshot is saved as img_####.jpg.


Download ready-to-use exe: This script has been compiled.


Or, here is the code:

/*
 *	1. Keep script running.
 *	2. Limit to one running copy.
 *	3. Run script without pauses.
 */
#Persistent
#SingleInstance ignore
SetBatchLines, 10ms



/*
 *-------------------------------------------------------------------------------------
 * 		Use hotkey: 	Win + PrtScr
 *-------------------------------------------------------------------------------------
 */
#PrintScreen::

	/*
	 * Create folder.
	 */
	IfNotExist, PrintScreen
	{
		FileCreateDir, PrintScreen
	}


	/*
	 * Reset counter.
	 */
	countLoop := 1


	/*
	 * Repeat until we have unused name for file.
	 */
	loopFileName:

		/*
		 * Reset string.
		 */
		countLoopString := countLoop
		
		/*
		 * Add leading zeroes to string.
		 */
		loopStringAddZeroes:
			if (StrLen(countLoopString) < 4)
			{
				countLoopString := "0" countLoopString
				Goto, loopStringAddZeroes
			}
		
		/*
		 * Form the name of new file.
		 */
		newFileName := "PrintScreen\img_" countLoopString ".jpg"
		
		/*
		 * Check if file name is taken.
		 */
		IfExist, % newFileName
		{
			countLoop++
			Goto, loopFileName
		}

		
	/*
	 * Capture screenshot.
	 */
	CaptureScreen(0, False, newFileName, 100)
return



/*
 * If the script goes this far...
 */
Exit




/* 
 *-------------------------------------------------------------------------------------
 *	Screen Capture with Transparent Windows and Mouse Cursor:
 *			http://www.autohotkey.com/forum/topic18146.html
 *-------------------------------------------------------------------------------------
	CaptureScreen(aRect, bCursor, sFileTo, nQuality)
		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) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
		4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
		5) 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.

	Example:
		CaptureScreen(0)
		CaptureScreen(1)
		CaptureScreen(2)
		CaptureScreen(3)
		CaptureScreen("100, 100, 200, 200")
		CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed

	Convert:
		Convert(sFileFr, sFileTo, nQuality)
		Convert("C:\image.bmp", "C:\image.jpg")
		Convert("C:\image.bmp", "C:\image.jpg", 95)
		Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/

;CaptureScreen()
;Return

CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
	If	!aRect
	{
		SysGet, nL, 76
		SysGet, nT, 77
		SysGet, nW, 78
		SysGet, nH, 79
	}
	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
	{
		VarSetCapacity(mi, 40, 0)
		DllCall("GetCursorPos", "int64P", pt)
		DllCall("GetMonitorInfo", "Uint", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2), "Uint", NumPut(40,mi)-4)
		nL := NumGet(mi, 4, "int")
		nT := NumGet(mi, 8, "int")
		nW := NumGet(mi,12, "int") - nL
		nH := NumGet(mi,16, "int") - nT
	}
	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, nQuality), 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 = "", nQuality = "")
{
	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,0)
	DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
	Loop, %	nCount
		If	InStr(Ansi4Unicode(NumGet(ci,76*(A_Index-1)+44)), "." . sExtTo)
		{
			pCodec := &ci+76*(A_Index-1)
			Break
		}
	If	InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
	{
	DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage, "Uint", pCodec, "UintP", nSize)
	VarSetCapacity(pi,nSize,0)
	DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint", nSize, "Uint", &pi)
	Loop, %	NumGet(pi)
		If	NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
		{
			pParam := &pi+28*(A_Index-1)
			NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
			Break
		}
	}

	If	pImage
		pCodec	? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", pParam) : 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
}




/*
 *====================================================================================
 *									END OF FILE
 *====================================================================================
 */


Keywords for Google:

print screen, screen shot, screenshot, save screen shot as jpeg, save
screenshot as jpg, save printscreen as jpg, capture screenshot as jpg,
capture printscreen as jpeg

doyle
  • Members
  • 335 posts
  • Last active: Mar 02 2012 04:47 PM
  • Joined: 14 Nov 2007
More Keywords:

Make my screen a jpeg

JPEG my computer screen

screen capture squeezed out as a jpeg

Delusion
  • Members
  • 272 posts
  • Last active: Jul 13 2014 09:04 PM
  • Joined: 16 Jul 2008
this is great!
many thanks :)
QuickSubs | Popcorn Movie Catalog
All my scripts are just in AutoHotkey v1.0.48.05

RappyBMX
  • Guests
  • Last active:
  • Joined: --
sweet here's my version :D

http://remus.313desi...reenShooter.exe

when you open it it will create a folder and if you press printscreen it will capture the entire desktop an save it in that folder, press alt+printscreen it will capture the active window and save it in that folder...

if you open it and don't take a screenshoot then close it, it will delete that folder... if you double click the trayicon it will open the actual folder where it saves the screen's.

rao
  • Guests
  • Last active:
  • Joined: --
Hello this is working fine,

I also want to save the ALT+PrtScr to jpeg file, please let me know the modifications.

regards
rao

rappybmx
  • Guests
  • Last active:
  • Joined: --
!PrintScreen::
   IfNotExist, PrintScreen
   {
      FileCreateDir, PrintScreen
   }
   countLoop2 := 1
   loopFileName2:
   countLoopString2 := countLoop2
      loopStringAddZeroes2:
         if (StrLen(countLoopString2) < 4)
         {
            countLoopString2 := "0" countLoopString2
            Goto, loopStringAddZeroes2
         }
   newFileName2 := "PrintScreen\img_" countLoopString ".jpg"
   IfExist, % newFileName2
   {
      countLoop2++
      Goto, loopFileName2
   }
   CaptureScreen(1, True, newFileName2, 100)
return

ScrollLock::
Run, %newFolderName%
return

best,
http://remus.313designstudio.com/

opt.
  • Members
  • 2 posts
  • Last active: Dec 05 2009 04:14 AM
  • Joined: 05 Dec 2009
thanks, really handy :D

poetbox
  • Members
  • 113 posts
  • Last active: Sep 11 2013 08:05 AM
  • Joined: 07 Jan 2007

I couldn't find a script, so I put this together. It runs in System Tray.
Press Win + PrtScr to capture screenshot as a JPG.


What happens when you press the hot-key?

1. Folder PrintScreen is created (in the same folder as location of
the ahk script).
2. In this folder, screenshot is saved as img_####.jpg.

No,It's of no use.
Please check the code.Thank you!

  • Guests
  • Last active:
  • Joined: --

No,It's of no use.
Please check the code.Thank you!


How so?

Works for me.

RappyBMX
  • Guests
  • Last active:
  • Joined: --
PrintScreen::
{
if (screenenabled = true)
{
;save print screen
}
else
{
;do normal print screen
}
}


how can i do that ?

if screenenabled = false i want the print screen to be normal... just do a printscreen and put it in my clipboard :)

if i do
Send {PrintScreen}
it will create and infinite loop :)


anyone ?

rapid ahk
  • Guests
  • Last active:
  • Joined: --
hi,

i receive an error at line 133

Line Text: DllCall("GetMonitorInfo", "Unit", DllCall("MonitorFromPoint", "int64", pt, Error:Missing")"

How is it so?

  • Guests
  • Last active:
  • Joined: --
Are you sure you copied the programcode correctly?

The line in the programcode reads:

DllCall("GetMonitorInfo", "Uint", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2)


  • Guests
  • Last active:
  • Joined: --

hi,

i receive an error at line 133

Line Text: DllCall("GetMonitorInfo", "Unit", DllCall("MonitorFromPoint", "int64", pt, Error:Missing")"

How is it so?


This thread uses "Screen capture with transparent windows and mouse cursor", which requires 'GdiPlus.dll'. Most people have this already installed. If it is missing, search for 'GdiPlus.dll' download on Google.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Maybe it would be a bit nicer to replace the entire script with something like:

pToken := Gdip_Startup()
Gdip_SaveBitmapToFile(pBitmap := Gdip_BitmapFromScreen(), A_Now ".jpg")
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)

:wink:

Relayer
  • Members
  • 122 posts
  • Last active: Jun 22 2015 09:21 PM
  • Joined: 24 Nov 2008
tic,

I am using your Gdip functions and it worked great with v1.30 but v1.42 gives me inconsistent results in saving screen captures. FYI. It seems to sometimes pick a different set of coordinates to capture than the ones I give it.

Relayer