Jump to content
RyukShini

Image quality is bad compared to paint

Recommended Posts

RyukShini
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=car.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GDIPlus.au3>
#include <File.au3>
#include <Array.au3>
#include <ColorConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>

; Declare array
Dim $Images[1]
; Gets all JPG files in the current directory (@ScriptDir).
Local $search = FileFindFirstFile("*.jpg")

; Check if the search was successful
If $search = -1 Then
    MsgBox(0, "Error", "No JPG files could be found.")
    Exit
EndIf

; Resize array
While 1
    If IsArray($Images) Then
        Local $Bound = UBound($Images)
        ReDim $Images[$Bound+1]
    EndIf
    $Images[$Bound] = FileFindNextFile($search)
    If @error Then ExitLoop
WEnd

; Close the search handle
FileClose($search)

; Create directory "resized" if not there yet
$nymappe = InputBox("Mappe / Bil Navn", "Mappe / Bil Navn")
If NOT FileExists(@ScriptDir & "\" & $nymappe & "\") Then
    DirCreate(@ScriptDir & "\" & $nymappe & "\")
EndIf

; Loop for JPGs - gets dimension of JPG and calls resize function to resize to 50% width and 50% height
For $i = 1 to Ubound($Images)-1
    If $Images[$i] <> "" AND FileExists(@ScriptDir & "\" & $Images[$i]) Then
        Local $ImagePath = @ScriptDir & "\" & $Images[$i]
        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_ImageLoadFromFile($ImagePath)
        Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage)
        Local $ImageHeight = _GDIPlus_ImageGetHeight($hImage)
        _GDIPlus_ImageDispose($hImage)
        _GDIPlus_Shutdown()
        ;MsgBox(0,"DEBUG", $ImageWidth & " x " & $ImageHeight)
        Local $NewImageWidth = ($ImageWidth / 100) * 15
        Local $NewImageHeight = ($ImageHeight / 100) * 15

        ;MsgBox(0,"DEBUG: " & $i,$Images[$i])
        _ImageResize(@ScriptDir & "\" & $Images[$i], @ScriptDir & "\" & $nymappe & "\" & $Images[$i], $NewImageWidth, $NewImageHeight)
    EndIf
Next

; Resize function
Func _ImageResize($sInImage, $sOutImage, $iW, $iH)
    Local $hWnd, $hDC, $hBMP, $hImage1, $hImage2, $hGraphic, $CLSID, $i = 0

    ;OutFile path, to use later on.
    Local $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "\", 0, -1))

    ;OutFile name, to use later on.
    Local $sOF = StringMid($sOutImage, StringInStr($sOutImage, "\", 0, -1) + 1)

    ;OutFile extension , to use for the encoder later on.
    Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1))

    ; Win api to create blank bitmap at the width and height to put your resized image on.
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDC = _WinAPI_GetDC($hWnd)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDC)

    ;Start GDIPlus
    _GDIPlus_Startup()

    ;Get the handle of blank bitmap you created above as an image
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)

    ;Load the image you want to resize.
    $hImage2 = _GDIPlus_ImageLoadFromFile($sInImage)

    ;Get the graphic context of the blank bitmap
    $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1)

    ;Draw the loaded image onto the blank bitmap at the size you want
    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iW, $iH)

    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)

    ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image.
    Do
        $i += 1
    Until (Not FileExists($sOP & $i & "_" & $sOF))

    ;Prefix the number to the begining of the output filename
    $sOutImage = $sOP & $i & "_" & $sOF

    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID)

    ;Clean up and shutdown GDIPlus.
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _WinAPI_DeleteObject($hBMP)
    _GDIPlus_Shutdown()


EndFunc

Quality gets quite bad compared to using Paint / Photoshop when resizing with GDIPlus
Any idea how to make the quality better?
Thanks in advance

Share this post


Link to post
Share on other sites
UEZ

Try the built-in functions

_GDIPlus_ImageResize
_GDIPlus_ImageScale

Further it makes no sense to  call _GDIPlus_Startup() / _GDIPlus_Shutdown() in a loop. Just call _GDIPlus_Startup() once when you start the script and _GDIPlus_Shutdown() when you exit.

