Jump to content

Rotating an image from a custom origin with overlaying other image


Recommended Posts

Hi guys, 

I saw in a post #6 in the topic mentioned below, that you posted a way to rotate an image.

I'm trying to rotate similat image, a niddle, but I want to rotate it in a specific anchor/origin point (it's base), so it can be a niddle of a speed meter I'm trying to make. 

My niddle has the width=40, height = 9, location on he speed meter: left=291, top=352. I need the anchor to be at (Left,Top) = (325,357), as the speed meter located by:

Global $OriginX = 325
Global $OriginY = 357
$SpeedMeterGause =  GUICtrlCreatePic("C:\Users\salon\Pictures\speedomete.gif", 280, 312, 90, 90); meter dimentions 90x90
$SpeedMeterNiddle = GUICtrlCreatePic("C:\Users\salon\Pictures\Niddle.jpg",  291, 352, 40, 9) ;custom location of the niddle, dim 40x9

I want the niddle to be able to rotate all over the meter, from let's say, angles of -45 degrees (represents minimum) to 270 degrees (maximum).

Attached a picture of the speed meter on the lower-right corner of the GUI, and the script itself.

Is it possible?

Thanks!!!

 

 

speedometer.png

Load Menu.au3

Link to comment
Share on other sites

14 hours ago, junkew said:

 

 

Hi @junkew,

I'm looking to rotate an image on top of other image, when the rotation point is not the center of the image, but the far end middle of it:
For example: My niddle is 40x9 (WxH), and it's located on (100,100), I want the rotation point to be on (100+40,100+9/2), and not (100+40/2,100+9/2) as the center of the image.

 

Link to comment
Share on other sites

Have a look here:

 

Please ask if you have any question.

 

Meanwhile I will write an example how to rotate a bitmap needle.

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

Here a basic example how a rotation of a transparent needle can be done.

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

Global Const $iWidth = 300, $iHeight = 200
Global Const $hGUI = GUICreate("GDI+ Needle Rotation Example", $iWidth, $iHeight)
GUISetState()

_GDIPlus_Startup()
;create buffered graphic handle to display final drawn image
Global Const $hCanvas = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global Const $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hCanvas)
Global Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hGfx, 4)

;load needle from memory
Global Const $hImage = _GDIPlus_BitmapCreateFromMemory(_Zeiger())

;create a new image with squared dimension of the loaded needle bitmap and place the needle center in the middle
Global Const $iNeedleCenterX = 25, $iNeedleCenterY = 8, $iImageWidth = 117, $iImageHeight = 17, $iNeedleWidth = 2 * ($iImageWidth - $iNeedleCenterX), $iNeedleHeight = $iNeedleWidth
Global Const $hImage_Needle = _GDIPlus_BitmapCreateFromScan0($iNeedleWidth, $iNeedleHeight)
Global Const $hCtxt = _GDIPlus_ImageGetGraphicsContext($hImage_Needle)
_GDIPlus_GraphicsDrawImageRect($hCtxt, $hImage, $iNeedleWidth / 2 - $iNeedleCenterX, $iNeedleHeight / 2 - $iNeedleCenterY, $iImageWidth, $iImageHeight)


Global Const $fRadius = $iImageWidth - $iNeedleCenterX, $fCenterScreenX = $iWidth / 2, $fCenterScreenY = $iHeight / 2 - 30

Global $fAngle = 0, $iDir = 1

Global Const $hBrush = _GDIPlus_LineBrushCreate(0, 0, $fRadius, $fRadius, 0xFFFF0000, 0xFF00FF00, 1)

Do
    ;do some animation
    _GDIPlus_GraphicsClear($hGfx)
    RotateNeedle($fAngle)
    $fAngle += 0.5 * $iDir
    If BitOR($fAngle < 0, $fAngle > 180) Then $iDir *= -1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_BrushDispose($hBrush)
            _GDIPlus_GraphicsDispose($hCanvas)
            _GDIPlus_GraphicsDispose($hGfx)
            _GDIPlus_GraphicsDispose($hCtxt)
            _GDIPlus_BitmapDispose($hBitmap)
            _GDIPlus_BitmapDispose($hImage_Needle)
            _GDIPlus_ImageDispose($hImage)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
    EndSwitch

Until False

