Jump to content

Recommended Posts

Posted

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.

Posted

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

Posted

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

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...