Edited by 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
RyukShini
22 minutes ago, UEZ said:

Try the built-in functions

_GDIPlus_ImageResize
_GDIPlus_ImageScale

Further it makes no sense to  call _GDIPlus_Startup() / _GDIPlus_Shutdown() in a loop. Just call _GDIPlus_Startup() once when you start the script and _GDIPlus_Shutdown() when you exit.

Thank you I will look in to that.
Could you give me a small example?:sweating:

Share this post


Link to post
Share on other sites
UEZ
Just now, RyukShini said:

Could you give me a small example?:sweating:

What about the examples in the help file?


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
RyukShini
20 minutes ago, UEZ said:

What about the examples in the help file?

Oh sorry, of course!
 

Share this post


Link to post
Share on other sites
Synapsee
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=car.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GDIPlus.au3>
#include <File.au3>
#include <Array.au3>
#include <ColorConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>

; Declare array
Dim $Images[1]
; Gets all JPG files in the current directory (@ScriptDir).
Local $search = FileFindFirstFile("*.jpg")

; Check if the search was successful
If $search = -1 Then
    MsgBox(0, "Error", "No JPG files could be found.")
    Exit
EndIf

;if no exit then startup gdi
_GDIPlus_Startup()

; Resize array
While 1
    If IsArray($Images) Then
        Local $Bound = UBound($Images)
        ReDim $Images[$Bound+1]
    EndIf
    $Images[$Bound] = FileFindNextFile($search)
    If @error Then ExitLoop
WEnd

; Close the search handle
FileClose($search)

; Create directory "resized" if not there yet
$nymappe = InputBox("Mappe / Bil Navn", "Mappe / Bil Navn")
If NOT FileExists(@ScriptDir & "\" & $nymappe & "\") Then
    DirCreate(@ScriptDir & "\" & $nymappe & "\")
EndIf

; Loop for JPGs - gets dimension of JPG and calls resize function to resize to 50% width and 50% height
For $i = 1 to Ubound($Images)-1
    If $Images[$i] <> "" AND FileExists(@ScriptDir & "\" & $Images[$i]) Then
        Local $ImagePath = @ScriptDir & "\" & $Images[$i]
        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_ImageLoadFromFile($ImagePath)
        Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage)
        Local $ImageHeight = _GDIPlus_ImageGetHeight($hImage)
        _GDIPlus_ImageDispose($hImage)
        _GDIPlus_Shutdown()
        ;MsgBox(0,"DEBUG", $ImageWidth & " x " & $ImageHeight)
        Local $NewImageWidth = ($ImageWidth / 100) * 15
        Local $NewImageHeight = ($ImageHeight / 100) * 15

        ;MsgBox(0,"DEBUG: " & $i,$Images[$i])
        _ImageResize(@ScriptDir & "\" & $Images[$i], @ScriptDir & "\" & $nymappe & "\" & $Images[$i], $NewImageWidth, $NewImageHeight)
    EndIf
Next

; Resize function
Func _ImageResize($sInImage, $sOutImage, $iW, $iH)

    ;OutFile path, to use later on.
    Local $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "\", 0, -1))

    ;OutFile name, to use later on.
    Local $sOF = StringMid($sOutImage, StringInStr($sOutImage, "\", 0, -1) + 1)

    ;OutFile extension , to use for the encoder later on.
    Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1))

    ;Load the image you want to resize.
    $hImage = _GDIPlus_ImageLoadFromFile ($sInImage)

    ;Resize
    $hBitmap_Scaled = _GDIPlus_ImageResize($hImage, $iW, $iH)

    ;U can test this too
    ;$hBitmap_Scaled = _GDIPlus_ImageScale($hImage, 0.15, 0.15)

    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)

    ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image.
    Do
        $i += 1
    Until (Not FileExists($sOP & $i & "_" & $sOF))

    ;Prefix the number to the begining of the output filename
    $sOutImage = $sOP & $i & "_" & $sOF

    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage, $CLSID)

    ;Clean up and shutdown GDIPlus.
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap_Scaled)

EndFunc

_GDIPlus_Shutdown()

 

im not sure if this improve quality.

Share this post


