Jump to content
Sign in to follow this  
mdepot

Propose using ImageAttribute with SetWrapMode to TileFlipXY on _GDIPlus_ImageScale and _GDIPlus_ImageResize - (Moved)

Recommended Posts

I noticed a few minor image artifacts when using _GDIPlus_ImageScale and _GDIPlus_ImageResize.  There was a slight ghost border being created around the edges of the image, and the right and bottom edges had transparency showing through.  I created tickets for the issues and also submitted a proposed code fix.  Please see Trac #3647  and Trac #3650 for more details if interested.  Feedback welcome.  ( @UEZ ?)

Thanks

Edited by mdepot

Share this post


Link to post
Share on other sites

Moved to the appropriate forum.

Moderation Team


Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

@mdepot can you test please these two new versions whether the resize / scale works better now?

 

_GDIPlus_ImageResize2:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

Global Enum $GDIP_WrapModeTile, $GDIP_WrapModeTileFlipX, $GDIP_WrapModeTileFlipY, $GDIP_WrapModeTileFlipXY, $GDIP_WrapModeClamp

Example()

Func Example()
    ; Load an image
    Local $sFile = FileOpenDialog("Select an image", "", "Image (*.jpg;*.png;*.bmp;*.gif;*.tif)")
    If @error Then Exit MsgBox($MB_ICONWARNING, "Waring", "No image was selected! Exiting script...")

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_ImageLoadFromFile($sFile)
    Local $aDim = _GDIPlus_ImageGetDimension($hBitmap)
    Local $hBitmap_Resized = _GDIPlus_ImageResize2($hBitmap, $aDim[0] / 2, $aDim[0] / 2) ;resize image

    Local $hGUI = GUICreate("GDI+ test", $aDim[0] / 2, $aDim[0] / 2, -1, -1) ;create a test gui to display the resized image
    GUISetState(@SW_SHOW)

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Resized, 0, 0) ;display scaled image

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ;cleanup resources
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap_Resized)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example


Func _GDIPlus_ImageResize2($hImage, $iWidth_new, $iHeight_new, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth_new, $iHeight_new)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetImageWrapMode($hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth_new, $iHeight_new, $hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageResize2

Func _GDIPlus_ImageAttributesSetImageWrapMode($hImageAttributes, $iWrapMode = $GDIP_WrapModeTileFlipXY, $iColor = 0xFF000000)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesWrapMode", "handle", $hImageAttributes, _
                                            "long", $iWrapMode, "uint", $iColor, "bool", False)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_ImageAttributesSetImageWrapMode

 

_GDIPlus_ImageScale2:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

Global Enum $GDIP_WrapModeTile, $GDIP_WrapModeTileFlipX, $GDIP_WrapModeTileFlipY, $GDIP_WrapModeTileFlipXY, $GDIP_WrapModeClamp

Example()

Func Example()
    ; Load an image
    Local $sFile = FileOpenDialog("Select an image", "", "Image (*.jpg;*.png;*.bmp;*.gif;*.tif)")
    If @error Then Exit MsgBox($MB_ICONWARNING, "Waring", "No image was selected! Exiting script...")

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_ImageLoadFromFile($sFile)
    Local $aDim = _GDIPlus_ImageGetDimension($hBitmap)

    Local $iScale = 4 ;1.0 is without any scaling
    Local $hBitmap_Scaled = _GDIPlus_ImageScale2($hBitmap, $iScale, $iScale, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR) ;scale image by 275% (magnify)

    Local $hGUI = GUICreate("GDI+ test", $aDim[0] * $iScale, $aDim[1] * $iScale, -1, -1) ;create a test gui to display the resized image
    GUISetState(@SW_SHOW)

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Scaled, 0, 0) ;display scaled image

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ;cleanup resources
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap_Scaled)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _GDIPlus_ImageScale2($hImage, $iScaleW, $iScaleH, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $iWidth_new = $iWidth * $iScaleW
    Local $iHeight_new =  $iHeight * $iScaleH
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth_new, $iHeight_new)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetImageWrapMode($hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth_new, $iHeight_new, $hIA)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageScale2

Func _GDIPlus_ImageAttributesSetImageWrapMode($hImageAttributes, $iWrapMode = $GDIP_WrapModeTileFlipXY, $iColor = 0xFF000000)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesWrapMode", "handle", $hImageAttributes, _
                                            "long", $iWrapMode, "uint", $iColor, "bool", False)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_ImageAttributesSetImageWrapMode

 

