Lupo73 Posted July 26, 2013 Share Posted July 26, 2013 (edited) I'm writing a unique function to correctly convert, resize and crop images: - I started from this smashly function: '?do=embed' frameborder='0' data-embedContent>> - 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! expandcollapse popup#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 Edited July 26, 2013 by Lupo73 SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders. Link to comment Share on other sites More sharing options...
UEZ Posted July 26, 2013 Share Posted July 26, 2013 (edited) Create an empty bitmap with alpha channel using _GDIPlus_BitmapCreateFromScan0() function: ; #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 And use _GDIPlus_GraphicsDrawImageRectRect() function to copy the image to the empty bitmap. Transparency shouldn't be lost. Br, UEZ Edited July 26, 2013 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Lupo73 Posted July 26, 2013 Author Share Posted July 26, 2013 Perfect, thanks! I updated the code if someone what to use it. SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders. Link to comment Share on other sites More sharing options...
Lupo73 Posted July 27, 2013 Author Share Posted July 27, 2013 I made more tests and it works as expected. Only a minor issue, EXIF are lost. Is is possible to keep image data too? SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders. Link to comment Share on other sites More sharing options...
UEZ Posted July 28, 2013 Share Posted July 28, 2013 Search the forum for EXIF. There are some examples.Br,UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Lupo73 Posted July 29, 2013 Author Share Posted July 29, 2013 I may use: - this script to read Exif '?do=embed' frameborder='0' data-embedContent>> - and this one to write Exif But they have different outputs and so only some metadata (and only for jpg) could be imported. Reading these and other topics, it seems not possible to support resize/crop features (using _GDIPlus_GraphicsDrawImageRectRect to define them) and keep image metadata (that requires to work on the original file, like in the _GDIPlus_SetMetaData example). SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now