Link to post
Share on other sites
RyukShini
58 minutes ago, Synapsee said:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=car.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GDIPlus.au3>
#include <File.au3>
#include <Array.au3>
#include <ColorConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>

; Declare array
Dim $Images[1]
; Gets all JPG files in the current directory (@ScriptDir).
Local $search = FileFindFirstFile("*.jpg")

; Check if the search was successful
If $search = -1 Then
    MsgBox(0, "Error", "No JPG files could be found.")
    Exit
EndIf

;if no exit then startup gdi
_GDIPlus_Startup()

; Resize array
While 1
    If IsArray($Images) Then
        Local $Bound = UBound($Images)
        ReDim $Images[$Bound+1]
    EndIf
    $Images[$Bound] = FileFindNextFile($search)
    If @error Then ExitLoop
WEnd

; Close the search handle
FileClose($search)

; Create directory "resized" if not there yet
$nymappe = InputBox("Mappe / Bil Navn", "Mappe / Bil Navn")
If NOT FileExists(@ScriptDir & "\" & $nymappe & "\") Then
    DirCreate(@ScriptDir & "\" & $nymappe & "\")
EndIf

; Loop for JPGs - gets dimension of JPG and calls resize function to resize to 50% width and 50% height
For $i = 1 to Ubound($Images)-1
    If $Images[$i] <> "" AND FileExists(@ScriptDir & "\" & $Images[$i]) Then
        Local $ImagePath = @ScriptDir & "\" & $Images[$i]
        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_ImageLoadFromFile($ImagePath)
        Local $ImageWidth = _GDIPlus_ImageGetWidth($hImage)
        Local $ImageHeight = _GDIPlus_ImageGetHeight($hImage)
        _GDIPlus_ImageDispose($hImage)
        _GDIPlus_Shutdown()
        ;MsgBox(0,"DEBUG", $ImageWidth & " x " & $ImageHeight)
        Local $NewImageWidth = ($ImageWidth / 100) * 15
        Local $NewImageHeight = ($ImageHeight / 100) * 15

        ;MsgBox(0,"DEBUG: " & $i,$Images[$i])
        _ImageResize(@ScriptDir & "\" & $Images[$i], @ScriptDir & "\" & $nymappe & "\" & $Images[$i], $NewImageWidth, $NewImageHeight)
    EndIf
Next

; Resize function
Func _ImageResize($sInImage, $sOutImage, $iW, $iH)

    ;OutFile path, to use later on.
    Local $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "\", 0, -1))

    ;OutFile name, to use later on.
    Local $sOF = StringMid($sOutImage, StringInStr($sOutImage, "\", 0, -1) + 1)

    ;OutFile extension , to use for the encoder later on.
    Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1))

    ;Load the image you want to resize.
    $hImage = _GDIPlus_ImageLoadFromFile ($sInImage)

    ;Resize
    $hBitmap_Scaled = _GDIPlus_ImageResize($hImage, $iW, $iH)

    ;U can test this too
    ;$hBitmap_Scaled = _GDIPlus_ImageScale($hImage, 0.15, 0.15)

    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)

    ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image.
    Do
        $i += 1
    Until (Not FileExists($sOP & $i & "_" & $sOF))

    ;Prefix the number to the begining of the output filename
    $sOutImage = $sOP & $i & "_" & $sOF

    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage, $CLSID)

    ;Clean up and shutdown GDIPlus.
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap_Scaled)

EndFunc

_GDIPlus_Shutdown()

 

im not sure if this improve quality.

It did not, thank you a lot for trying, but it didn't make any changes really :/
Both of these:
 

;Resize
    $hBitmap_Scaled = _GDIPlus_ImageResize($hImage, $iW, $iH)

    ;U can test this too
    ;$hBitmap_Scaled = _GDIPlus_ImageScale($hImage, 0.15, 0.15)

 

Edited by RyukShini

Share this post


Link to post
Share on other sites
Synapsee

maybe can u post 2 img. the original one and the paint result u target. like this we can see the quality problem and wait a "GDI expert" solution.

I prefer a full AutoIt Version but maybe u can look on a tiers party software (with command line) for improve quality.

Edited by Synapsee

Share this post


Link to post
Share on other sites
Synapsee

wow ! i have a solution, we need set the quality jpeg encoder setting, by default seems not be quality=100.

 

...
    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)






    ; code found here :
    ; https://www.autoitscript.com/autoit3/docs/libfunctions/_GDIPlus_ImageSaveToStream.htm
    
        Local $sImgCLSID = _GDIPlus_EncodersGetCLSID("jpg") ;create CLSID for a JPG image file type
        Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID) ;convert CLSID GUID to binary form and returns $tagGUID structure
        Local $tParams = _GDIPlus_ParamInit(1) ;initialize an encoder parameter list and return $tagGDIPENCODERPARAMS structure
        Local $tData = DllStructCreate("int Quality") ;create struct to set JPG quality setting
        DllStructSetData($tData, "Quality", 100) ;quality 0-100 (0: lowest, 100: highest)
        Local $pData = DllStructGetPtr($tData) ;get pointer from quality struct
        _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) ;add a value to an encoder parameter list




    ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image.
    Do
        $i += 1
    Until (Not FileExists($sOP & $i & "_" & $sOF))

    ;Prefix the number to the begining of the output filename
    $sOutImage = $sOP & $i & "_" & $sOF




    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage, $CLSID)
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage & "2.jpg", $CLSID, $tParams); <=========== create a 100% quality output
...

 

