Sign in to follow this  
Followers 0
oMBRa

rotate an image

24 posts in this topic

how to rotate an image on the axis that go through the middle of the image?

I have already tried _GDIPlus_MatrixRotate() but it rotates the image on the left corner

Share this post


Link to post
Share on other sites



Hi!

You need to translate the matrix before using GDIPlus_MatrixRotate.

Like this:

#include <GDIPlus.au3>

Opt("GuiOnEventMode", 1)
$hwnd = GUICreate("Test", 300, 300)
GUISetState()
GUISetOnEvent(-3, "close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(300, 300, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$pen = _GDIPlus_PenCreate(0xFF00FF00, 2)

InetGet("http://msp5.photobucket.com/albums/y196/dannydude182/smiley-300x300.png",@ScriptDir&"\smiley.png")

$image=_GDIPlus_ImageLoadFromFile(@ScriptDir&"\smiley.png")

$matrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($matrix, 150, 150)



$inc = 0
Do
    _GDIPlus_GraphicsClear($backbuffer)
    
    _GDIPlus_MatrixRotate($matrix,1)
    _GDIPlus_GraphicsSetTransform($backbuffer,$matrix)
    
    _GDIPlus_GraphicsDrawImageRect($backbuffer,$image,-150,-150,300,300)
    
    
    _GDIPlus_GraphicsDrawImageRect($graphics,$bitmap,0,0,300,300)
    Sleep(10)
Until 0


Func close()
    Exit
EndFunc  ;==>close


Func _GDIPlus_MatrixTranslate($hMatrix, $nOffsetX, $nOffsetY, $fOrder = True)
    $aResult = DllCall($ghGDIPDll, "int", "GdipTranslateMatrix", "ptr", $hMatrix, "float", $nOffsetX, "float", $nOffsetY, "int", $fOrder)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>_GDIPlus_MatrixTranslate

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

thx it works, but now how to change the background to another color?

Edited by oMBra

Share this post


Link to post
Share on other sites

thx it works, but now how to change the background to another color?

Check the parameters for _GDIPlus_GraphicsClear().


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

so I should replace

_GDIPlus_GraphicsClear($backbuffer)

with

_GDIPlus_GraphicsClear(0xFFFFFFFF)

?

Share this post


Link to post
Share on other sites

so I should replace

_GDIPlus_GraphicsClear($backbuffer)

with

_GDIPlus_GraphicsClear(0xFFFFFFFF)

?

No.

_GDIPlus_GraphicsClear($backbuffer,0xFFFFFFFF)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

yes, u are right, firs time I tried it was extremely slow so I thought it was wrong but now works properly...

I would have at least half of your skill!

Share this post


Link to post
Share on other sites

You can rotate an image with this functions:

Func GdipRotateTextureTransform($hBrush,$Angle,$MatrixOrder=0)
    Local $DLL = "gdiplus.dll"
    Local $RESULT
    $RESULT = DllCall($DLL,"int","GdipRotateTextureTransform","int",$hBrush,"float",$Angle,"int",$MatrixOrder)
EndFunc

Func GdipCreateTexture($hImg,$WrapMode=0x00)
    Local $DLL = "gdiplus.dll"
    Local $RESULT
    $RESULT = DllCall($DLL,"int","GdipCreateTexture","int",$hImg,"int",$WrapMode,"int*",0)
    Return $RESULT[3]
EndFunc

When the words fail... music speaks

Share this post


Link to post
Share on other sites

a reply after 2,5 years :)

i have a question, is this also be possible with images which have different width and height?

i tryed it but during rotation the longer side would be cut of. tryed many code-moddings

of the given example since the last two days, but cant find a solution....

regards, andy

Share this post


Link to post
Share on other sites

as @monoceres says two years ago you need to translate the matrix first, because the axis is in the 0, 0 coords of the graphics.

Share this post


Link to post
Share on other sites

as @monoceres says two years ago you need to translate the matrix first, because the axis is in the 0, 0 coords of the graphics.

thx for the hint, got it now! there was some wrong parameters in my matrixtranslation.

but there is another question: if i rotate a png with transparency, the background will be black colored.

is there a way to keep the transparency?

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

try this

#include <GDIPlus.au3>

Opt("GuiOnEventMode", 1)
$hwnd = GUICreate("Test", 300, 300)
GUISetState()
GUISetOnEvent(-3, "close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(300, 300, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$pen = _GDIPlus_PenCreate(0xFF00FF00, 2)

InetGet("http://msp5.photobucket.com/albums/y196/dannydude182/smiley-300x300.png",@ScriptDir&"\smiley.png")

$image=_GDIPlus_ImageLoadFromFile(@ScriptDir&"\smiley.png")

$matrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($matrix, 150, 150)



$inc = 0
Do
;~     _GDIPlus_GraphicsClear($backbuffer)

    _GDIPlus_MatrixRotate($matrix,1)
    _GDIPlus_GraphicsSetTransform($backbuffer,$matrix)

    _GDIPlus_GraphicsDrawImageRect($backbuffer,$image,-150,-150,300,300)


    _GDIPlus_GraphicsDrawImageRect($graphics,$bitmap,0,0,300,300)
    Sleep(10)
Until 0


Func close()
    Exit
EndFunc  ;==>close


;~ Func _GDIPlus_MatrixTranslate($hMatrix, $nOffsetX, $nOffsetY, $fOrder = True)
;~     $aResult = DllCall($ghGDIPDll, "int", "GdipTranslateMatrix", "ptr", $hMatrix, "float", $nOffsetX, "float", $nOffsetY, "int", $fOrder)
;~     If @error Then Return SetError(@error, @extended, False)
;~     Return SetError($aResult[0], 0, $aResult[0] = 0)
;~ EndFunc  ;==>_GDIPlus_MatrixTranslate

And be sure that your png transparencies are fully transparents

Edited by monoscout999

Share this post


Link to post
Share on other sites

Another version. to avoid that white dots around be sure that your PNG file have fully tranparencies around.

#include <GDIPlus.au3>
#include <winapi.au3>
#include <windowsconstants.au3>
Opt("GuiOnEventMode", 1)
$hwnd = GUICreate("Test", 300, 300,-1,-1,$WS_POPUP,$WS_EX_LAYERED)
Guisetbkcolor(0xFFFFFF)
_WinAPI_SetLayeredWindowAttributes($hwnd,0xFFFFFF,255)
GUISetState()
GUISetOnEvent(-3, "close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(300, 300, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$pen = _GDIPlus_PenCreate(0xFF00FF00, 2)

InetGet("http://msp5.photobucket.com/albums/y196/dannydude182/smiley-300x300.png",@ScriptDir&"\smiley.png")

$image=_GDIPlus_ImageLoadFromFile(@ScriptDir&"\smiley.png")

$matrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($matrix, 150, 150)



$inc = 0
Do
    _GDIPlus_GraphicsClear($backbuffer,0xffffffff)

    _GDIPlus_MatrixRotate($matrix,1)
    _GDIPlus_GraphicsSetTransform($backbuffer,$matrix)

    _GDIPlus_GraphicsDrawImageRect($backbuffer,$image,-150,-150,300,300)


    _GDIPlus_GraphicsDrawImageRect($graphics,$bitmap,0,0,300,300)
    Sleep(10)
Until 0


Func close()
    Exit
EndFunc  ;==>close


;~ Func _GDIPlus_MatrixTranslate($hMatrix, $nOffsetX, $nOffsetY, $fOrder = True)
;~     $aResult = DllCall($ghGDIPDll, "int", "GdipTranslateMatrix", "ptr", $hMatrix, "float", $nOffsetX, "float", $nOffsetY, "int", $fOrder)
;~     If @error Then Return SetError(@error, @extended, False)
;~     Return SetError($aResult[0], 0, $aResult[0] = 0)
;~ EndFunc  ;==>_GDIPlus_MatrixTranslate

Share this post


Link to post
Share on other sites

thanks again, i will do some tests with your 2nd example.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Hera a small modification from monoscout999's 2nd example:

#include <GDIPlus.au3>
#include <winapi.au3>
#include <windowsconstants.au3>
Opt("GuiOnEventMode", 1)

If Not FileExists(@ScriptDir&"\smiley.png") Then InetGet("http://msp5.photobucket.com/albums/y196/dannydude182/smiley-300x300.png",@ScriptDir&"\smiley.png")
_GDIPlus_Startup()
$image=_GDIPlus_ImageLoadFromFile(@ScriptDir&"\smiley.png")
$w = _GDIPlus_ImageGetWidth($image)
$h = _GDIPlus_ImageGetHeight($image)
$dx = -12
$hwnd = GUICreate("Test",$w,$h,$dx,-1,$WS_POPUP,$WS_EX_LAYERED)
Guisetbkcolor(0)
_WinAPI_SetLayeredWindowAttributes($hwnd,0,255)
GUISetState()
GUISetOnEvent(-3, "close")
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($w,$h, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)

$matrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($matrix, $w/2,$h/2)

$inc = 0
$d = 1
$x = $dx
$max_x = @DesktopWidth - $w + 12
Do
    _GDIPlus_GraphicsClear($backbuffer,0xFF000000)

    _GDIPlus_MatrixRotate($matrix,$d)
    _GDIPlus_GraphicsSetTransform($backbuffer,$matrix)

    _GDIPlus_GraphicsDrawImageRect($backbuffer,$image,-$w/2,-$h/2,$w,$h)

    _GDIPlus_GraphicsDrawImageRect($graphics,$bitmap,0,0,$w,$h)

    WinMove($hwnd, "", $x, $h/2)
    $x += 1 * $d
    If $x < $dx Or $x > $max_x Then $d *= -1
    Sleep(20)
Until 0


Func close()
    _GDIPlus_MatrixDispose($matrix)
    _GDIPlus_ImageDispose($image)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc  ;==>close

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

Share this post


Link to post
Share on other sites

Amazing as always! welcome back UEZ!

Share this post


Link to post
Share on other sites

ok volks, here is another mod:

#include <GDIPlus.au3>
#include <WindowsConstants.au3>

Opt("GuiOnEventMode", 1)
_GDIPlus_Startup()
$image= _GDIPlus_ImageLoadFromFile(FileOpenDialog("Image", @WindowsDir & "\", "Images (*.jpg;*.bmp;*.gif;*.png)", 1 ))
$width = _GDIPlus_ImageGetWidth($image)
$height = _GDIPlus_ImageGetHeight($image)
$maxwidth = 800
$maxheight = 600
$xa = $width / $maxwidth
$i = $maxwidth
while $height / $xa > $maxheight
    $i -= 1
    $xa = $Width / $i
wend
$Width2 = $Width
$Height2 = $Height
if $Width > $maxwidth or $Height > $maxheight then
    $Width2 = int($Width / $xa)
    $Height2 = int($Height / $xa)
endif
$diagonal = sqrt(($Width2*$Width2)+($Height2*$Height2))

$hwnd = GUICreate("Test", $diagonal, $diagonal+20, -1, -1, -1, $WS_EX_LAYERED)
GUISetOnEvent(-3, "close")
$slider = GUICtrlCreateSlider(0, $diagonal, $diagonal, 20)
GUICtrlSetLimit(-1, 360, 0)
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($diagonal, $diagonal, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
GUISetState()
Guisetbkcolor(0x010101)
_WinAPI_SetLayeredWindowAttributes($hwnd,0x010101,255)
;start. this part converts large inputimages to a tempimage with §maxwidth and $maxheight
;its more resource-friendly for matrix operations
$hBitmap1 = _WinAPI_CreateBitmap($Width2, $Height2, 1, 32)
$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
$backbuffer1 = _GDIPlus_ImageGetGraphicsContext($hImage1)
_GDIPlus_GraphicsDrawImageRect($backbuffer1, $Image, 0, 0, $Width2, $Height2)
_GDIPlus_ImageSaveToFile($hImage1, @ScriptDir&"\rotatest.png")
_GDIPlus_BitmapDispose($hImage1)
_WinAPI_DeleteObject ($hBitmap1)
$image3= _GDIPlus_ImageLoadFromFile(@ScriptDir&"\rotatest.png")
;end.
$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($matrix, round($diagonal/2), round($diagonal/2))
$angle = 1
Do
    Sleep(20)
    if $angle <> GUICtrlRead($slider) then
        $matrix = _GDIPlus_MatrixCreate()
        _GDIPlus_MatrixTranslate($matrix, round($diagonal/2), round($diagonal/2))
        _GDIPlus_GraphicsClear($backbuffer, 0xFF010101)
        _GDIPlus_MatrixRotate($matrix,GUICtrlRead($slider))
        _GDIPlus_GraphicsSetTransform($backbuffer,$matrix)
        _GDIPlus_GraphicsDrawImageRect($backbuffer,$image3,-round($Width2/2),-round($Height2/2),$Width2,$Height2)
        _GDIPlus_GraphicsDrawImageRect($graphics,$bitmap,0,0,$diagonal,$diagonal)
        $angle = GUICtrlRead($slider)
    endif
Until 0

Func close()
    Exit
EndFunc  ;==>close

this example shows how i use it in my application.

An additional question: Is it possible to rotate a string??

#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GuiOnEventMode", 1)

_GDIPlus_Startup()
$kPen = _GDIPlus_BrushCreateSolid(0xff000000)
$bg = _GDIPlus_BrushCreateSolid(0xffffffff)
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate ($hFamily, 20, 0)
$hFormat = _GDIPlus_StringFormatCreate ()
$tt = GUICreate("test", 200, 100, -1, -1, -1, $WS_EX_LAYERED)
GUISetOnEvent(-3, "close")
GUISetBkColor(0x010101)
GUISetState()
_WinAPI_SetLayeredWindowAttributes($tt, 0x010101)
$tGraphic = _GDIPlus_GraphicsCreateFromHWND($tt)
$ttLayout = _GDIPlus_RectFCreate(0, 0, 200, 100)
;_GDIPlus_GraphicsFillRect($tGraphic, 0, 0, DllStructGetData($aInfo[0],3), DllStructGetData($aInfo[0],4), $bg)
_GDIPlus_GraphicsDrawStringEx ($tGraphic, "Hello World!", $hFont, $ttLayout, $hFormat, $kPen)

Do
    Sleep(20)
Until 0

Func close()
    Exit
EndFunc  ;==>close

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Of course it is possible to rotate a string. Just write the text to the bitmap and rotate the bitmap (backbuffer) afterwards.

To rotate each letter is a little more complicated - have a look to Ballet of Letters (#30).

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

Share this post


Link to post
Share on other sites

Of course it is possible to rotate a string. Just write the text to the bitmap and rotate the bitmap (backbuffer) afterwards.

To rotate each letter is a little more complicated - have a look to Ballet of Letters (#30).

Br,

UEZ

how has the second example from my post above to be modified for rotating its string?

because there is just a string without any bitmap.

sorry if the question seems "dumb",

i am not too lazy to try it by myself but after the last 2 days of nonstop-coding i need a timeout :)

got headaches just now.....

Share this post


Link to post
Share on other sites

how has the second example from my post above to be modified for rotating its string?

.....

Your second example has this added to it.

; --------- Added Rotate ------------------
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix, 50,0)
_GDIPlus_MatrixRotate($hMatrix, 45)
_GDIPlus_GraphicsSetTransform($tGraphic, $hMatrix)
; -------> End of Added Rotate ----------

Resulting in this.

#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GuiOnEventMode", 1)

_GDIPlus_Startup()
$kPen = _GDIPlus_BrushCreateSolid(0xff000000)
$bg = _GDIPlus_BrushCreateSolid(0xffffffff)
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate($hFamily, 20, 0)
$hFormat = _GDIPlus_StringFormatCreate()
$tt = GUICreate("test", 200, 100, -1, -1, -1, $WS_EX_LAYERED)
GUISetOnEvent(-3, "close")
GUISetBkColor(0x010101)
GUISetState()
_WinAPI_SetLayeredWindowAttributes($tt, 0x010101)
$tGraphic = _GDIPlus_GraphicsCreateFromHWND($tt)

; --------- Added Rotate ------------------
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($hMatrix, 50, 0)
_GDIPlus_MatrixRotate($hMatrix, 45)
_GDIPlus_GraphicsSetTransform($tGraphic, $hMatrix)
; -------> End of Added Rotate ----------

$ttLayout = _GDIPlus_RectFCreate(0, 0, 200, 100)
;_GDIPlus_GraphicsFillRect($tGraphic, 0, 0, DllStructGetData($aInfo[0],3), DllStructGetData($aInfo[0],4), $bg)
_GDIPlus_GraphicsDrawStringEx($tGraphic, "Hello World!", $hFont, $ttLayout, $hFormat, $kPen)

Do
    Sleep(20)
Until 0

Func close()
    Exit
EndFunc   ;==>close

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  
Followers 0