Jump to content

GDIPlus Rotate Image - Assign to Control


YellowLab
 Share

Recommended Posts

I have been pulling my hair out with this one. I don't know if it can be done.

Here is what I want to do:

1) Load Image (ideally from a resource, currently from a file)

2) Rotate that image 90 or 180 degrees

3) apply image to an already existing control

This topic has been helpful in getting started:

http://www.autoitscript.com/forum/index.php?showtopic=107822&st=0&p=760283&hl=gdi%20rotate&fromsearch=1&#entry760283

I kind of pilfered that code and have this:

$sFile is the file location

$nW is the rotated image's width (already known)

$nH is the rotate image's height (already known)

_GDIPlus_Startup()
$hImage1 = _GDIPlus_ImageLoadFromFile($sFile)
$hGraphic1 = _GDIPlus_ImageGetGraphicsContext($hImage1)
$hImage2 = _GDIPlus_BitmapCreateFromGraphics($nW,$nH,$hGraphic1)
$hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hImage2)

$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($matrix, 90)
_GDIPlus_GraphicsSetTransform($hGraphic2, $matrix)
_GDIPlus_GraphicsDrawImage($hGraphic2, $hImage1, 0, -$nW)

_GDIPlus_ImageSaveToFile($hImage2, @ScriptDir & "\PNGs\image.png")

_GDIPlus_MatrixDispose($matrix)
_GDIPlus_GraphicsDispose($hGraphic1)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)

_GDIPlus_Shutdown()

This all works, in that the image dump shows the image rotated 90 degrees. I have tried using Zedna's resource.au3 function _SetBitmapToCtrl; however, the function needs a bitmap, obviously. I have tried to convert the image with out success. Looking at Zedna's function I think this is something of what I need to do, but can't figure out how to complete it on a non-resource entity:

; thanks ProgAndy
; for other types than BITMAP use GDI+ for converting to bitmap first
$hData = _MemGlobalAlloc($nSize,2) 
$pData = _MemGlobalLock($hData)
_MemMoveMemory($ResData,$pData,$nSize)
_MemGlobalUnlock($hData)
$pStream = DllCall( "ole32.dll","int","CreateStreamOnHGlobal", "int",$hData, "long",1, "Int*",0)
$pStream = $pStream[3]
$pBitmap = DllCall($ghGDIPDll,"int","GdipCreateBitmapFromStream", "ptr",$pStream, "int*",0)
$pBitmap = $pBitmap[2]
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($pBitmap)
_SetBitmapToCtrl($CtrlId, $hBitmap)
If @error Then SetError(3, 0, 0)
_GDIPlus_BitmapDispose($pBitmap)
_WinAPI_DeleteObject($pStream)
_MemGlobalFree($hData)

I need '$nSize' for my non-resource data. Further digging in Zedna's code shows this is calculated by (I think):

$ResSize = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hInstance, "int", $InfoBlock)

where

$hInstance = _WinAPI_GetModuleHandle("")

$InfoBlock = DllCall("kernel32.dll", "int", "FindResourceExA", "int", $hInstance, "long", $ResType, "str", $ResName, "short", $ResLang)

Any help would be appreciated.

Thanks!

Edited by YellowLab

You can't see a rainbow without first experiencing the rain.

Link to comment
Share on other sites

Maybe this might help you a little bit: Image Rotation over a background or GDI+ Image Rotator and Saver

Regards,

UEZ

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

Link to comment
Share on other sites

I think I have gotten it solved. I was deleting the converted resource:

This code will crash:

_GDIPlus_Startup()
$hImage1 = _GDIPlus_ImageLoadFromFile($sFile)
$hGraphic1 = _GDIPlus_ImageGetGraphicsContext($hImage1)
$hImage2 = _GDIPlus_BitmapCreateFromGraphics($nW,$nH,$hGraphic1)
$hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hImage2)

$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($matrix, 90)
_GDIPlus_GraphicsSetTransform($hGraphic2, $matrix)
_GDIPlus_GraphicsDrawImage($hGraphic2, $hImage1, 0, -$nW)

$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage2)

_SetBitmapToCtrl($arControls[$nIndex][$MY_CONTROL_ID], $hBitmap)

_GDIPlus_MatrixDispose($matrix)
_GDIPlus_GraphicsDispose($hGraphic1)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
_GDIPlus_BitmapDispose($hBitmap)

_GDIPlus_Shutdown()

This code will not and works as intended:

_GDIPlus_Startup()
$hImage1 = _GDIPlus_ImageLoadFromFile($sFile)
$hGraphic1 = _GDIPlus_ImageGetGraphicsContext($hImage1)
$hImage2 = _GDIPlus_BitmapCreateFromGraphics($nW,$nH,$hGraphic1)
$hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hImage2)

$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($matrix, 90)
_GDIPlus_GraphicsSetTransform($hGraphic2, $matrix)
_GDIPlus_GraphicsDrawImage($hGraphic2, $hImage1, 0, -$nW)

$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage2)

_SetBitmapToCtrl($arControls[$nIndex][$MY_CONTROL_ID], $hBitmap)

_GDIPlus_MatrixDispose($matrix)
_GDIPlus_GraphicsDispose($hGraphic1)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
;_GDIPlus_BitmapDispose($hBitmap) ;DO NOT DISPOSE!

It was found by removing the $hBitmap resource entirely:

_GDIPlus_Startup()
$hImage1 = _GDIPlus_ImageLoadFromFile($sFile)
$hGraphic1 = _GDIPlus_ImageGetGraphicsContext($hImage1)
$hImage2 = _GDIPlus_BitmapCreateFromGraphics($nW,$nH,$hGraphic1)
$hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hImage2)

$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($matrix, 90)
_GDIPlus_GraphicsSetTransform($hGraphic2, $matrix)
_GDIPlus_GraphicsDrawImage($hGraphic2, $hImage1, 0, -$nW)

_SetBitmapToCtrl($arControls[$nIndex][$MY_CONTROL_ID], _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage2))

_GDIPlus_MatrixDispose($matrix)
_GDIPlus_GraphicsDispose($hGraphic1)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)

Hope someone finds this useful.

You can't see a rainbow without first experiencing the rain.

Link to comment
Share on other sites

Tell me about this function?

_setBitmaptoCtrl

Not disposing of the bitmap seems like a memory leak. Someone recently taught me to set a bitmap to a ctrl as per below. This will delete the bitmap also.

_WinAPI_DeleteObject(GUICtrlSendMsg($Control, 0x0172, 0, $hBMP1))
Link to comment
Share on other sites

SetBitmapToCtrl is a function in Zedna's resource UDF. I agree that not disposing of the bitmap resource is a potential source for a memory leak. Which makes me wonder, why does explicitly defining the bitmap used in the function versus generting it at run time create such different results?

picea892 - the function you provide works perfectly well. Thank you.

You can't see a rainbow without first experiencing the rain.

Link to comment
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
 Share

  • Recently Browsing   0 members

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