Share this post


Link to post
Share on other sites
RyukShini
1 hour ago, Synapsee said:

wow ! i have a solution, we need set the quality jpeg encoder setting, by default seems not be quality=100.

 

...
    ;Get the encoder of to save the resized image in the format you want.
    $CLSID = _GDIPlus_EncodersGetCLSID($Ext)






    ; code found here :
    ; https://www.autoitscript.com/autoit3/docs/libfunctions/_GDIPlus_ImageSaveToStream.htm
    
        Local $sImgCLSID = _GDIPlus_EncodersGetCLSID("jpg") ;create CLSID for a JPG image file type
        Local $tGUID = _WinAPI_GUIDFromString($sImgCLSID) ;convert CLSID GUID to binary form and returns $tagGUID structure
        Local $tParams = _GDIPlus_ParamInit(1) ;initialize an encoder parameter list and return $tagGDIPENCODERPARAMS structure
        Local $tData = DllStructCreate("int Quality") ;create struct to set JPG quality setting
        DllStructSetData($tData, "Quality", 100) ;quality 0-100 (0: lowest, 100: highest)
        Local $pData = DllStructGetPtr($tData) ;get pointer from quality struct
        _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData) ;add a value to an encoder parameter list




    ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image.
    Do
        $i += 1
    Until (Not FileExists($sOP & $i & "_" & $sOF))

    ;Prefix the number to the begining of the output filename
    $sOutImage = $sOP & $i & "_" & $sOF




    ;Save the new resized image.
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage, $CLSID)
    _GDIPlus_ImageSaveToFileEx($hBitmap_Scaled, $sOutImage & "2.jpg", $CLSID, $tParams); <=========== create a 100% quality output
...

 

Amazing!
Will definitely try this when I get back to work.

Thanks a lot ;)

Share this post


Link to post
Share on other sites
RyukShini

@Synapsee

 

It still has a bit of quality loss but it made it better, thank you for trying but Its still not as good as paint?
 

Share this post


Link to post
Share on other sites
Synapsee

can u post the file source jpg for sample ?

Share this post


Link to post
Share on other sites
RyukShini
2 hours ago, Synapsee said:

can u post the file source jpg for sample ?

I can give you a * 15 with paint and * 15 GDI plus!
Would you like that?

Still not good enough quality!
let me know and i'll sent you 2 pics.

Edited by RyukShini

Share this post


Link to post
Share on other sites
UEZ

Why not saving in PNG format?


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
RyukShini
3 minutes ago, UEZ said:

Why not saving in PNG format?

Do you expect the quality to be better?
It still doesn't change the fact that Paint makes the quality better than GDIPlus for .jpg images.

But thank you for the suggestion!

Share this post


Link to post
Share on other sites
InnI
On ‎08‎.‎07‎.‎2016 at 3:36 PM, RyukShini said:

Paint makes the quality better than GDIPlus for .jpg images

