I wondered if someone could show me how to do the following using GDI:
1. Scale an image so the shortest edge is 88 pixels (keeping aspect ratio)
2. Crop the scaled image to select the center 88x88 pixels
Here is the code I have so far (with help from Prog@ndy) which squahes the entire image to 88x88
AutoIt
#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <GuiListView.au3> #include <GDIPlus.au3> ; Hide system tray icon #NoTrayIcon ; Use Event mode Opt("GUIOnEventMode", 1) ; Setup some constants Const $ProgramName = "Cropper" Const $Version = "v1.00" Const $WindowTitle = $ProgramName & " " & $Version & " by NiVZ" #Region ### START Koda GUI section ### Form= $Form = GUICreate($WindowTitle, 520, 520) $TabHost = GUICtrlCreateTab(10, 10, 504, 500) $TabPhoto = GUICtrlCreateTabItem("Photos") $grpPhotos = GUICtrlCreateGroup("Photo List", 20, 40, 300, 460) $lvPhotos = GUICtrlCreateListView("Photo Title", 30, 60, 280, 390, BitOR($LVS_SHOWSELALWAYS, $LVS_SINGLESEL, $LVS_REPORT, $LVS_NOCOLUMNHEADER)) GUICtrlSetBKColor(-1, $GUI_BKCOLOR_LV_ALTERNATE) _GUICtrlListView_SetColumnWidth(-1, 0, 259) $btnAddPhoto = GUICtrlCreateButton("Add Photo", 30, 460, 90, 30) GUICtrlCreateGroup("", -99, -99, 1, 1) Global $grpPThumb = GUICtrlCreateGroup("Thumbnail", 330, 40, 170, 160) Global $imgPIcon = GUICtrlCreatePic("", 370, 60, 88, 88, -1, $WS_EX_CLIENTEDGE) ;Global $butChange = GUICtrlCreateButton("Change Thumbnail", 360, 158, 108, 30) GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group #EndRegion ### END Koda GUI section ### GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents") GUICtrlSetOnEvent($btnAddPhoto, "AddPhoto") _GDIPlus_Startup() GUISetState(@SW_SHOW) While 1 ; Wait for events WEnd Func AddPhoto() ; Show the add videos dialog Local $aFiles = FileOpenDialog("Add Photo", @DesktopDir, "Photos (*.jpg)", 1 + 2 + 4, "", $Form) If @error Then ; Do nothing Else CropImage($aFiles) EndIf EndFunc Func CropImage($inFilename) ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks Local $hLblDC = _WinAPI_GetDC(GUICtrlGetHandle($imgPIcon)) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hLblDC, 88, 88) Local $hDC = _WinAPI_CreateCompatibleDC($hLblDC) _WinAPI_SelectObject($hDC, $hBitmap) Local $hImg = _GDIPlus_ImageLoadFromFile($inFilename) Local $hGraph = _GDIPlus_GraphicsCreateFromHDC($hDC) _GDIPlus_GraphicsDrawImageRect($hGraph, $hImg, 0, 0, 88, 88) _GDIPlus_GraphicsDispose($hGraph) _GDIPlus_ImageDispose($hImg) Local $tData = DllStructCreate("byte[15488]") Local $tBITMAPINFOHEADER = DllStructCreate("DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; DWORD colormap[3]") DllStructSetData($tBITMAPINFOHEADER, 1, DllStructGetSize($tBITMAPINFOHEADER)) DllStructSetData($tBITMAPINFOHEADER, 2, 88) DllStructSetData($tBITMAPINFOHEADER, 3, -88) DllStructSetData($tBITMAPINFOHEADER, 4, 1) DllStructSetData($tBITMAPINFOHEADER, 5, 16) ; use default GDI32 16 bit format: 5-5-5 DllStructSetData($tBITMAPINFOHEADER, 6, 0) ; Choose Colormask manually, example for 5-5-5 ;~ DllStructSetData($tBITMAPINFOHEADER, 6, 3) ;BI_BITFIELDS ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x7C00, 1) ;- Red mask ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x03E0, 2) ;- Green mask ;~ DllStructSetData($tBITMAPINFOHEADER, "colormap", 0x001F, 3) ;- Blue mask _WinAPI_GetDIBits($hLblDC, $hBitmap, 0, 88, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1) _WinAPI_ReleaseDC(GUICtrlGetHandle($imgPIcon), $hLblDC) _WinAPI_DeleteDC($hDC) _GUICtrlStatic_SetImage($imgPIcon, $hBitmap) EndFunc Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit ;Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE ;MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle) ;Case @GUI_CtrlId = $GUI_EVENT_RESTORE ;MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle) EndSelect EndFunc ;==>SpecialEvents Func _GUICtrlStatic_SetImage($iCtrlId, $hBitmap) ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks Local Const $STM_SETIMAGE = 0x0172 Local Const $IMAGE_BITMAP = 0 Local Const $SS_BITMAP = 0xE Local Const $GWL_STYLE = -16 If IsHWnd($iCtrlId) Then If WinGetProcess($iCtrlId) <> @AutoItPID Then Return SetError(1,0,0) Else $iCtrlId = GUICtrlGetHandle($iCtrlId) If Not $iCtrlId Then Return SetError(2,0,0) EndIf ; set SS_BITMAP style to control Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE) If @error Then Return SetError(3, 0, 0) DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP)) If @error Then Return SetError(4, 0, 0) Local $oldBmp = DllCall("user32.dll", "handle", "SendMessageW", "hwnd", $iCtrlId, "int", $STM_SETIMAGE, "wparam", $IMAGE_BITMAP, "handle", $hBitmap) If @error Then Return SetError(5, 0, 0) If $oldBmp[0] Then _WinAPI_DeleteObject($oldBmp[0]) Return 1 EndFunc
Thanks,
NiVZ





