I'm writing a unique function to correctly convert, resize and crop images:
- I started from this smashly function: http://www.autoitscript.com/forum/topic/75022-image-resize-how/
- I used some more "WinAPIEx.au3" functions (udf required to run the code)
- I implemented a code (generally used in php) to correctly resize and crop images
Now my problem is that the output lost transparency. I bypassed it defining a white background with _GDIPlus_GraphicsClear(), but I'd like to keep transparency as well. I found some solutions, but they use _GDIPlus_GraphicsDrawImageRect() function that doesn't allow to crop images. Can you help me? Thanks!
AutoIt
#include-once #include <GDIPlus.au3> #include "APIConstants.au3" #include "WinAPIEx.au3" Global $aFiles = FileOpenDialog("Load Photo", @DesktopDir, "Photos (*.jpg;*.png;*.gif;*.bmp;*.tif)", 1 + 2) If @error = 0 Then Global $mFolder = FileSelectFolder("Select a destination folder", "", 3) $mFolder = _WinAPI_PathRemoveBackslash($mFolder) If $mFolder <> "" Then FileCopy($aFiles, $mFolder & "\ORIGINAL - " & _WinAPI_PathStripPath($aFiles), 9) __ImageWriteResize($aFiles, $mFolder & "\100x100 crop0 - " & _WinAPI_PathStripPath($aFiles), 100, 100, 0) __ImageWriteResize($aFiles, $mFolder & "\100x100 crop1 - " & _WinAPI_PathStripPath($aFiles), 100, 100, 1) __ImageWriteResize($aFiles, $mFolder & "\1000x100 crop0 - " & _WinAPI_PathStripPath($aFiles), 1000, 100, 0) __ImageWriteResize($aFiles, $mFolder & "\1000x100 crop1 - " & _WinAPI_PathStripPath($aFiles), 1000, 100, 1) __ImageWriteResize($aFiles, $mFolder & "\300x600 crop0 - " & _WinAPI_PathStripPath($aFiles), 300, 600, 0) __ImageWriteResize($aFiles, $mFolder & "\300x600 crop1 - " & _WinAPI_PathStripPath($aFiles), 300, 600, 1) __ImageWriteResize($aFiles, $mFolder & "\2000x2000 crop0 - " & _WinAPI_PathStripPath($aFiles), 2000, 2000, 0) __ImageWriteResize($aFiles, $mFolder & "\2000x2000 crop1 - " & _WinAPI_PathStripPath($aFiles), 2000, 2000, 1) EndIf EndIf Func __ImageWriteResize($sInFile, $sOutFile, $iOutWidth, $iOutHeight, $iCrop = 0) #cs Description: Save A Converted, Resized And Cropped Image From A Loaded Image File. Returns: 1 #ce Local $hInHandle, $iInWidth, $iInHeight, $iRatio, $hOutHandle, $hGraphic, $CLSID, $iInX = 0, $iInY = 0 Local $sExt = StringTrimLeft(_WinAPI_PathFindExtension($sOutFile), 1) _GDIPlus_Startup() $hInHandle = _GDIPlus_ImageLoadFromFile($sInFile) $iInWidth = _GDIPlus_ImageGetWidth($hInHandle) $iInHeight = _GDIPlus_ImageGetHeight($hInHandle) If $iCrop = 1 Then ; Images Are Cropped To Width And Height, Keeping Aspect Ratio (Smaller Images Are Expanded). If $iOutWidth / $iInWidth > $iOutHeight / $iInHeight Then $iRatio = $iOutWidth / $iInWidth Else $iRatio = $iOutHeight / $iInHeight EndIf $iInX = Int(($iInWidth - $iOutWidth / $iRatio) / 2) $iInY = Int(($iInHeight - $iOutHeight / $iRatio) / 4) $iInWidth = Int($iOutWidth / $iRatio) $iInHeight = Int($iOutHeight / $iRatio) Else ; Images Are Limited To Width And Height, Keeping Aspect Ratio (Smaller Images Are Not Expanded). If $iOutWidth / $iInWidth < $iOutHeight / $iInHeight Then $iRatio = $iOutWidth / $iInWidth Else $iRatio = $iOutHeight / $iInHeight EndIf If $iRatio > 1 Then $iRatio = 1 ; To Keep Size Of Smaller Images. EndIf $iOutWidth = Int($iInWidth * $iRatio) $iOutHeight = Int($iInHeight * $iRatio) EndIf $hOutHandle = _GDIPlus_BitmapCreateFromScan0($iOutWidth, $iOutHeight) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hOutHandle) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hInHandle, $iInX, $iInY, $iInWidth, $iInHeight, 0, 0, $iOutWidth, $iOutHeight) $CLSID = _GDIPlus_EncodersGetCLSID(StringUpper($sExt)) _GDIPlus_ImageSaveToFileEx($hOutHandle, $sOutFile, $CLSID) _GDIPlus_ImageDispose($hInHandle) _GDIPlus_ImageDispose($hOutHandle) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return 1 EndFunc ;==>__ImageWriteResize ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_BitmapCreateFromScan0 ; Description ...: Creates a Bitmap object based on an array of bytes along with size and format information ; Syntax.........: _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight[, $iStride = 0[, $iPixelFormat = 0x0026200A[, $pScan0 = 0]]]) ; Parameters ....: $iWidth - The bitmap width, in pixels ; $iHeight - The bitmap height, in pixels ; $iStride - Integer that specifies the byte offset between the beginning of one scan line and the next. This ; +is usually (but not necessarily) the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) ; +multiplied by the width of the bitmap. The value passed to this parameter must be a multiple of four ; $iPixelFormat - Specifies the format of the pixel data. Can be one of the following: ; |$GDIP_PXF01INDEXED - 1 bpp, indexed ; |$GDIP_PXF04INDEXED - 4 bpp, indexed ; |$GDIP_PXF08INDEXED - 8 bpp, indexed ; |$GDIP_PXF16GRAYSCALE - 16 bpp, grayscale ; |$GDIP_PXF16RGB555 - 16 bpp; 5 bits for each RGB ; |$GDIP_PXF16RGB565 - 16 bpp; 5 bits red, 6 bits green, and 5 bits blue ; |$GDIP_PXF16ARGB1555 - 16 bpp; 1 bit for alpha and 5 bits for each RGB component ; |$GDIP_PXF24RGB - 24 bpp; 8 bits for each RGB ; |$GDIP_PXF32RGB - 32 bpp; 8 bits for each RGB. No alpha. ; |$GDIP_PXF32ARGB - 32 bpp; 8 bits for each RGB and alpha ; |$GDIP_PXF32PARGB - 32 bpp; 8 bits for each RGB and alpha, pre-mulitiplied ; $pScan0 - Pointer to an array of bytes that contains the pixel data. The caller is responsible for ; +allocating and freeing the block of memory pointed to by this parameter. ; Return values .: Success - Returns a handle to a new Bitmap object ; Failure - 0 and either: ; |@error and @extended are set if DllCall failed ; Remarks .......: After you are done with the object, call _GDIPlus_ImageDispose to release the object resources ; Related .......: _GDIPlus_ImageDispose ; Link ..........; @@MsdnLink@@ GdipCreateBitmapFromScan0 ; Example .......; Yes ; =============================================================================================================================== Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0) Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[6] EndFunc ;==>_GDIPlus_BitmapCreateFromScan0