Problem mit GDI+

  • Hallo!

    Ich verkleinere mit der Funktion siehe Spoiler(ist nicht das ganze Script) mehere Bilder.
    Nach ca. 6000 Bilder Funktioniert es nicht mehr. Es werden keine Bilder mehr gespeichert.
    Mir ist aufgefallen das die Autoit.exe im Taskmanager sich im laufe der Zeit ziemlich "viel" Speicher verwendet.
    Beim Start des Scripts sind es noch ca 20 MB am Ende dann ca 80 MB.
    Hat einer so ein Problem mit GDI+ schon gehabt und eine Lösung gefunden?

    Das Script fragt ab ob die Bilder schon existieren.
    Wenn man das Script also noch ein mal über die gleichen Bilder zum Umwandeln anwendet wird der "rest" der fehlt erstellt.
    Bsp.: ich hab 8000 Bilder die umgewandelt werden sollen, dann kommen beim erstenmal ausführen 6000 umgewandelte heraus.
    Beim zweitenmal dann der Rest (2000).

    Danke für eure Hilfe!

    Concara


    Spoiler anzeigen
    [autoit]


    Func _resize($FILE, $len, ByRef $NewH, ByRef $NewW)
    Local $NewFile, $hImage, $iX, $iY, $hGraphics, $hGraphicsImg, $hBitMap
    $error_o = DirCreate(@ScriptDir & "\klein")
    If Not $error_o Then
    MsgBox(4096, "Error", 'Es konnte der Orndern "klein" nicht erstellt werden. Gehen sie sicher, dass sie Schreibrechte in diesem Ordner haben!')
    Return 0
    EndIf
    $NewFile = @ScriptDir & "\klein" & StringTrimLeft($FILE, StringLen($len))
    If Not FileExists($NewFile) Then
    ;~ _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($FILE)
    If StringRight($FILE, StringLen($FILE) - StringInStr($FILE, ".","",-1)) = "gif" Or StringRight($FILE, StringLen($FILE) - StringInStr($FILE, ".","",-1)) = "bmp" Then
    _GDIPlus_ImageSaveToFile($hImage,$NewFile & "TEMP.jpg")
    _GDIPlus_ImageDispose($hImage)
    $hImage = _GDIPlus_ImageLoadFromFile($NewFile & "TEMP.jpg")
    FileDelete($NewFile & "TEMP.jpg")
    Else
    $hImage = _GDIPlus_ImageLoadFromFile($FILE)
    EndIf

    $iX = _GDIPlus_ImageGetWidth ($hImage)
    $iY = _GDIPlus_ImageGetHeight ($hImage)

    If $iX >= $iY Then
    $NewH = Round($NewH * $iY / $iX)
    Else
    $NewW = Round($NewW * $iX / $iY)
    EndIf

    ; Create sized BMP
    $hGraphicsImg = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBitMap = _GDIPlus_BitmapCreateFromGraphics($NewW,$NewH,$hGraphicsImg)
    _GDIPlus_GraphicsDispose($hGraphicsImg)
    ; ------------

    ; Create sized BMP
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitMap)
    _GDIPlus_GraphicsDrawImageRect($hGraphics,$hImage,0,0,$NewW,$NewH)
    _GDIPlus_GraphicsDispose($hGraphics)
    ;-----------------

    _GDIPlus_ImageSaveToFile($hBitMap,$NewFile)

    ; Cleanup
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BitmapDispose($hBitMap)
    _WinAPI_DeleteObject ($hImage)
    _WinAPI_DeleteObject ($hBitmap)
    _WinAPI_DeleteObject ($hGraphics)
    _WinAPI_DeleteObject ($hGraphicsImg)
    ;~ _GDIPlus_Shutdown()
    Return 1
    Else
    ;_GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile($NewFile)
    $iX = _GDIPlus_ImageGetWidth ($hImage)
    $iY = _GDIPlus_ImageGetHeight ($hImage)
    If $iX >= $iY Then
    $NewH = Round($NewH * $iY / $iX)
    Else
    $NewW = Round($NewW * $iX / $iY)
    EndIf
    _GDIPlus_ImageDispose($hImage)
    ;_GDIPlus_Shutdown()
    Return 2
    EndIf
    Return 0
    EndFunc

    [/autoit]

    If not :?: then ?( else :thumbup:

    Einmal editiert, zuletzt von Concara (8. April 2009 um 14:51)

  • Hi

    Beim Überfliegen fallen mir folgende Sachen auf:

    1) In Zeile 11 wird ein Bild geladen
    Wenn es sich nicht um ein gif oder bmp handelt, dann wird es in Zeile 18 erneut geladen und ist somit 2x im Speicher

    2) Ich würde den Ordner "klein" nicht in der Funktion erstellen, sondern nur einmal am Anfang; die Funktion wird doch 8000 mal ausgeführt!

    3) Ich verstehe ab Zeile 12 nicht so ganz:
    Wenn gif oder bmp, dann speicherst du mal in Jpg, lädst diese und speicherst am Schluß wieder in gif/bmp? ($NewFile bleibt doch gleich...)

    Warum das Script jedoch nur bis 6000 geht, weiß ich jetzt auch nicht?!?
    Gib mal nach jedem _GDIPlus_ImageSaveToFile ein Consolewrite incl. @error, und zwar so, daß du erkennst um welches _GDIPlus_ImageSaveToFile es sich handelt...
    ConsoleWrite(@error & " " & $Newfile & " 1" & @lf)
    ConsoleWrite(@error & " " & $Newfile & " 2" & @lf)

    Vielleicht auch mit Counter...
    Dann siehst du zumindest mal, ob die Funktion auch tatsächlich 8000 mal ausgeführt wird, oder z.b. nur nicht richtig gespeichert...

    lgE

  • Hi Eukalyptus!

    Vielen vielen Dank.
    Punkt 1 wars sehr wahrscheinlich.
    Ziemlich einfach der Fehler wenn mans sehen würde.

    Punkt 2 hab ich natürlich auch umgesetzt. Speed ist immer gut, vorallem wenn es sehr viele Bilder sind.

    Punkt 3:
    Das mache ich, weil aus irgend einem Grund es (mir) nicht möglich ist gif oder bmp Bilder sonst in kleinere Bilder umzuwandeln mit GDI+.
    Also erstelle ich zuerst ein Jpg das dann umgewandelt wird und speichere es dann.
    Ich verwende diese Funktion um eine Webgallarie zu erstellen. Und da ist es mir egal ob die Vorschaubilder dann nicht mehr das Originalformat haben.
    jpg groß wird zu jpg klein
    bmp groß wird zu jpg klein
    gif groß wird zu jpg klein

    Nochmal herzlichen Dank

    If not :?: then ?( else :thumbup: