Jump to content

GDIPlus, need help with rotating an image


AlmarM
 Share

Go to solution Solved by UEZ,

Recommended Posts

Hi!

I'm having an issue regarding rotating an image using GDIPlus.

I'm trying to draw an image at the center of the GUI, with the center of the image as it's origin.

I would like to rotate this image around it's origin points.

This is what I currently have.

#include <GDIPlus.au3>

Global $hGraphic = -1
Global $hBitmap = -1
Global $hBackbuffer = -1

Global $hArrowTexture = -1
Global $hArrowBitmap = -1
Global $hArrowGC = -1
Global $hArrowMatrix = -1
 
; NOTES
; image width = 112
; image height = 37

Global $hGUI = GUICreate("", 512, 512)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(512, 512, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

Global $iBitmapSize = Ceiling(Sqrt(112^2 + 37^2)) ; A² + B² = C², used to the image can rotate without losing data
$hArrowTexture = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\arrow.png")
$hArrowBitmap = _GDIPlus_BitmapCreateFromGraphics($iBitmapSize, $iBitmapSize, $hBackbuffer)
$hArrowGC = _GDIPlus_ImageGetGraphicsContext($hArrowBitmap)
$hArrowMatrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($hArrowMatrix, -(112 / 2), -(37 / 2)) ; move it back to 0, 0 since (112 / 2) and (37 / 2) are it's middle origin point
_GDIPlus_MatrixRotate($hArrowMatrix, 10) ; rotate it around it's middle origin point
_GDIPlus_GraphicsSetTransform($hArrowGC, $hArrowMatrix)

GUISetState()
While 1
    Switch GUIGetMsg()
        Case -3
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_ImageDispose($hBackbuffer)
            _GDIPlus_Shutdown()
            Exit

    EndSwitch

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF6495ED)

    _GDIPlus_GraphicsClear($hArrowGC, 0xFFCCCCCC) ; show the GC
    _GDIPlus_GraphicsDrawImageRect($hArrowGC, $hArrowTexture, ($iBitmapSize - 112) / 2, ($iBitmapSize - 37) / 2, 112, 37) ; place the arrow at the center of it's GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hArrowBitmap, 256 - ($iBitmapSize / 2), 256 - ($iBitmapSize / 2)) ; move it's GC by an offset so the image is at the correct XY using it's origin

    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 512, 512)
WEnd

 

I cannot seem to get it right.

Any help is welcome! If more info is needed, please tell. :)

post-26984-0-77382100-1383352174_thumb.p

Minesweeper

A minesweeper game created in autoit, source available.

_Mouse_UDF

An UDF for registering functions to mouse events, made in pure autoit.

2D Hitbox Editor

A 2D hitbox editor for quick creation of 2D sphere and rectangle hitboxes.

Link to comment
Share on other sites

That does seem to work, I'll keep that in mind. :D

Though I'd like to keep working without the beta for now.

I think in my example I'm doing the position wrong, but I can't see how.

Minesweeper

A minesweeper game created in autoit, source available.

_Mouse_UDF

An UDF for registering functions to mouse events, made in pure autoit.

2D Hitbox Editor

A 2D hitbox editor for quick creation of 2D sphere and rectangle hitboxes.

Link to comment
Share on other sites

  • Solution

Try this:

#include <GDIPlus.au3>

Global $hGUI = GUICreate("", 512, 512)

_GDIPlus_Startup()
$hArrowTexture = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\arrow.png")
$iW = _GDIPlus_ImageGetWidth($hArrowTexture)
$iH = _GDIPlus_ImageGetHeight($hArrowTexture)
$iW2 = $iW / 2
$iH2 = $iH / 2

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(512, 512, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

$hArrowBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iW, $hBackbuffer)
$hArrowGC = _GDIPlus_ImageGetGraphicsContext($hArrowBitmap)
$hArrowMatrix = _GDIPlus_MatrixCreate()

GUISetState()

AdlibRegister("Rotate", 20)

