Не, ничего не вышло. То-есть, код вышел, но файл всё равно теряет качество. Вот функция, которая проворачивает файл два раза, на 90 и 270 градусов:
RotateImage(A_Desktop . "\test.jpg")
RotateImage(imagePath) {
static EncoderParameterValueTypeLong := 4
, #EncoderValueTransformRotate90 := 13
, #EncoderValueTransformRotate270 = 15
hModule := DllCall("LoadLibrary", "str", "gdiplus.dll", Ptr)
VarSetCapacity(si, 8 + A_PtrSize*2, 0)
si := Chr(1)
DllCall("gdiplus\GdiplusStartup", PtrP, pToken, Ptr, &si, Ptr, 0)
SplitPath, imagePath,, imageDir, ext, nameNoExt
if !RegExMatch(ext, "i)^J(PG|PEG|PE|FIF)$") {
MsgBox, Файлы %ext% не поддерживаются
Return
}
Loop 2 {
nSize := nListSize := nCount := pCodec := ""
DllCall("gdiplus\GdipLoadImageFromFile", WStr, imagePath, PtrP, pBitmap)
DllCall("gdiplus\GdipGetImageEncodersSize", UIntP, nCount, UIntP, nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", UInt, nCount, UInt, nSize, Ptr, &ci)
if !(nCount && nSize)
return -2
Loop, % nCount {
sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
if InStr(sString, "*." ext) {
pCodec := &ci+idx
break
}
}
DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, UintP, nListSize)
VarSetCapacity(EncoderParameters, nListSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, UInt, nListSize, Ptr, &EncoderParameters)
NumPut(1, EncoderParameters, 0, "UInt")
NumPut(1, EncoderParameters, 16 + A_PtrSize, "UInt")
NumPut(EncoderParameterValueTypeLong, EncoderParameters, 20 + A_PtrSize, "UInt")
NumPut(A_Index = 1 ? #EncoderValueTransformRotate90 : #EncoderValueTransformRotate270, NumGet(EncoderParameters, 24 + A_PtrSize) + 0, "UInt")
sOutput := ( A_Index = 1 ? A_Temp : imageDir ) . "\" . nameNoExt . ".jpg"
if A_IsUnicode
pOutput := &sOutput
else {
VarSetCapacity(wOutput, StrPut(sOutput, "UTF-16")*2, 0)
StrPut(sOutput, &wOutput, "UTF-16")
pOutput := &wOutput
}
DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, pOutput, Ptr, pCodec, Ptr, &EncoderParameters)
DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
imagePath := A_Temp . "\" . nameNoExt . ".jpg"
}
DllCall("gdiplus\GdiplusShutdown" , Ptr, pToken)
DllCall("FreeLibrary", Ptr, hModule)
FileDelete, % A_Temp . "\" . nameNoExt . ".jpg"
}