- Offizieller Beitrag
Mir ist gerade etwas aufgefallen, wofür ich keine echte Erklärung finde.
Hier mal das Script:
#include <APIShellExConstants.au3>
#include <GDIPlus.au3>
#include <GDIPlusConstants.au3>
#include <WinAPIShellEx.au3>
_GDIPlus_Startup()
$sFileOrig = @ScriptDir & '\test_o.jpg'
$iFileSize = FileGetSize($sFileOrig) ; Originalgroesse: 7560412 bytes
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iFileSize = ' & $iFileSize & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$sFilename = @ScriptDir & '\test.jpg'
FileCopy($sFileOrig, $sFilename, $FC_OVERWRITE)
$iFileSize = FileGetSize($sFilename) ; hier (logisch): 7560412 bytes
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iFileSize = ' & $iFileSize & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
_RotateImage($sFilename)
_RotateImage($sFilename)
_RotateImage($sFilename)
_RotateImage($sFilename)
$iFileSize = FileGetSize($sFilename) ; nach 4x90 Grad: 7138682 bytes
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iFileSize = ' & $iFileSize & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
_RotateImage($sFilename)
_RotateImage($sFilename)
_RotateImage($sFilename)
_RotateImage($sFilename)
$iFileSize = FileGetSize($sFilename) ; nach weiteren 4x90 Grad: 7138682 bytes
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iFileSize = ' & $iFileSize & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
_GDIPlus_Shutdown()
Func _RotateImage($sImgFile)
Local Const $sTmpFile = @ScriptDir & '\TmpRotateImage.jpg'
Local $hImage, $sCLSID, $tData, $tParams, $ret
$hImage = _GDIPlus_ImageLoadFromFile($sImgFile) ; <- das erzeugt einen Datei-Lock auf $sImgFile
$sCLSID = _GDIPlus_EncodersGetCLSID('JPG')
$tData = DllStructCreate('int Data')
DllStructSetData($tData, 'Data', $GDIP_EVTTRANSFORMROTATE90)
$tParams = _GDIPlus_ParamInit(1)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, 'Data'))
$ret = _GDIPlus_ImageSaveToFileEx($hImage, $sImgFile, $sCLSID, $tParams) ; <- das funktioniert nicht, weil $sImgFile hier noch gelockt ist
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ; @extended = 7 ($GDIP_ERRWIN32ERROR)
; die gedrehte Bitmap muss erstmal unter einem anderen Namen ($sTmpFile) gespeichert werden:
$ret = _GDIPlus_ImageSaveToFileEx($hImage, $sTmpFile, $sCLSID, $tParams)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF)
_GDIPlus_ImageDispose($hImage) ; <- erst hiermit wird der Datei-Lock auf $sImgFile aufgehoben
_WinAPI_ShellFileOperation($sTmpFile, $sImgFile, $FO_RENAME, $FOF_NOCONFIRMATION) ; $sTmpFile umbenennen
EndFunc
Alles anzeigen
Das Bild ist zu groß als Anhang, deswegen auf meiner Homepage: https://technik-hobby.de/software/test_o.jpg
So nebenbei ist mir aufgefallen, dass "_GDIPlus_ImageLoadFromFile" einen Dateilock erzeugt, der erst beim "_GDIPlus_ImageDispose" wieder entfernt wird. Man kann also das gedrehte Image nicht unter dem gleichen Namen abspeichern.
Aber davon abgesehen, ist das eigentlich Merkwürdige, dass das Bild nach den ersten vier 90 Grad Drehungen plötzlich rund 400 KB kleiner ist.
Ich dachte, die JPG-90-Grad-Drehung wäre verlustfrei?
Nach weiteren vier mal 90 Grad wird es dann auch nicht mehr kleiner und das Bild sieht auch nach den 8 Drehungen noch genauso aus, wie das Original (auch in 200%-Ansicht).
Also ist die Drehung wohl wirklich verlustfrei (was die Bilddaten betrifft). Aber was sind dann die 400 KB?
Ok, es fehlen ein paar EXIF-Daten (kann man mit IrfanView sehen), aber das kann doch keine 400 KB ausmachen, oder?
Ich möchte gern in meinem Programm eine Drehung der Bilder anbieten, aber ich wüsste gern, welche Daten dabei verloren gehen.