Func RotateNeedle($fAngle)
    ;draw a dummy background
    Local Const $hPath = _GDIPlus_PathCreate()
    _GDIPlus_PathAddArc($hPath, $fCenterScreenX - $fRadius, $fCenterScreenY, 2 * $fRadius, 2 * $fRadius, 180, 180)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)
    _GDIPlus_PathDispose($hPath)

    ;create a new bitmap
    Local Const $hBmp = _GDIPlus_BitmapCreateFromScan0($iNeedleWidth, $iNeedleHeight)
    Local Const $hContext = _GDIPlus_ImageGetGraphicsContext($hBmp)
    _GDIPlus_GraphicsSetPixelOffsetMode($hContext, 2)

    ;create a matrix handle to rotate bitmap
    Local Const $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, $fRadius, $fRadius)
    _GDIPlus_MatrixRotate($hMatrix, -180 + $fAngle)
    _GDIPlus_GraphicsSetTransform($hContext, $hMatrix)
    _GDIPlus_MatrixTranslate($hMatrix, -$fRadius, -$fRadius)
    _GDIPlus_GraphicsSetTransform($hContext, $hMatrix)

    ;copy needle to the rotated bitmap
    _GDIPlus_GraphicsDrawImageRect($hContext, $hImage_Needle, 0, 0, $iNeedleWidth, $iNeedleHeight)

    ;copy result to our main graphic content
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBmp, $fCenterScreenX - $fRadius, $fCenterScreenY - 10, $iNeedleWidth, $iNeedleHeight)
    _GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap, 0, 0, $iWidth, $iHeight)

    ;release resources within this function to avoid memory leak
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_ImageDispose($hBmp)
EndFunc


;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2015-09-19

Func _Zeiger($bSaveBinary = False, $sSavePath = @ScriptDir)
    Local $Zeiger
    $Zeiger &= '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'
    $Zeiger &= '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'
    $Zeiger &= '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'
    $Zeiger &= 'oECslVar9YZSOjLGiFKxdgkRCquVFqWUUlrZ2U9P/guwxJjXdV3J5/PRsaPH3jn41sEZoOVYa1lYWODkyVlarVbKIwsi6XZN6EGn08Ha7oKkNhlFlk5nOS6wRQRBiLUR2WyWoaFByqOjlEdGKJVKZLNZjh49Rq1WIwgCMpls75L6eblQ5TDRtRW+pQ8Vro44ibKkS0oJZk6vT8+dn4c07iZOPJzptRKndAkozjl2JLlCP3Zf+f7qUpLWGs/z8P0OW6an+fqdd1LwCzjAi512u3riRF0brXubU9qSstM13JeIstZWRCSvtSIIApaWFgnDoGcRAwMDbBrcxMjwMOVymXK5jF/08TwPYxwe+d0jzcVWa74xM9NUSkvaAaquMEMbycKaXHxWrAJEgtgLYQfV/UAvJT+Hi44USlL6taY0xEpTRM6Vw6TDxoVwTDocqL7UfK11yfkd4BTwsaNE3Q1kbGiVxa4XVEWp/F852smfbZ79g1K5e7ReRkRYXl7GGEM2m8E4Br9QIF8okM/ncV2HKLK89uprrcceffx5YL/ruH+NQnsa7EaU3ux5YulFZ0KpR13C3iQ2XzK6v9j4vFHoVwFq/uzc9cAvPS/z7Ww24xrjkMvlKI+WKY+MkMvl6HQ68u7bh/67sLDwotZ6P/AKUK83aiFf0IbQ/wAq4CpjdWoV/AAAAABJRU5ErkJggg=='
    Local $bString = _WinAPI_Base64Decode($Zeiger)
    If @error Then Return SetError(1, 0, 0)
    $bString = Binary($bString)
    If $bSaveBinary Then
        Local Const $hFile = FileOpen($sSavePath & "\tacho_zeiger_max.png", 18)
        If @error Then Return SetError(2, 0, $bString)
        FileWrite($hFile, $bString)
        FileClose($hFile)
    EndIf
    Return $bString
EndFunc   ;==>_Zeiger

Func _WinAPI_Base64Decode($sB64String)
    Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "")
    Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]")
    $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0)
    If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "")
    Return DllStructGetData($bBuffer, 1)
EndFunc   ;==>_WinAPI_Base64Decode

 

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

×
×
  • Create New...