Is still actual?

#include <ScreenCapture.au3>

$hBMP = _ScreenCapture_Capture()

; GDI+ resizign
_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
$hScale = _GDIPlus_ImageScale($hImage, 0.5, 0.5)
_GDIPlus_ImageSaveToFile($hScale, "GDIP.jpg")

; gdi32 resizing
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)
$iW2 = $iW / 2
$iH2 = $iH / 2
$hDC = _WinAPI_GetDC(0)
$hDC1 = _WinAPI_CreateCompatibleDC($hDC)
_WinAPI_SelectObject($hDC1, $hBMP)
$hDC2 = _WinAPI_CreateCompatibleDC($hDC)
$hBMP2 = _WinAPI_CreateCompatibleBitmap($hDC, $iW2, $iH2)
_WinAPI_SelectObject($hDC2, $hBMP2)

_WinAPI_SetStretchBltMode($hDC2, 3) ; looks like Paint resizing
;~ _WinAPI_SetStretchBltMode($hDC2, 4) ; looks better than Paint

_WinAPI_StretchBlt($hDC2, 0, 0, $iW2, $iH2, $hDC1, 0, 0, $iW, $iH, 0x00CC0020) ; $SRCCOPY
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP2)
_GDIPlus_ImageSaveToFile($hBitmap, "Paint.jpg")

