Abilio_KID Posted February 21, 2014 Posted February 21, 2014 I've been reading a bit the forums and I simply couldn't find (yet) a solution to this small problem. I have a piece of code that takes a screenshot of the full desktop (multiple monitors included) and saves it to disk. So far nothing too hard, I even setup a variable to reduce the JPEG quality if I want to. However, I also used another variable to select screenshot percentage (for example, 50% of the original destop size). For that matter I need to do a few more bits of code to resize the image and then save it to disk. Now the problem, whatever JPEG quality I chose, the final image is not the quality I set up. It's also never 100% full quality. Here's an example code (just for testing) of what I mean: #include <ScreenCapture.au3> ;These 2 are not needed as they are already included once in <ScreenCapture.au3> ;#include <WinAPI.au3> ;#include <GDIPlus.au3> $file = @ScriptDir & "\xxx.jpg" ;File to save the screenshot (as an example) $qua = 100 ;JPEG quality $per = 75 ;Percentage of the original screenshot size ; Take a screenshot and save it to disc (I have 2 monitors) _ScreenCapture_SetJPGQuality($qua) ;This setting seems to be ignored unless I use "_ScreenCapture_Capture" $x1 = _WinAPI_GetSystemMetrics(76) $y1 = _WinAPI_GetSystemMetrics(77) $x2 = _WinAPI_GetSystemMetrics(78) $y2 = _WinAPI_GetSystemMetrics(79) If $per = 100 Then $pic = _ScreenCapture_Capture($file, $x1, $y1, $x2, $y2) ;JPEG is saved in whatever quality I chose in "$qua" Else $pic = _ScreenCapture_Capture("", $x1, $y1, $x2, $y2) _GDIPlus_Startup() $bmp = _GDIPlus_BitmapCreateFromHBITMAP($pic) $scaled = _GDIPlus_ImageResize($bmp, $x2*$per/100, $y2*$per/100, 7) ;Scaling works as intended _GDIPlus_ImageSaveToFile($scaled, $file) ;Even if "$qua = 100" it seems to save it at a lesser quality. WHY? _GDIPlus_BitmapDispose($bmp) _GDIPlus_BitmapDispose($scaled) _GDIPlus_Shutdown() EndIf _WinAPI_DeleteObject($pic) Sorry if this has already been answeared somewhere else but I don't seem to be able to find anything yet.
Abilio_KID Posted February 21, 2014 Author Posted February 21, 2014 Ok, seems I'm smart enough to look into the includes and figure this out myself. I copied some small code from one UDF function into another. Here's the result: expandcollapse popup#include <ScreenCapture.au3> ;These 2 are not needed as they are already included once in <ScreenCapture.au3> ;#include <WinAPI.au3> ;#include <GDIPlus.au3> $file = @ScriptDir & "\xxx.jpg" ;File to save the screenshot (as an example) Global $qua = 100 ;JPEG quality $per = 75 ;Percentage of the original screenshot size ; Take a screenshot and save it to disc (I have 2 monitors) _ScreenCapture_SetJPGQuality($qua) ;This setting was previously ignored unless I used "_ScreenCapture_Capture" $x1 = _WinAPI_GetSystemMetrics(76) $y1 = _WinAPI_GetSystemMetrics(77) $x2 = _WinAPI_GetSystemMetrics(78) $y2 = _WinAPI_GetSystemMetrics(79) If $per = 100 Then $pic = _ScreenCapture_Capture($file, $x1, $y1, $x2, $y2) ;JPEG is saved in whatever quality I chose in "$qua" Else $pic = _ScreenCapture_Capture("", $x1, $y1, $x2, $y2) _GDIPlus_Startup() $bmp = _GDIPlus_BitmapCreateFromHBITMAP($pic) $scaled = _GDIPlus_ImageResize($bmp, $x2*$per/100, $y2*$per/100, 7) ;Scaling works as intended My_GDIPlus_ImageSaveToFile($scaled, $file) ;Used the altered function instead. Now it works. _GDIPlus_BitmapDispose($bmp) _GDIPlus_BitmapDispose($scaled) _GDIPlus_Shutdown() EndIf _WinAPI_DeleteObject($pic) Exit ; Changed from original "_GDIPlus_ImageSaveToFile" Func My_GDIPlus_ImageSaveToFile($hImage, $sFileName) Local $sExt = __GDIPlus_ExtractFileExt($sFileName) Local $sCLSID = _GDIPlus_EncodersGetCLSID($sExt) If $sCLSID = "" Then Return SetError(-1, 0, False) ; Added from here... Local $tData, $tParams $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $qua) ;Using here my variable instead _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData)) Local $pParams = 0 If IsDllStruct($tParams) Then $pParams = $tParams ; ...to here. Local $bRet = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams) ;Changed from "0" to "$pParams" Return SetError(@error, @extended, $bRet) EndFunc Basically I added to the function the option of chosing the JPEG quality. Shouldn't this be already in the UDF? Unless I'm missing something here...
UEZ Posted February 21, 2014 Posted February 21, 2014 Try this: $pic = _ScreenCapture_Capture("", $x1, $y1, $x2, $y2) _GDIPlus_Startup() $bmp = _GDIPlus_BitmapCreateFromHBITMAP($pic) $scaled = _GDIPlus_ImageResize($bmp, $x2*$per/100, $y2*$per/100, 7) $iJPGQual = 50 $sCLSID = _GDIPlus_EncodersGetCLSID("JPG") $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $iJPGQual) $pData = DllStructGetPtr($tData) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) $pParams = DllStructGetPtr($tParams) _GDIPlus_ImageSaveToFileEx($scaled, $file, $sCLSID, $pParams) _GDIPlus_BitmapDispose($bmp) _GDIPlus_BitmapDispose($scaled) _GDIPlus_Shutdown() Br, UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Abilio_KID Posted February 21, 2014 Author Posted February 21, 2014 Thanks UEZ, I would eventually slim it down to avoid having another (almost) repeated function, but you saved me some work. Thanks once more.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now