GDI-Bilder Drehen

  • Hi,
    ich habe leider keine Ahnung von GDI+.
    Ich brauch eine Funktion, die mein Bild um eine Bestimmt Gradzahl drehen kann.
    Das Funktioniert ja mit _GDIPlus_Matrix...
    So wie ich das bis jetzt Verstanden hab dreht man den Hintergrund des Bildes und zeichnet auf den gedrehten Hintergrund das Bild drauf. Wenn der Hintergrund jetzt wieder gerade ist, ist das draufgezeichnete Bild logischerweise gedreht.

    Allerdings weis ich nicht, wie man einen leeren Hintergrund erstellt. Weil ich ja eigentlich nur ein einziges Bild drehen will.

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\leer.jpg") ; <-- leerer Hintergrund
    $hImage2 = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\test.jpg")

    [/autoit] [autoit][/autoit] [autoit]

    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixRotate($hMatrix, 5, "False")
    _GDIPlus_GraphicsSetTransform($hImage, $hMatrix)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hImage, $hImage2, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_ImageSaveToFile($hImage, @MyDocumentsDir & "\GDIPlus_Image.jpg")

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_Shutdown()

    [/autoit]

    Das funktioniert logischerweise nicht :D.
    Kann mir vielleicht mal schnell jemand auf die Sprünge Helfen?

    Danke :)
    anno2008

    Einmal editiert, zuletzt von anno2008 (28. September 2009 um 17:26)

  • Hallo anno2008,

    dieses Beispiel aus der Hilfe sollte dir weiterhelfen:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("Test Rotate", 800, 600)
    GUISetState()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)

    [/autoit] [autoit][/autoit] [autoit]

    $hImage = _GDIPlus_ImageLoadFromFile(@WindowsDir & "\Angler.bmp")
    $iWidth = _GDIPlus_ImageGetWidth($hImage) * 96 / _GDIPlus_ImageGetVerticalResolution($hImage)
    $iHeight = _GDIPlus_ImageGetHeight($hImage) * 96 / _GDIPlus_ImageGetHorizontalResolution($hImage)

    [/autoit] [autoit][/autoit] [autoit]

    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, 400, 300)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_MatrixRotate($hMatrix, 90, "False")
    _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, -$iWidth / 2, -$iHeight / 2)

    [/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    GUIRegisterMsg ( 0x000F, "my_wm_paint" )
    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    Func my_wm_paint()
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, -$iWidth / 2, -$iHeight / 2)
    EndFunc

    [/autoit]

    mfg (Auto)Bert

    • Offizieller Beitrag

    Oder so:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit]

    _Main()

    [/autoit] [autoit][/autoit] [autoit]

    Func _Main()
    Local $hGUI, $file, $hImage1, $hGraphic, $width, $height
    $hGUI = GUICreate("GDI+", 600, 400)
    GUISetState()
    _GDIPlus_Startup()
    $file = @SystemDir & '\oobe\images\mslogo.jpg'
    $hImage1 = _GDIPlus_BitmapCreateFromFile($file)
    $width = _GDIPlus_ImageGetWidth($hImage1)
    $height = _GDIPlus_ImageGetHeight($hImage1)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    ;DrawInsert($hGraphic, $hImage2, $iX, $iY, $nAngle, $iWidth, $iHeight, $iARGB = 0xFF000000, $nWidth = 1)
    DrawInsert($hGraphic, $hImage1, 150, 10, 20, $width + 2, $height + 2, 0xFFFF8000, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = -3
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Main

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ==================================================================================================
    ;Name...........: DrawInsert
    ; Description ...: Draw one image in another
    ; Syntax.........: DrawInsert($hGraphic, $hImage2, $iX, $iY, $nAngle, $iWidth, $iHeight, $iARGB = 0xFF000000, $nWidth = 1)
    ; inserts Graphics $hImage2 into $hGraphic
    ; Parameters ....: $hGraphics - Handle to a Graphics object
    ; $hImage - Handle to an Image object to be inserted
    ; $iX - The X coordinate of the upper left corner of the inserted image
    ; $iY - The Y coordinate of the upper left corner of the inserted image
    ; $iWidth - The width of the rectangle Border around insert
    ; $iHeight - The height of the rectangle Border around insert
    ; $iARGB - Alpha, Red, Green and Blue components of pen color - Border colour
    ; $nWidth - The width of the pen measured in the units specified in the $iUnit parameter - Border Width

    [/autoit] [autoit][/autoit] [autoit]

    ; Return values .: Success - True
    ; Failure - False
    ;==================================================================================================
    Func DrawInsert($hGraphic, $hImage2, $iX, $iY, $nAngle, $iWidth, $iHeight, $iARGB = 0xFF000000, $nWidth = 1)
    Local $hMatrix, $hPen2

    [/autoit] [autoit][/autoit] [autoit]

    ;Rotation Matrix
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixRotate($hMatrix, $nAngle, "False")
    _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage2, $iX, $iY)

    [/autoit] [autoit][/autoit] [autoit]

    ;get pen + color
    $hPen2 = _GDIPlus_PenCreate($iARGB, $nWidth)

    [/autoit] [autoit][/autoit] [autoit]

    ; Draw a frame around the inserted image
    _GDIPlus_GraphicsDrawRect($hGraphic, $iX, $iY, $iWidth, $iHeight, $hPen2)

    [/autoit] [autoit][/autoit] [autoit]

    ; Clean up resources
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_PenDispose($hPen2)
    Return 1
    EndFunc ;==>DrawInsert

    [/autoit]
  • Hi,
    ja, ich hab beide Beispiele gesehn. Ich will das Bild aber nicht in der GUI anzeigen lassen, sondern es als gedrehtes Bild abspeichern. Deshalb brauch ich ja ein "leeres" Bild, aber nicht die GUI, das ich drehen kann und das andere dann draufzeichnen kann. Ich weis aber leider nicht wie das geht und weil ich mit GDI+ noch nie was großes gemacht hab finde ich auch den Befehl gerade nicht.

  • Das nutzt mir überhaupt nix. Kann mir vielleicht nicht einfach mal jemand ein Script geben?
    Bei _GDIPlus_ImageSaveToFile werden die Daten von einem Screenshot bezogen. Ich brauch ein leeres Bild oder sowas.

  • Sry, das ist wohl schwerer als ich gedacht habe.
    Ich verstehe einfach nicht, wie man den "Hintergrund" auf die richtige Größe bringen kann, weil das Bild ja durch das drehen in Breite und Höhe größer oder auch kleiner werden kann.
    Gibt es vielleicht eine bessere Möglichkeit ein Bild zu drehen?

  • Hallo Anno2008,
    du brauchst keine GUI um das Bild zu drehen, und auch kein "leeres" Bid.
    Ablauf:
    -Die Daten aus deiner Bitmap clonen
    -Aus der Bitmap ein Graphiccontext machen (Leinwand), in das man zeichnen kann
    -Matrix vorbereiten und drehen
    -Clone in den Context zeichnen (dabei wird er gedreht)
    -Leinwand speichern

    Spoiler anzeigen
    [autoit]

    #include <GDIPlusConstants.au3>
    #include <GDIPlus.au3>
    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hGUI, $file, $hImage1, $hGraphic, $width, $height, $hmatrix, $image1, $hclone
    $hGUI = GUICreate("GDI+", 600, 400)
    GUISetState()
    _GDIPlus_Startup()
    $file = @SystemDir & '\oobe\images\mslogo.jpg'
    $hImage1 = _GDIPlus_BitmapCreateFromFile($file)
    $width = _GDIPlus_ImageGetWidth($hImage1)
    $height = _GDIPlus_ImageGetHeight($hImage1)
    $hClone = _GDIPlus_BitmapCloneArea($hImage1, 0, 0, $width, $height, $GDIP_PXF24RGB) ;bild clonen

    $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1) ; aus dem img eine graphicscontext machen, damit man auf der "leinwand" auch zeichnen kann

    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixRotate($hMatrix, 3, "False") ;3 grad drehen
    _GDIPlus_GraphicsSetTransform($hgraphic, $hMatrix) ;bitmap vorbereiten

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hgraphic, $hclone, 0,0) ;clone in die Bitmap zeichnen

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_ImageSaveToFile($himage1, @scriptdir&"\gedreht_Image.jpg")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_ImageDispose ($hImage1)
    _WinAPI_DeleteObject ($hclone)
    _WinAPI_DeleteObject ($hgraphic)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()

    [/autoit]

    */EDIT/* du hast schon gemerkt, daß man beim Drehen aufpassen muss, grosse Winkel gehen nicht "auf einmal" , sondern man muss ggf mehrmals drehen und dabei den Mittelpunkt der Drehung anpassen

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (27. September 2009 um 19:30)

  • Hallo,
    danke für deine Antwort.
    Das ist ein Ansatz. Du benutzt als Hintergrund jetzt das original Bild und zeichnest das geklonte darüber. Allerdings soll der Hintergrund ja weiß sein, weil ich nur das Bild an sich drehen will.
    Also brauch ich im Prinzip doch ein "leeres Bild", auf dass ich das Originalbild Zeichnen kann. Aber ein noch größeres Problem hab ich damit die Größe anzupassen. Dadurch, dass ich das Bild oben links drehe wird das Gesamtbild breiter. Wenn ich wüsste wie man das "leere Bild" erstellen kann, könnte ich ausrechnen, wie breit und hoch das neue Bild sein muss, damit das Bild dann reinpasst.

    autoit.de/wcf/attachment/6194/
    autoit.de/wcf/attachment/6193/

    So soll sich das verändern.

  • aaahhhh, jetzt wirds hell^^
    Ja natürlich musst du dann ein entsprechend grösseres Bild erstellen, das bissl Fingerabzählen wg der Größe sollte aber kein Problem sein^^
    Als "Hintergrund" nimmst du dann einfach ein GUI-Fenster (nicht angezeigt) in der entsprechenden Größe.