Lyoko Posted May 27, 2012 Posted May 27, 2012 My English very bad! ( I need udf to resize the file bmp and converter png to bmp file, it work on windows 7 and windows xp! Thanks you!
Zedna Posted May 27, 2012 Posted May 27, 2012 Search this forum. This was asked and answered already. Resources UDF ResourcesEx UDF AutoIt Forum Search
qwert Posted May 30, 2012 Posted May 30, 2012 I'm wrestling with this problem, also. What I'm specifically trying to do is to scale an existing image (in a file) so that the result is 800 pixels maximum in it's largest dimension — and then write the result to a different file name. The matches from "resize" searches return suggestions like this:_GDIPlus_GraphicsSetTransform() and _GDIPlusMatrixScale are probably what you want.You can adapt the _GDIPlusMatrixScale() example to your needs.But for those of us who have never written an image to a file using Au3, it's a big step to see how these can be used.Can someone point out a good starting point for this? Or at least a better search term?Thanks for any help.
UEZ Posted May 30, 2012 Posted May 30, 2012 Try this or 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
qwert Posted May 30, 2012 Posted May 30, 2012 Excellent! I was able to add a single statement to your first script to confirm that it gives the result I need: _GDIPlus_ImageSaveToFile($hBitmap, "C:\Temp\Test_File.jpg") I added it just before the ImageDispose and GraphicsDispose statements in the ScaleImage function. There are probably better ways, but this will work very well in my simple application. Thank you.
Belini Posted May 30, 2012 Posted May 30, 2012 I got this code a while ago and I do not know who the author is. expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> _ImageResize(@ScriptDir & "Test.jpg", @ScriptDir & "Test new.jpg", 500, 500) Func _ImageResize($sInImage, $sOutImage, $iW, $iH) ;declaracion de variables Local $sOP, $sOF, $sInExt, $Ext, $hBitmap, $hImage1, $hImage2, $hGraphic, $CLSID, $i = 0 Local $sType = "BMP|GIF|JPG|JPEG|PNG|TIF|TIFF" If Not FileExists($sInImage) Then Return SetError(1, 0, 0) $sInExt = StringUpper(StringTrimLeft($sInImage, StringInStr($sInImage, ".", 0, -1))) If Not StringRegExp($sInExt, "A(" & $sType & ")z", 0) Then Return SetError(2, 0, 0) ;OutFile path, to use later on. $sOP = StringLeft($sOutImage, StringInStr($sOutImage, "", 0, -1)) If Not FileExists($sOP) Then Return SetError(3, 0, 0) ;OutFile name, to use later on. $sOF = StringTrimLeft($sOutImage, StringInStr($sOutImage, "", 0, -1)) ;OutFile extension , to use for the encoder later on. $Ext = StringUpper(StringTrimLeft($sOutImage, StringInStr($sOutImage, ".", 0, -1))) If Not StringRegExp($Ext, "A(" & $sType & ")z", 0) Or $Ext = "ICO" Then Return SetError(4, 0, 0) If Not IsInt($iW) And Not IsInt($iH) Then Return SetError(5, 0, 0) ; WinAPI to create blank bitmap at the width and height to put your resized image on. $hBitmap = _WinAPI_CreateBitmap($iW, $iH, 1, 32) ;Start GDIPlus _GDIPlus_Startup() ;Get the handle of blank bitmap you created above as an image $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ;Load the image you want to resize. $hImage2 = _GDIPlus_ImageLoadFromFile($sInImage) ;Get the graphic context of the blank bitmap $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1) ;im not sure if this is better going here or if its the best form to call it DllCall($ghGDIPDll, "int", "GdipSetInterpolationMode", "hwnd", $hGraphic, "int", "7") ;Draw the loaded image onto the blank bitmap at the size you want _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $iW, $iH) ;Get the encoder of to save the resized image in the format you want. $CLSID = _GDIPlus_EncodersGetCLSID($Ext) ;Generate a number for out file that doesn't already exist, so you don't overwrite an existing image. Do $i += 1 Until (Not FileExists($sOP & $i & "_" & $sOF)) ;Prefix the number to the begining of the output filename $sOutImage = $sOP & $i & "_" & $sOF ;Save the new resized image. _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID) ;Clean up and shutdown GDIPlus. _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return SetError(0, 0, 1) EndFunc ;==>_ImageResize My Codes: Virtual Key Code UDF: http://www.autoitscript.com/forum/topic/138246-virtual-key-code-udf/ GuiSplashTextOn.au3: http://www.autoitscript.com/forum/topic/143542-guisplashtexton-udf/ Menu versions of Autoit: http://www.autoitscript.com/forum/topic/137435-menu-versions-of-autoit/#entry962011 Selects first folder of letters: ]http://www.autoitscript.com/forum/topic/144780-select-folders-by-letter/#entry1021708/spoiler] List files and folders with long addresses.: http://www.autoitscript.com/forum/topic/144910-list-files-and-folders-with-long-addresses/#entry102 2926 Program JUKEBOX made in Autoit:some functions:http://www.youtube.com/watch?v=WJ2tC2fD5Qs Navigation to search:http://www.youtube.com/watch?v=lblwOFIbgtQ
qwert Posted June 6, 2012 Posted June 6, 2012 My initial success with writing scaled JPG result files was shortlived. A major fault has surfaced: It doesn't work right on Win 7. As I summarized in my previous post:I was able to add a single statement to your first script to confirm that it gives the result I need:_GDIPlus_ImageSaveToFile($hBitmap, "C:\Temp\Test_File.jpg")I added it just before the ImageDispose and GraphicsDispose statements in the ScaleImage function.Everything works great on Win XP. I can scale and write any size image. But on Win 7, the ScaleImage function returns a completely black image whenever the source file is larger that about 100,000 bytes. In other words, small source images always work and large ones always fail. The resulting black image is about 17,000 bytes, so the conversion is doing something. But now and then, the script even crashes on the larger images.This is perplexing because I can't see any difference between the two runtime environments. I thought maybe it was a timing problem where the Dispose was executing before the JPG write had time to finish a large image. But, alas, a 2-second delay didn't help. I've confirmed that the ImageLoadFromFile is working. So the problem seems to be related to the ImageGetGraphicsContext.Anyone have suggestions of what to try? I really like the clarity of the ScaleImage approach. I just hope it can work in all OSs.
UEZ Posted June 6, 2012 Posted June 6, 2012 (edited) Can you show the code and attach an example image? Br, UEZ Edited June 6, 2012 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
qwert Posted June 6, 2012 Posted June 6, 2012 Thanks for your offer to take a look at this. It took me a while to get a suitable demonstration script ... and in testing it, I further isolated the problem: Something isn't properly initialized on the first use, only. After one large JPG image (e.g., > 1Mb ) is viewed and written (resulting in a black image), it writes subsequent large images just fine.But the aspect I first stated is still valid: the "first use failure" only occurs on Win 7 — and then, only when upsizing images larger than about 100K bytes. All images upscale correctly on XP. This difference seems very pecular and I'll sure be interested on seeing how this is occuring.expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <ListViewConstants.au3> #include <GDIPlus.au3> Global Const $STM_SETIMAGE = 0x0172 Global Const $IMAGE_BITMAP = 0 Global $hImage, $sFile, $aInfo, $aData, $w, $h $factor = 2 ; adjustable sizing factor ;===================== create a test GUI ================= $hGUI = GUICreate("Image Information", 700, 700, -1, -1 ) $hPic = GUICtrlCreatePic("", 6, 60, 600, 600) $hSelect = GUICtrlCreateButton("Select JPG Image", 20, 12, 120, 20) $hWrite = GUICtrlCreateButton("Write JPG Image", 160, 12, 120, 20) GUICtrlCreateLabel("Current scale factor = " & $factor, 300, 16, 200, 20) GUISetState(@SW_SHOW) _GDIPlus_StartUp() ;=====================main loop ===================== While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $hSelect $sFile = FileOpenDialog("Please select file", "", "Image files (*.jpg;*.tif;*.gif;*.bmp;*.png)") If @error Then ContinueLoop _LoadImage() Case $hWrite $hScale = Round ( $h * $factor ) $wScale = Round ( $w * $factor ) ScaleImage ( $sFile, $wScale, $hScale, 7 ) ; scale image to requested size MsgBox( 0, "Write Complete", @ScriptDir & "\Result.jpg") EndSwitch WEnd _GDIPlus_ShutDown() ;================= Functions ================================= Func _LoadImage() $hImage = _GDIPlus_ImageLoadFromFile($sFile) ; ; use GDI+ to load and display image $w = _GDIPlus_ImageGetWidth($hImage) $h = _GDIPlus_ImageGetHeight($hImage) If $w < 600 And $h < 600 Then $Pct = 100 _GUICtrlSetGDIPlusImage($hPic, $hImage) ElseIf $w >= $h Then $Pct = Round (600/$w * 100 ) _GUICtrlSetGDIPlusImage($hPic, _ImageResize($hImage, 600, 600 * $h / $w)) Else $Pct = Round ( 600/$h * 100 ) _GUICtrlSetGDIPlusImage($hPic, _ImageResize($hImage, 600 * $w / $h, 600)) EndIf _GDIPlus_ImageDispose($hImage) EndFunc ;================= create image to work with ============================ Func _GUICtrlSetGDIPlusImage($nCtrlID, $hImage) Local $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) DllCall("gdi32.dll", "bool", "DeleteObject", "handle", GUICtrlSendMsg($nCtrlID, $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP)) EndFunc ;===================== scale image ================================== Func ScaleImage($sFile, $iScaleW, $iScaleH, $iInterpolationMode = 7) If Not FileExists($sFile) Then Return SetError(1, 0, 0) Local $sImage = _GDIPlus_ImageLoadFromFile($sFile) If @error Then Return SetError(2, 0, 0) ; Local $iWidth = _GDIPlus_ImageGetWidth($sImage) * $iScaleW ; don't do scale ... use direct W x H params Local $iWidth = $iScaleW Local $iHeight = $iScaleH Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) If @error Then Return SetError(3, 0, 0) $hBitmap = $hBitmap[6] Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBmpCtxt, "int", $iInterpolationMode) _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight) _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Result.jpg") ;<<<<<<<<<<<<<<<<<<< MY ADDITION _GDIPlus_ImageDispose($sImage) _GDIPlus_GraphicsDispose($hBmpCtxt) Return $hBitmap EndFunc ;===================== resize image ================================ Func _ImageResize($hImage, $newW, $newH) $GC = _GDIPlus_ImageGetGraphicsContext($hImage) $newBmp = _GDIPlus_BitmapCreateFromGraphics($newW, $newH, $GC) $newGC = _GDIPlus_ImageGetGraphicsContext($newBmp) _GDIPlus_GraphicsDrawImageRect($newGC, $hImage, 0, 0, $newW, $newH) _GDIPlus_GraphicsDispose($GC) _GDIPlus_GraphicsDispose($newGC) Return $newBmp EndFunc ;=================== end ============================
UEZ Posted June 7, 2012 Posted June 7, 2012 The reason for the black image is easy! Have a closer look to line 75: _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight) The function returns false because you try to copy an empty handle ($hImage) to the bitmap context! Use this line instead and you will see the difference: _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $sImage, 0, 0, $iWidth, $iHeight) 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
qwert Posted June 7, 2012 Posted June 7, 2012 Thanks very much for spotting that. I can't recall what ever led me to go with $sImage instead of $hImage. It's a relief to find it wasn't due to OS differences. It now works in all OSs: XP, Vista and 7. I appreciate your assistance.
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