GDI+ Image Rotator and Saver

  • Hi,

    ich hatte letztens von einem User aus einem anderen Forum eine Anfrage, wie man ein Bild drehen kann und dieses anschließend speichert.

    Spoiler anzeigen
    [autoit]


    ;Coded by UEZ 2009.12.23
    #include <GUIConstantsEx.au3>
    #include <GDIplus.au3>
    #include <SliderConstants.au3>
    #Include <GuiStatusBar.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>

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

    Opt('MustDeclareVars', 1)

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

    Global $file, $msg

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

    Do
    $file = FileOpenDialog("Select Image to load", @ScriptDir, "Images (*.jpg;*.png; *.bmp;*.gif)")
    If @error Then
    $msg = MsgBox(20, "Error", "Please select an image!")
    If $msg = 7 Then
    Exit
    Else
    SetError(1)
    EndIf
    EndIf
    Until Not @error
    Global $dll = DllOpen("user32.dll")
    Global $date, $nMsg, $d, $date, $path, $suffix, $sCLSID
    Global $encoder = "PNG"
    _GDIPlus_Startup()
    Global $hImage = _GDIPlus_BitmapCreateFromFile($file)
    Global $iX = _GDIPlus_ImageGetWidth($hImage)
    Global $iY = _GDIPlus_ImageGetHeight($hImage)
    Global $hwnd = GUICreate("GDI+ Image Rotation by UEZ 2009", $iX + 200, $iY + 80, -1, -1)
    Global $Button1 = GUICtrlCreateButton("Rotate_Image", $iX + 63, 36, 75, 25)
    Global $Button2 = GUICtrlCreateButton("Save Image", $iX + 63, 92, 75, 25)
    GUICtrlSetTip($Button2, "Image will be saved to " & @ScriptDir)
    Global $Button3 = GUICtrlCreateButton("Exit", $iX + 63, $iY + 12, 75, 25)
    Global $Input1 = GUICtrlCreateInput("", $iX + 63, 10, 73, 21)
    GUICtrlSetTip($Input1, "Enter degree -359° - 359° here")
    Global $Label = GUICtrlCreateLabel("Degree:", $iX + 20, 12, 40, 17)
    Global $Slider = GUICtrlCreateSlider(10, $iY + 10, $iX - 10, 40, $TBS_AUTOTICKS + $TBS_ENABLESELRANGE)
    GUICtrlSetTip($Slider, "-90° to 90°")
    GUICtrlSetLimit($Slider, 90, -90)
    GUICtrlSetData($Slider, 0)
    Dim $aParts[4] = [106, 148, 250, -1]
    Global $StatusBar = _GUICtrlStatusBar_Create($hwnd, $aParts)
    GUISetState()
    _GUICtrlStatusBar_SetText($StatusBar, "Degree from Slider:", 0)
    _GUICtrlStatusBar_SetText($StatusBar, "Image Dimension:", 2)
    _GUICtrlStatusBar_SetText($StatusBar, $iX & " x " & $iY, 3)
    Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hwnd)
    Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphic)
    Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Global $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, $iX / 2, $iY / 2)
    Rotate_Image(0)

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

    $d = GUICtrlRead($Slider)
    _GUICtrlStatusBar_SetText($StatusBar, $d & "° ", 1)
    While Sleep(30)
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE, $Button3
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    DllClose($dll)
    Exit
    Case $Button1
    $d = GUICtrlRead($Input1)
    If StringIsInt($d) Then
    Rotate_Image(Int($d))
    Else
    MsgBox(16, "Error", "Please enter an integer from -359 - 359!")
    EndIf
    Case $Button2
    $sCLSID = _GDIPlus_EncodersGetCLSID ($encoder)
    $path = @ScriptDir & "\Saved_"
    $date = @YEAR & "-" & @MON & "-" & @MDAY & "_" & @HOUR & @MIN & @SEC
    $suffix = "." & StringLower($encoder)
    _GDIPlus_Save_to_Image($path & $date & $suffix, $hwnd, $encoder, $iX, $iY)
    If Not @error Then
    MsgBox(0, "Information", "Image successfully save to: " & $path & $date & $suffix)
    Else
    MsgBox(16, "Error", "Image could not be saved!")
    EndIf
    Case $Slider, _IsPressed("01")
    $d = GUICtrlRead($Slider)
    _GUICtrlStatusBar_SetText($StatusBar, $d & "° ", 1)
    Rotate_Image(Int($d))
    EndSwitch
    WEnd

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

    Func Rotate_Image($degree)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)
    _GDIPlus_MatrixRotate($hMatrix, $degree, "False")
    _GDIPlus_GraphicsSetTransform($hBackbuffer, $hMatrix)
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hImage, -$iX / 2, -$iY / 2, $iX, $iY)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iX, $iY)
    EndFunc

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

    ; #FUNCTION# =============================================================================
    ; Name...........: _GDIPlus_Save_to_Image
    ; Description ...: INTERNAL FUNCTION - save drawn image to file
    ; Syntax.........: _GDIPlus_Save_to_Image($file, $hWnd, $CLSID, $w, $h)
    ; Parameters ....: $file - filename
    ; $hWnd - handle to GUI
    ; Autor .........: ptrex, ProgAndy, UEZ
    ; =========================================================================================
    Func _GDIPlus_Save_to_Image($file, $hWnd, $CLSID = "PNG", $w = 0, $h = 0)
    Local $hDC, $memBmp, $memDC, $hImage, $size, $sCLSID
    If $file <> "" Or $hWnd <> "" Then
    If $w = 0 Or $h = 0 Then
    $size = WinGetClientSize($hWnd)
    $w = $size[0]
    $h = $size[1]
    EndIf
    $hDC = _WinAPI_GetDC($hWnd)
    $memDC = _WinAPI_CreateCompatibleDC($hDC)
    $memBmp = _WinAPI_CreateCompatibleBitmap($hDC, $w, $h)
    _WinAPI_SelectObject ($memDC, $memBmp)
    _WinAPI_BitBlt($memDC, 0, 0, $w, $h, $hDC, 0, 0, 0x00CC0020) ; 0x00CC0020 = $SRCCOPY
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP ($memBmp)
    $sCLSID = _GDIPlus_EncodersGetCLSID ($CLSID)
    _GDIPlus_ImageSaveToFileEx ($hImage, $file, $sCLSID)
    If @error Then
    Return SetError(1, 0, 0)
    Else
    Return SetError(0, 0, 0)
    EndIf
    _GDIPlus_ImageDispose ($hImage)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($memDC)
    _WinAPI_DeleteObject ($memBmp)
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndFunc

    [/autoit]


    Es ist nicht besonderes, aber vielleicht ist es ja für irgend jemanden mal nützlich! Vielleicht gibt es ja solche Beispiele hier in diesem Forum ohne Ende...

    @Hamburger: Wolltest du sowas haben :D

    Gruß,
    UEZ

    Edit: Hab's ein bißchen angepasst

  • Cooles Script, hatte mich daran auch schonmal versucht:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <ScreenCapture.au3>
    #include <WinAPI.au3>

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

    _Rotate90(@WindowsDir&"\Angler.bmp",@ScriptDir&"\new.bmp")

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

    Func _Rotate90($ZielImage,$ZielPfad)
    _GDIPlus_Startup()

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

    $hImage2 = _GDIPlus_BitmapCreateFromFile($ZielImage)
    $Width = _GDIPlus_ImageGetWidth($hImage2)
    $Height = _GDIPlus_ImageGetHeight($hImage2)
    $hBitmap1 = _ScreenCapture_Capture("",0,0,$height,$width)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)

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

    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix,$height*2,-$width)
    _GDIPlus_MatrixRotate($hMatrix, 90, "False")
    _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage2, $width, $height)

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

    $result = _GDIPlus_ImageSaveToFile($hImage1, $ZielPfad)

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

    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _WinAPI_DeleteObject($hBitmap1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Return $result
    EndFunc

    [/autoit]

    Aber leider geht das komischerweise nicht bei allen Bildern.

    Nützliches Script, danke ;)

  • ... hatte mich daran auch schonmal versucht:

    Weiß ich ;)

    Zitat


    Aber leider geht das komischerweise nicht bei allen Bildern.

    Meinst du dein Programm?

    Bei meinem Programm werden mache Bilder gestreckt angezeigt. Ich weiß nicht warum!

    Zitat


    Nützliches Script, danke ;)

    Bitte!

    Das Skript habe ich auf die Schnelle erstellt, d.h. es können noch Fehler enthalten sein!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Jetzt wo du es sagt, es sind genau die selben Bilder bei deinen sowohl meins als auch deins nicht geht, bzw. Fehler enthalten, sehr komisch.

    Der Work-Around ist _GDIPlus_GraphicsDrawImageRect() anstelle von _GDIPlus_GraphicsDrawImage() zu benutzen! Ich weiß nicht, warum einige Bilder mit _GDIPlus_GraphicsDrawImage() gestreckt angezeigt werden! ?(

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