.tif Dateien um 180 Grad drehen

  • Hallo zusammen,

    kennt jemand eine Möglichkeit eine .tif Datei um 180 Grad zu drehen. Ich würde das gerne im Hintergrund laufen lassen, also über nen dll Aufruf z.B.
    Ideal wären Windows-Boardmittel (Bild und Faxanzeige, Paint), da das zukünftige Programm aber nicht auf zu vielen Rechnern laufen wird, wären auch andere Programme verschmerzbar.

    Hintergrund:

    Über unsere MFPs werden Kundendokumente eingescannt, mit entsprechenden Infos werden die .tif Dateien im Netzwerk abgelegt.
    Diese werden dann von 2-3 MItarbeitern über ein selbst geschriebenes Programm eingelesen, welches das Ganze an unser DMS übergibt (hier öffnet sich auch eine Vorschau der Datei, eine Bearbeitung ist aber nicht möglich).

    Sollte ein Mitarbeiter aus Versehen das Dokument auf dem Kopf eingescannt haben, möchte ich das gerne einfach per Script um 180 Grad drehen (Am Besten ohne ein ExtraProgramm aufzurufen und die "Drehen" Taste zu betätigen, das wäre lediglich meine "Notlösung")

    Vielen Dank schonmal für eure Hilfe!

    Einmal editiert, zuletzt von presgomacho (17. Mai 2011 um 13:06)

  • Mit GDI+ auf eine Graphic zeichnen, 180° Rotieren (ich glaube das ist nicht nur optisch... bin mir aber nicht sicher!) und abspeichern.

  • Schau dir das Beispiel in der Hilfe zu der Funktion

    [autoit]

    _GDIPlus_ImageSaveToFileEx

    [/autoit]

    an, da kannst du mit _GDIPlus_ParamAdd erstellte Parameter anhängen. Im Biespiel wird sogar das Bild um 90° gedreht. Das ist der lürzeste und einfachste Weg ein Bild mit GDI+ zu drehen. ;)

  • Mich würde jetzt interessieren ob bei Matrix Rotate nur OPTISCH dir Graphic gedreht wird oder wirklich das Bild darauf, also ob man das Bild dann 180° gedreht speichern kann.

  • Zitat

    Mich würde jetzt interessieren ob bei Matrix Rotate nur OPTISCH dir Graphic gedreht wird oder wirklich das Bild darauf, also ob man das Bild dann 180° gedreht speichern kann.


    Wenn du die Transformation auf den GraphicsContext einer Bitmap anwendest geht das. Ansonsten könntest du das Bild auch gar nicht speichern ;).

  • Hm, okay, danke erstmal an euch.
    Hab mich grad mal ein bisschen mit GDI+ beschäftigt, muss mich da aber erstmal zurecht finden.

    Ich lass den Thread erstmal offen, komm bestimmt noch mit der ein oder anderen Frage auf ecuh zu!

  • Das einfachste ist folgendes (mit GDIP.au3)

    [autoit]

    $hImage = _GDIPLus_ImageLoadFromFile
    _GDIPlus_ImageRotateFlip($hImage, 2)
    _GDIPlus_ImageSaveToFile($hImage
    _GDIPlus_ImageDispose($hImage)

    [/autoit]
    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_ImageRotateFlip
    ; Description ...: Rotates and flips an image
    ; Syntax.........: _GDIPlus_ImageRotateFlip($hImage, $iRotateFlipType)
    ; Parameters ....: $hImage - Pointer to an Image object
    ; $iRotateFlipType - Type of rotation and flip:
    ; |0 - No rotation and no flipping (A 180-degree rotation, a horizontal flip and then a vertical flip)
    ; |1 - A 90-degree rotation without flipping (A 270-degree rotation, a horizontal flip and then a vertical flip)
    ; |2 - A 180-degree rotation without flipping (No rotation, a horizontal flip folow by a vertical flip)
    ; |3 - A 270-degree rotation without flipping (A 90-degree rotation, a horizontal flip and then a vertical flip)
    ; |4 - No rotation and a horizontal flip (A 180-degree rotation followed by a vertical flip)
    ; |5 - A 90-degree rotation followed by a horizontal flip (A 270-degree rotation followed by a vertical flip)
    ; |6 - A 180-degree rotation followed by a horizontal flip (No rotation and a vertical flip)
    ; |7 - A 270-degree rotation followed by a horizontal flip (A 90-degree rotation followed by a vertical flip)
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipImageRotateFlip
    ; Example .......; No
    ; ===============================================================================================================================

    [/autoit]
  • Also,

    folgendermaßen habe ich das Ganze erstmal umgesetzt:

    Spoiler anzeigen
    [autoit]

    _GDIPlus_Startup ()
    $test = _GDIPlus_ImageRotateFlip($hImage, 2)
    _GDIPlus_ImageSaveToFile($hImage,'D:\Test.tif')
    _GDIPlus_ImageDispose($hImage)
    $hImage = _GDIPLus_ImageLoadFromFile('D:\1010_2011_05_13_14_43_41_147.tif')
    MsgBox(0,'',@error)
    _GDIPlus_ShutDown ()

    [/autoit]

    Das funktioniert auch einwandfrei, allerdings wird bei mehrseitigen Dokumenten nur die erste Seite gedreht, die restlichen werden einfach abgeschnitten.
    Wie kann ich denn die anderen Seiten ebenfalls drehen und das Abschneiden verhindern?

    edit name22:

    Hab mir auch die Möglichkeit mit _GDIPlus_ImageSaveToFileEx angeschaut.
    Mit JPG klappts super, mit TIFs leider nicht. In der au3 hab ich folgendes gesehen:
    Global Const $GDIP_EVTTRANSFORMROTATE90 = 13 ; JPEG: Lossless 90 degree clockwise rotation
    Schätze das diese Funktion damit nur mit dem JPG Encoder möglich ist, oder?

    Einmal editiert, zuletzt von presgomacho (17. Mai 2011 um 10:15)

  • Klappt irgendwie aber trotzdem nicht bei mir:

    [autoit]

    _GDIPlus_Startup ()
    $hImage = _GDIPlus_ImageLoadFromFile ('D:\1010_2011_05_13_14_43_41_147.tif')
    ; Get JPEG encoder CLSID
    $sCLSID = _GDIPlus_EncodersGetCLSID ("TIF")
    ; Set up parameters for 90 degree rotation
    $tData = DllStructCreate("int Data")
    DllStructSetData($tData, "Data", $GDIP_EVTTRANSFORMROTATE90)
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))
    ; Save image with rotation
    _GDIPlus_ImageSaveToFileEx ($hImage,'D:\GDIPlus_Image2.tif', $sCLSID, DllStructGetPtr($tParams))
    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()

    [/autoit]

    Allerdings hab ich hier auch wieder das Problem, das mir bei mehrseitigen Dokumenten nach der 1. Seite alles abgeschnitten wird.
    Bin dann noch auf die FreeImage UDF von progandy gestoßen.
    Das Rotieren einer einzelnen Seite geht damit auch sehr gut.
    Hier man kann aber auch MultiPage Dateien öffnen und bearbeiten, allerdings steh ich jetzt ein wenig auf dem Schlauch:
    Nach dem OpenMultiBitMap Befehl weiß ich nicht, wie ich die einzelnen Seite ansprechen soll um die Rotation durchzuführen?

    Hat jemand eine Idee? Oder gibt es eine Möglichkeit mit den bereits vorgestellten Lösungen eine Multi-Page Rotation zu verwirklichen?

    Spoiler anzeigen
    [autoit]

    _FreeImage_LoadDLL(@ScriptDir&"\FreeImage.dll")
    _FreeImage_Initialise()
    $sFile = 'D:\1010_2011_05_13_14_43_41_147.tif'
    $FIF = _FreeImage_GetFileTypeU($sFile)
    If $FIF = $FIF_UNKNOWN Then
    $FIF = _FreeImage_GetFIFFromFilenameU($sFile)
    EndIf
    $hImage = _FreeImage_OpenMultiBitmap($FIF, $sFile, False, False)
    _FreeImage_RotateClassic($hImage, 90)
    _FreeImage_CloseMultiBitmap($hImage, 0)

    [/autoit]
  • Hi

    Hab da was gebastelt:

    Spoiler anzeigen
    [autoit]

    #include <GDIP.au3>
    #include <GDIPlus.au3>
    #include <GDIPlusConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Opt("MustDeclareVars", 1)

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

    _GDIPlus_Startup()

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

    Global $aImage = _LoadMultiPageImage(@ScriptDir & "\MultiPage.Tif")
    If @error Or Not IsArray($aImage) Then
    MsgBox(0, "ERROR", "Mehrseitiges Bild konnte nicht geöffnet werden")
    Exit
    EndIf

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

    Global $iWidth = _GDIPlus_ImageGetWidth($aImage[1]) * 96 / _GDIPlus_ImageGetHorizontalResolution($aImage[1])
    Global $iHeight = _GDIPlus_ImageGetHeight($aImage[1]) * 96 / _GDIPlus_ImageGetVerticalResolution($aImage[1])

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

    Global $hGui = GUICreate("Mehrseitiges Bild", $iWidth, $iHeight)
    GUISetState()
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)

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

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")

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

    For $i = 1 To $aImage[0]
    _GDIPlus_ImageRotateFlip($aImage[$i], 2)
    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $aImage[$i], 0, 0)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    MsgBox(0, "Seite " & $i & "/" & $aImage[0], "Diese Seite wurde um 180° gedreht...")
    Next

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

    _SaveMultiPageImage($aImage, @ScriptDir & "\MultiPage_Rotated.tif")
    If @error Then
    MsgBox(0, "ERROR", "Mehrseitiges Bild konnte nicht gespeichert werden")
    Exit
    EndIf
    MsgBox(0, "", "Mehrseitiges Bild wurde als TIFF gespeichert...")

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

    For $i = 1 To $aImage[0]
    _GDIPlus_BitmapDispose($aImage[$i])
    Next

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

    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()

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

    Func _SaveMultiPageImage($aImage, $sPath)
    If Not IsArray($aImage) Then Return SetError(1, 1, False)
    Local $sExt = __GDIPlus_ExtractFileExt($sPath)
    Local $sCLSID = _GDIPlus_EncodersGetCLSID($sExt)
    If $sCLSID = "" Then Return SetError(1, 2, False)

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

    Local $tData = DllStructCreate("int Data")
    DllStructSetData($tData, "Data", $GDIP_EVTMULTIFRAME)
    Local $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

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

    _GDIPlus_ImageSaveToFileEx($aImage[1], $sPath, $sCLSID, DllStructGetPtr($tParams))

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

    $tParams = _GDIPlus_ParamInit(1)
    DllStructSetData($tData, "Data", $GDIP_EVTFRAMEDIMENSIONPAGE)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

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

    For $i = 2 To $aImage[0]
    _GDIPlus_ImageSaveAddImage($aImage[1], $aImage[$i], DllStructGetPtr($tParams))
    If @error Then Return SetError(1, $i + 1, False)
    Next

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

    Return True
    EndFunc ;==>_SaveMultiPageImage

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

    Func _LoadMultiPageImage($sPath)
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPath)
    If @error Then Return SetError(1, 1, False)
    Local $iCount = _GDIPlus_ImageGetFrameDimensionsCount($hImage)
    If Not $iCount Then Return SetError(1, 2, False)
    Local $aList = _GDIPlus_ImageGetFrameDimensionsList($hImage)
    If @error Or Not IsArray($aList) Then Return SetError(1, 3, False)

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

    Local $iPixelFormat, $iImageW, $iImageH
    Local $aReturn[1], $iCnt = 0
    For $i = 1 To $aList[0]
    $iCount = _GDIPlus_ImageGetFrameCount($hImage, $aList[$i])
    For $j = 1 To $iCount
    _GDIPlus_ImageSelectActiveFrame($hImage, $aList[$i], $j)
    $iCnt += 1
    ReDim $aReturn[$iCnt + 1]
    $iPixelFormat = _GDIPlus_ImageGetPixelFormat($hImage)
    $iImageW = _GDIPlus_ImageGetWidth($hImage)
    $iImageH = _GDIPlus_ImageGetHeight($hImage)
    $aReturn[$iCnt] = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iImageW, $iImageH, $iPixelFormat)
    Next
    Next
    _GDIPlus_ImageDispose($hImage)
    $aReturn[0] = $iCnt
    Return $aReturn
    EndFunc ;==>_LoadMultiPageImage

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

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    Func WM_ERASEBKGND($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return True
    EndFunc ;==>WM_ERASEBKGND

    [/autoit]

    E

  • Dickes Danke Eukalyptus!
    Natürlich auch an name22, progandy und Badbunny ein Dankeschön ;)
    Das funktioniert echt super!

    Jetzt muss ich das Ganze noch auf meine Bedürfnisse anpassen :)