While 1
    Switch GUIGetMsg()
        Case -3
            AdlibUnRegister("Rotate")
            _GDIPlus_MatrixDispose($hArrowMatrix)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_GraphicsDispose($hArrowGC)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_BitmapDispose($hArrowBitmap)
            _GDIPlus_BitmapDispose($hArrowTexture)
            _GDIPlus_ImageDispose($hBackbuffer)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func Rotate()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF6495ED)

    _GDIPlus_MatrixTranslate($hArrowMatrix, $iW2, $iW2) ; move it back to 0, 0 since (112 / 2) and (37 / 2) are it's middle origin point
    _GDIPlus_MatrixRotate($hArrowMatrix, 1) ; rotate it around it's middle origin point
    _GDIPlus_GraphicsSetTransform($hArrowGC, $hArrowMatrix)
    _GDIPlus_MatrixTranslate($hArrowMatrix, -$iW2, -$iW2)

    _GDIPlus_GraphicsClear($hArrowGC, 0xFFCCCCCC) ; show the GC
    _GDIPlus_GraphicsDrawImageRect($hArrowGC, $hArrowTexture, -$iW2, -$iH2, $iW, $iH) ; place the arrow at the center of it's GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hArrowBitmap, 256 - $iW2, 256 - $iW2) ; move it's GC by an offset so the image is at the correct XY using it's origin

    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 512, 512)
EndFunc

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

Link to comment
Share on other sites

Try this:

#include <GDIPlus.au3>

Global $hGUI = GUICreate("", 512, 512)

_GDIPlus_Startup()
$hArrowTexture = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\arrow.png")
$iW = _GDIPlus_ImageGetWidth($hArrowTexture)
$iH = _GDIPlus_ImageGetHeight($hArrowTexture)
$iW2 = $iW / 2
$iH2 = $iH / 2

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(512, 512, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

$hArrowBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iW, $hBackbuffer)
$hArrowGC = _GDIPlus_ImageGetGraphicsContext($hArrowBitmap)
$hArrowMatrix = _GDIPlus_MatrixCreate()

GUISetState()

AdlibRegister("Rotate", 20)

While 1
    Switch GUIGetMsg()
        Case -3
            AdlibUnRegister("Rotate")
            _GDIPlus_MatrixDispose($hArrowMatrix)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_GraphicsDispose($hArrowGC)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_BitmapDispose($hArrowBitmap)
            _GDIPlus_BitmapDispose($hArrowTexture)
            _GDIPlus_ImageDispose($hBackbuffer)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func Rotate()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF6495ED)

    _GDIPlus_MatrixTranslate($hArrowMatrix, $iW2, $iW2) ; move it back to 0, 0 since (112 / 2) and (37 / 2) are it's middle origin point
    _GDIPlus_MatrixRotate($hArrowMatrix, 1) ; rotate it around it's middle origin point
    _GDIPlus_GraphicsSetTransform($hArrowGC, $hArrowMatrix)
    _GDIPlus_MatrixTranslate($hArrowMatrix, -$iW2, -$iW2)

    _GDIPlus_GraphicsClear($hArrowGC, 0xFFCCCCCC) ; show the GC
    _GDIPlus_GraphicsDrawImageRect($hArrowGC, $hArrowTexture, -$iW2, -$iH2, $iW, $iH) ; place the arrow at the center of it's GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hArrowBitmap, 256 - $iW2, 256 - $iW2) ; move it's GC by an offset so the image is at the correct XY using it's origin

    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 512, 512)
EndFunc

Br,

UEZ

 

Works like a charm! Thaaanks. :thumbsup:

Minesweeper

A minesweeper game created in autoit, source available.

_Mouse_UDF

An UDF for registering functions to mouse events, made in pure autoit.

2D Hitbox Editor

A 2D hitbox editor for quick creation of 2D sphere and rectangle hitboxes.

Link to comment
Share on other sites

  • 1 year later...