I tried to adapt https://www.codeproject.com/Articles/11143/Image-Resizing-outperform-GDI using the ImageAttributes idea.

Edited by UEZ
small modifications

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

Hi UEZ, thanks for responding.  :D   I tested your functions in my own app and I found they are working nicely.  I compared the image quality of the original code versus my earlier fix, and versus your improved fix.  So far this is the best.  I see you also added a call to set PixelOffsetMode, which is a nice addition. Thanks! 

In testing this I found out a little more about my ticket #3650.  It's not that the bottom and right edges were missing and showing through the transparency, but rather that the entire image was placed up and left by one pixel, so all of the image content was shifted up and left, and it was the top and left edge of the original image that was being clipped.  I updated the ticket to mention this.

I do have a couple other comments as feedback...

First, you must have meant to multiply by 4 instead of dividing by 4 in your posted example() for Resize2, yea obviously.

Regarding the name of the new dll setwrap function, since Microsoft names their function ImageAttributes::SetWrapMode here:
https://docs.microsoft.com/.../nf-gdiplusimageattributes-imageattributes-setwrapmode
I would suggest using the name _GDIPlus_ImageAttributesSetWrapMode as opposed to _GDIPlus_ImageAttributesSetImageWrapMode.

This one is really really minor, and I realize this is just test code anyway, but the names of the new size vars between the two functions are inconsistent.  ( $iNewWidth, $iNewHeight versus $iWidth_new, $iHeight_new)

And finally some thoughts about error check blocks.  Correct me if I'm wrong, but In my mind there's a minimum number of error blocks needed. That number is determined by the number of unique sets of variables that may need to be freed with a Dispose call at any given point within the function.  Depending on where we are in the code we may need to call Dispose for just $hBitmap, or for $hBitmap and $hBmpCtxt, or for $hBitmap and $hBmpCtxt and $hIA.  The location for any one of these blocks obviously needs to be after the allocation of variables in that set, but also before something new is allocated outside of that set, which would then require you to dispose a different set.  That can perhaps more easily be seen by looking at some code:

; partial code

    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    ; do stuff with $hBitmap
    If @error Then
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    ; do stuff with $hBitmap and $hBmpCtxt
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(5, 0, 0)
    EndIf

    Local $hIA = _GDIPlus_ImageAttributesCreate()
    ; do stuff with $hBitmap and $hBmpCtxt and $hIA
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(6, 0, 0)
    EndIf
    
    ; success, but before returning dispose of what will not be used again
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)

So that would seem to define the minimal error blocks needed and frames the function overall.  In my own test code, I started with this framework and then just filled in the "do stuff" blocks with other calls, arriving at this slightly modified version of your function body:

; partial code

    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(5, 0, 0)
    EndIf
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    _GDIPlus_ImageAttributesSetWrapMode($hIA)
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(6, 0, 0)
    EndIf
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)

Now of course that doesn't preclude us from also adding additional checks and error blocks on the other GDI function calls, but it does seem that this is would be the minimum that we can get away with.  (And even then, we're still leaving it up to the caller to dispose of $hBitmap afterwards.)

Anyway, so for what it's worth, here is a reprint of the test code you posted above, with some minor changes I mentioned.  Really, it's practically identical anyway.

_GDIPlus_ImageResize2:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

Global Enum $GDIP_WrapModeTile, $GDIP_WrapModeTileFlipX, $GDIP_WrapModeTileFlipY, $GDIP_WrapModeTileFlipXY, $GDIP_WrapModeClamp

Example()

Func Example()
    ; Load an image
    Local $sFile = FileOpenDialog("Select an image", "", "Image (*.jpg;*.png;*.bmp;*.gif;*.tif)")
    If @error Then Exit MsgBox($MB_ICONWARNING, "Waring", "No image was selected! Exiting script...")

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_ImageLoadFromFile($sFile)
    Local $aDim = _GDIPlus_ImageGetDimension($hBitmap)
    Local $hBitmap_Scaled = _GDIPlus_ImageResize2($hBitmap, $aDim[0] * 4, $aDim[0] * 4) ;resize image

    Local $hGUI = GUICreate("GDI+ test", $aDim[0] * 4, $aDim[0] * 4, -1, -1) ;create a test gui to display the resized image
    GUISetState(@SW_SHOW)

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Scaled, 0, 0) ;display scaled image

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ;cleanup resources
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap_Scaled)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example


