Jump to content
Sign in to follow this  
Abilio_KID

JPEG quality after screen capture and resizing

Recommended Posts

Abilio_KID

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.

Share this post


Link to post
Share on other sites
Abilio_KID

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:

#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...

Share this post


Link to post
Share on other sites
UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Abilio_KID

Thanks UEZ, I would eventually slim it down to avoid having another (almost) repeated function, but you saved me some work. Thanks once more.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.