Hi, sorry for the bump the topic ... I hardwired a little above code, but it does not work as it should. After the program used by him RAM is increased to 1.5GB. Why? And image is black... This is my code:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
OnAutoItExitRegister("_Exit")
Global $hGUI = GUICreate("", 512, 512)
GUISetBkColor(0x000000)
GUISetState()
_GDIPlus_Startup()
Global $Root = 0
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    _Rotate("arrow.png",$hGUI,0,0,512,512,$Root)
    $Root += 1
    If $Root = 359 Then $Root = 0
    ToolTip($Root,0,0)
    Sleep(10)
WEnd
Func _Rotate($szImage,$szGui,$szX,$szY,$szW,$szH,$szRot)
    Global $hArrowTexture = _GDIPlus_BitmapCreateFromFile($szImage)
    Global $iW = $szW
    Global $iH = $szH
    Global $iW2 = $iW / 2
    Global $iH2 = $iH / 2
    Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($szGui)
    Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($szW, $szH, $hGraphic)
    Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Global $hArrowBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iW, $hBackbuffer)
    Global $hArrowGC = _GDIPlus_ImageGetGraphicsContext($hArrowBitmap)
    Global $hArrowMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hArrowMatrix, $iW2, $iW2)
    _GDIPlus_MatrixRotate($hArrowMatrix, $szRot)
    _GDIPlus_GraphicsSetTransform($hArrowGC, $hArrowMatrix)
    _GDIPlus_MatrixTranslate($hArrowMatrix, -$iW2, -$iW2)
    _GDIPlus_GraphicsClear($hArrowGC,0xFFFFFFFF)
    _GDIPlus_GraphicsDrawImageRect($hArrowGC, $hArrowTexture, -$iW2, -$iH2, $iW, $iH)
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hArrowBitmap, $szX ,$szY)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap,$szX ,$szY,$szW,$szH)
EndFunc
Func _Exit()
    _GDIPlus_MatrixDispose($hArrowMatrix)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hArrowGC)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hArrowBitmap)
    _GDIPlus_BitmapDispose($hArrowTexture)
    _GDIPlus_ImageDispose($hBackbuffer)
    _GDIPlus_Shutdown()
EndFunc

@Edit Problem with Ram fixed I use that:
 

Func _ReduceMemory($i_PID = -1)
    If $i_PID <> -1 Then
        Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
        DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
    Else
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    EndIf
    Return $ai_Return[0]
EndFunc

But after some time image is black...

Edited by MrKris1224
Link to comment
Share on other sites

Not sure about the first issue, but that second script doesn't do what you think it does. All it does is take what is in your RAM, and dumps it to the hard drive, meaning what used to run pretty quickly is now going to slow down considerably and you're not actually restoring the RAM to the system, you're just emptying it into something 100's of times slower.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Your problem is that you calling _Rotate() in a loop without release the resources which causes a memory leak!

 

Check out post#6 to see how to rotate without causing a memory leak!

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

Link to comment
Share on other sites

That makes no sense regarding _ReduceMemory. If you add GDI+ handles permanently in the loop without releasing it then it will cause a memory leak!

Which operating system are you using?

 

The arrow is an image with transparent background!

Br,

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

Your script is quasi the example from post#6. Why don't you use it?

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

Link to comment
Share on other sites

Imho, this is simple - simplier not possible.

#include <GDIPlus.au3>

Global $hGUI = GUICreate("", 512, 512)

_GDIPlus_Startup()
$hArrowTexture = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\arrow.png")
$iW = _GDIPlus_ImageGetWidth($hArrowTexture)
$iH = _GDIPlus_ImageGetHeight($hArrowTexture)
$iW2 = $iW / 2
$iH2 = $iH / 2

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(512, 512, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

$hArrowBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iW, $hBackbuffer)
$hArrowGC = _GDIPlus_ImageGetGraphicsContext($hArrowBitmap)
$hArrowMatrix = _GDIPlus_MatrixCreate()

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            _GDIPlus_MatrixDispose($hArrowMatrix)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_GraphicsDispose($hArrowGC)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_BitmapDispose($hArrowBitmap)
            _GDIPlus_BitmapDispose($hArrowTexture)
            _GDIPlus_ImageDispose($hBackbuffer)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    Rotate()