Func _GDIPlus_ImageResize2($hImage, $iNewWidth, $iNewHeight, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    If @error Then
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(5, 0, 0)
    EndIf
    _GDIPlus_ImageAttributesSetWrapMode($hIA)
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(6, 0, 0)
    EndIf
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageResize2

Func _GDIPlus_ImageAttributesSetWrapMode($hImageAttributes, $iWrapMode = $GDIP_WrapModeTileFlipXY, $iColor = 0xFF000000)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesWrapMode", "handle", $hImageAttributes, _
            "long", $iWrapMode, "uint", $iColor, "boolean", False)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_ImageAttributesSetWrapMode

_GDIPlus_ImageScale2:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

Global Enum $GDIP_WrapModeTile, $GDIP_WrapModeTileFlipX, $GDIP_WrapModeTileFlipY, $GDIP_WrapModeTileFlipXY, $GDIP_WrapModeClamp

Example()

Func Example()
    ; Load an image
    Local $sFile = FileOpenDialog("Select an image", "", "Image (*.jpg;*.png;*.bmp;*.gif;*.tif)")
    If @error Then Exit MsgBox($MB_ICONWARNING, "Waring", "No image was selected! Exiting script...")

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_ImageLoadFromFile($sFile)
    Local $aDim = _GDIPlus_ImageGetDimension($hBitmap)

    Local $iScale = 4 ;1.0 is without any scaling
    Local $hBitmap_Scaled = _GDIPlus_ImageScale2($hBitmap, $iScale, $iScale) ;scale image by 400% (magnify)

    Local $hGUI = GUICreate("GDI+ test", $aDim[0] * $iScale, $aDim[1] * $iScale, -1, -1) ;create a test gui to display the resized image
    GUISetState(@SW_SHOW)

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Scaled, 0, 0) ;display scaled image

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ;cleanup resources
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap_Scaled)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _GDIPlus_ImageScale2($hImage, $iScaleW, $iScaleH, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $iNewWidth = $iWidth * $iScaleW
    Local $iNewHeight = $iHeight * $iScaleH
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    If @error Then
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    If @error Then
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(5, 0, 0)
    EndIf
    _GDIPlus_ImageAttributesSetWrapMode($hIA)
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(6, 0, 0)
    EndIf
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageScale2

Func _GDIPlus_ImageAttributesSetWrapMode($hImageAttributes, $iWrapMode = $GDIP_WrapModeTileFlipXY, $iColor = 0xFF000000)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesWrapMode", "handle", $hImageAttributes, _
            "long", $iWrapMode, "uint", $iColor, "boolean", False)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_ImageAttributesSetWrapMode

Thanks again.

Edited by mdepot

Share this post


Link to post
Share on other sites
23 hours ago, mdepot said:

First, you must have meant to multiply by 4 instead of dividing by 4 in your posted example() for Resize2, yea obviously

Why? Resize means also to reduce the size.

 

23 hours ago, mdepot said:

This one is really really minor, and I realize this is just test code anyway, but the names of the new size vars between the two functions are inconsistent.  ( $iNewWidth, $iNewHeight versus $iWidth_new, $iHeight_new)

That can be easily changed.

23 hours ago, mdepot said:

Regarding the name of the new dll setwrap function, since Microsoft names their function ImageAttributes::SetWrapMode here:
https://docs.microsoft.com/.../nf-gdiplusimageattributes-imageattributes-setwrapmode
I would suggest using the name _GDIPlus_ImageAttributesSetWrapMode as opposed to _GDIPlus_ImageAttributesSetImageWrapMode.

As you might seen all other functions are not names as the DLL call name. I chose a shorter name. :)

23 hours ago, mdepot said:

And finally some thoughts about error check blocks.  Correct me if I'm wrong, but In my mind there's a minimum number of error blocks needed. That number is determined by the number of unique sets of variables that may need to be freed with a Dispose call at any given point within the function.

Well I thought about the error checks and decided to reduce the error check to a minimum because I don't think that all checks are really needed to be "bullet proof".

 

@all: any other thoughts / suggestions?


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
18 hours ago, UEZ said:

Why? Resize means also to reduce the size.

Oh I see what you mean, and now I know what happened.  I tried the example on a file that was already so small to begin with that reducing by 4 made the window that pops up so small that the window controls were mangled.  (I had also been playing around with ImageMagick lately, so I happened to have the tree.gif sample they use on their demos already on my desktop, so I had used that.)

Anyway, thank you for looking this over, and for your feedback. :D

 

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...