; cleaning
_WinAPI_DeleteObject($hBMP)
_WinAPI_DeleteObject($hBMP2)
_WinAPI_ReleaseDC(0, $hDC)
_WinAPI_DeleteDC($hDC1)
_WinAPI_DeleteDC($hDC2)
_GDIPlus_ImageDispose($hScale)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_Shutdown()

 

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

  • Similar Content

    • Atoxis
      By Atoxis
      Howdy, I've gone through a lot of au3 forums, and I once had a working Imagesearch script that I got from here.  However, and i'm just totally not sure how but my imagesearch scripts aren't working anymore.
      I'm not new to au3 but i'm not the most experienced with it's syntax/commands.

      Anyways, I've looked over the big threads involving imagesearch.

      Does anyone have a working Imagesearch x64 for win10 that is currently working as of the date with the post.

      Dll's and what not is fine, just when I tell the script to run, I want to be able to find the image on the screen!
      Can't find a working copy so if anyone has one please send it my way lol.

      I've taken all the imagesearch downloads and what not and have played with them but I can't get any of them working on my end, despite others saying they're working.
      Thanks.
    • Sven-Seyfert
      By Sven-Seyfert
      Hi Community,

      I'm looking for a way to do a Video Overlay GUI or something like that. The idea is to create a GUI which plays a video loop (with transparency/alpha channel) in front of an other GUI. Before you asking why - because I don't believe that GDIPlus can do it out of the box. My skillset for that kind of graphical things isn't good enough to do that, but here are some specialist like @UEZ maybe who can help.

      Example alpha channel video (visualized as animated *.gif):

      I tried to do the light rays effect directly with GDIPlus, but honestly that's a bit too difficult for me. I would be very glad and grateful if there are some suggestions, ideas or recommendations.

      Code for the Video play:
       
      Example video "End.mpeg":
       
      The next challenge is that the overlay GUI should be not clickable. If I hover over the overlay area, I want to have the possibility to control the GUI or what ever, in the background. But if there is any chance to make it with GDIPlus as a Video Overlay for light rays, I would prefer that approach instead of my crazy work-around idea.

      Thanks for any suggestion - I'm grateful!
      Sven
    • Xandy
      By Xandy
      MapIt is a tile world editor.  MapIt was built around the concept of reversing Dragon Warrior map images.  MapIt can take image input and produce a tile and world array.
      MapIt features Unity style dragable labels that adjust property values.

      MapParser is a C++ project that scans images for unique tiles.  MapParser is very fast.  Due to hard drive failure, many bugs were restored b/c I had to rewind many years.  Frustrated with the design, I wrote a new version from the ground up.  This New Version:  AutoIt Front-end, command line controls, and shared with the world; so that I can't lose it again.
      You can toggle the C++ MapParser off to see the difference in speeds between the MapParser CPP verse AutoIt function.  Function is named Scan_Tiles() in AutoIt.  You can also chose to download without MapParser.exe.
      At the moment Scanning a image resets the arrays, but you can add tiles after scanning.
      Images can be added as tiles without scan image at all.  Then configure settings to give your world parameters and manually fill the world data with tile indexes.
      Using the settings you can change tile size after a scan.  Example: you wanted to replace a map with different sized tiles.
      Changing and replacing tile / world data is easy.  B/c tile world editor.

      Hotkeys, I use CTRL+R in image above to signal replace tile action and I use "G" to Get the tile under mouse.
      Hotkeys are not saved to disk and thus are set to default between sessions.
      I might draw the world to pre-rendered surfaces and use them as multi-layer someday.  I do that in my AutoIt, DragonWarrior Remake but I could spend forever unsure what features are important for this.  The DW_Remake has a method of replacing a tile with a tile on two layers.  So you could replace a tree on the first layer with a grass, and a tree in the second layer.  This is all getting very confusing.
      I attempted to write the good code.  If something could be better, please advise.
      Fifth release.  Enjoy.
      For download, videos, and example of created world file data; please visit the MapIt webpage: http://songersoft.com/programming/mapit/mapit_about.phtml
      Special thanks: @AdmiralAlkex, @Melba23, @MrCreatoR
      Main AutoIt source file: Will not run without other Includes and SDL DLLs.
      Last Update: 5/26/2018 3:45 PM EST
      REMOVED CODE BLOCK:  I was informed the this page loaded very slowly, one solution so far has been to remove the 2k lines in the code block.
      When I recieve more feedback from the User I may reduce image size or remove images.
      Next Version Added: $eSETTING_TILE_LAST_PATH I have the weekend, I want to write world layers with aBoard surfaces.  
    • c.haslam
      By c.haslam
      I had thought that _GDIPlus_ImageClone($hImage) removes all property items, but I now know that it copies property items.
      What is the easiest way of copying an image that has property items to another image that does not have property items?
    • c.haslam
      By c.haslam
      I think that _GDIPlus_ImageGetPropertyItem should return a Property Item that can readily be set as a property of another image. Why would one want to do this? A script might (as one of mine does) edit an image of a .jpg file then write the result to a .jpg file. In editing it, in my case, the number of horizontal and vertical pixels change, and the date/time edited should be set as a property. All other property items remain the same. Other GDI+ users may change other properties.
      So an approach is to copy all the property items from image1 to image2, then update a few properties.
      M$ provides a Property Item class (id, length, pointer to an array of values) but _GDIPlus_ImageGetPropertyItem returns something different.
      I think that, wherever reasonable, UDFs that are wrappers for M$ methods should work like M$'s methods. _GDIPlus_ImageGetPropertyItem does not do this:
      While M$ returns 2 values for a value that is a ratio of 2 numbers,  _GDIPlus_ImageGetPropertyItem returns numerator/denominator as a single value (often a Double). _GDIPlus_ImageSetPropertyItem (when included in GDIPlus.au3) will be unable to set ratio property items properly because it cannot know what the numerator and denominator are. So copying such property items will not work properly. M$ has a Void* buffer where the buffer is an array of values but _GDIPlus_ImageGetPropertyItem() returns the values in the same 1-d array as id, length and type. M$'s approach produces a 1-d array with the same number of elements for all property items while _GDIPlus_ImageGetPropertyItem produces a 1-d array with various numbers of elements. To me, this is not good programming practice. For a photo from a Sony camera, the worst case has 1-d array with 67 elements. When combined into a 2-d array with the property items of all properties, there are 66 rows and 67 columns, with many elements not used. So I suggest that _GDIPlus_ImageGetPropertyItem look like this:
      ; #FUNCTION# ==================================================================================================================== ; Name ..........: cGDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of meta data) from an Image object ; Syntax ........: cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success: Array containing the values of the property item ; [0] - identifier ; [1] - size, in bytes, of the value array ; [2] - type of value(s) in the value array ; [3] - value array ; Failure: Sets the @error flag to non-zero, @extended may contain GPSTATUS error code ($GPID_ERR*). ; Author ........: Eukalyptus ; Modified ......: c.haslam ; Remarks .......: types: unsigned byte = 1, ASCII string = 2, unsigned short = 3, unsigned long = 4, ; unsinged rational = 5, undefined = 7, signed long = 9, signed rational = 10 ; Related .......: _GDIPlus_ImageGetPropertyIdList ; Link ..........: https://msdn.microsoft.com/en-us/library/windows/desktop/ms535390(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534414(v=vs.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iSize = __GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) Local $tBuffer = DllStructCreate("byte[" & $iSize & "];") Local $pBuffer = DllStructGetPtr($tBuffer) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", _ $iPropID, "uint", $iSize, "struct*", $tBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) Local $tPropertyItem = DllStructCreate("int id; int length; short type; ptr pvalue;", $pBuffer) Local $iBytes = DllStructGetData($tPropertyItem, "length") Local $pValue = DllStructGetData($tPropertyItem, "pvalue") Local $aRet[4] Local $type = DllStructGetData($tPropertyItem,'type') Local $tValues, $iValues Switch $type Case 2 ;ASCII String $iValues = 1 $tValues = DllStructCreate("char[" & $iBytes & "];", $pValue) Case 3 ;Array of UShort $iValues = Int($iBytes / 2) $tValues = DllStructCreate("ushort[" & $iValues & "];", $pValue) Case 4, 5 ;Array of UInt / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("uint[" & $iValues & "];", $pValue) Case 9, 10 ;Array of Int / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("int[" & $iValues & "];", $pValue) Case Else ;Array of Bytes $iValues = 1 $tValues = DllStructCreate("byte[" & $iBytes & "];", $pValue) EndSwitch $aRet[0] = DllStructGetData($tPropertyItem,'id') $aRet[1] = $iBytes $aRet[2] = $type Local $aVals[$iValues] If $type=2 Or $type=7 Then ; ASCII string or undefined $aVals[0] = DllStructGetData($tValues,1) Else For $i = 0 To $iValues-1 $aVals[$i] = DllStructGetData($tValues,1,$i+1) Next EndIf $aRet[3] = $aVals Return $aRet EndFunc And here is an example:
      #include <GDIPlus.au3> #include <Array.au3> Example() Func Example() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile(RegRead((@AutoItX64 = True ? "HKLM\SOFTWARE\Wow6432Node\AutoIt v3\AutoIt" : "HKLM\SOFTWARE\AutoIt v3\AutoIt"), "InstallDir") & "\Examples\GUI\Torus.png") If @error Then _GDIPlus_Shutdown() MsgBox(16, "", "An error has occured - unable to load image!", 30) Return False EndIf Local $ar = _GDIPlus_ImageGetPropertyIdList($hImage) Local $vPropNbrs[UBound($ar,1)-1] ; Extract ID numbers For $i = 1 To UBound($ar,1)-1 $vPropNbrs[$i-1] = $ar[$i][0] Next ; Get all property items Local $aPropItems[UBound($vPropNbrs)][4],$vPropItem For $i = 0 To UBound($vPropNbrs)-1 $vPropItem = cGDIPlus_ImageGetPropertyItem($hImage,$vPropNbrs[$i]) For $j = 0 To 3 $aPropItems[$i][$j] = $vPropItem[$j] Next Next ; Collapse values arrays so _ArrayDisplay can display them Local $ar = $aPropItems For $i = 0 To UBound($aPropItems,1)-1 $ar[$i][0] = '0x'&Hex($ar[$i][0],4) $ar[$i][3] = '' For $j = 0 To UBound($aPropItems[$i][3])-1 $ar[$i][3] &= ($aPropItems[$i][3])[$j]&'|' Next $ar[$i][3] = StringTrimRight($ar[$i][3],1) Next _ArrayDisplay($ar) _GDIPlus_Shutdown() EndFunc Unfortunately this example (based on one now in the Help) does not exercise most of the item types, but I do not know of a file with EXIF metadata that is on most PCs. I have tested this code by updating and adding property items to torus.jpg and to a photo taken by a Sony camera. The code for implementing and calling _GDIPlus_ImageSetPropertyItem will be fairly simple [see below].
       
      Your thoughts?
       
×