WEnd

Func Rotate()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF6495ED)

    _GDIPlus_MatrixTranslate($hArrowMatrix, $iW2, $iW2) ; move it back to 0, 0 since (112 / 2) and (37 / 2) are it's middle origin point
    _GDIPlus_MatrixRotate($hArrowMatrix, 1) ; rotate it around it's middle origin point
    _GDIPlus_GraphicsSetTransform($hArrowGC, $hArrowMatrix)
    _GDIPlus_MatrixTranslate($hArrowMatrix, -$iW2, -$iW2)

    _GDIPlus_GraphicsClear($hArrowGC, 0x00000000) ; show the GC
    _GDIPlus_GraphicsDrawImageRect($hArrowGC, $hArrowTexture, -$iW2, -$iH2, $iW, $iH) ; place the arrow at the center of it's GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hArrowBitmap, 256 - $iW2, 256 - $iW2) ; move it's GC by an offset so the image is at the correct XY using it's origin

    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 512, 512)
EndFunc
Br,

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

Example:

#include <GDIPlus.au3>

Global $hGUI = GUICreate("", 512, 512)

_GDIPlus_Startup()
$hTextureArrow = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\arrow.png")
$iW = _GDIPlus_ImageGetWidth($hTextureArrow)
$iH = _GDIPlus_ImageGetHeight($hTextureArrow)
$iW2 = $iW / 2
$iH2 = $iH / 2

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(512, 512, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

$hBitmap_Background = _GDIPlus_ImageLoadFromFile("c:\Program Files (x86)\AutoIt3\Examples\GUI\logo4.gif")
$iW2_Bg = _GDIPlus_ImageGetWidth($hBitmap_Background) / 2
$iH2_Bg = _GDIPlus_ImageGetHeight($hBitmap_Background) / 2
$hBitmap_Arrow = _GDIPlus_BitmapCreateFromGraphics($iW, $iW, $hBackbuffer)
$hGCArrow = _GDIPlus_ImageGetGraphicsContext($hBitmap_Arrow)
$hMatrixArrow = _GDIPlus_MatrixCreate()

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            _GDIPlus_MatrixDispose($hMatrixArrow)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_GraphicsDispose($hGCArrow)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_BitmapDispose($hBitmap_Arrow)
            _GDIPlus_BitmapDispose($hTextureArrow)
            _GDIPlus_ImageDispose($hBitmap_Background)
            _GDIPlus_GraphicsDispose($hBackbuffer)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    Rotate()
WEnd

Func Rotate()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF6495ED)
    _GDIPlus_MatrixTranslate($hMatrixArrow, $iW2, $iW2) ; move it back to 0, 0 since (112 / 2) and (37 / 2) are it's middle origin point
    _GDIPlus_MatrixRotate($hMatrixArrow, 1) ; rotate it around it's middle origin point
    _GDIPlus_GraphicsSetTransform($hGCArrow, $hMatrixArrow)
    _GDIPlus_MatrixTranslate($hMatrixArrow, -$iW2, -$iW2)
    _GDIPlus_GraphicsClear($hGCArrow, 0x00000000)
    _GDIPlus_GraphicsDrawImageRect($hGCArrow, $hTextureArrow, -$iW2, -$iH2, $iW, $iH) ; place the arrow at the center of it's GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitmap_Background, (256 - $iW2_Bg), (256 - $iH2_Bg)) ; show the GC
    _GDIPlus_GraphicsDrawImage($hBackbuffer, $hBitmap_Arrow, 256 - $iW2, 256 - $iW2) ; move it's GC by an offset so the image is at the correct XY using it's origin
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 512, 512)
EndFunc

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

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