Jump to content



Photo

GDI Scale and Crop


  • Please log in to reply
2 replies to this topic

#1 NiVZ

NiVZ

    Adventurer

  • Active Members
  • PipPip
  • 101 posts

Posted 26 April 2012 - 11:12 AM

Hello,

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







#2 NiVZ

NiVZ

    Adventurer

  • Active Members
  • PipPip
  • 101 posts

Posted 26 April 2012 - 02:36 PM

Figured it out ;)

AutoIt         
[/sup] [sup]#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <GuiListView.au3> #include <GDIPlus.au3>[/sup] [sup]; Hide system tray icon #NoTrayIcon[/sup] [sup]; Use Event mode Opt("GUIOnEventMode", 1)[/sup] [sup]; Setup some constants Const $ProgramName  = "Cropper" Const $Version  = "v1.00" Const $WindowTitle = $ProgramName & " " & $Version & " by NiVZ"[/sup] [sup]#Region ### START Koda GUI section ### Form= $Form   = GUICreate($WindowTitle, 520, 520)[/sup] [sup]$TabHost  = GUICtrlCreateTab(10, 10, 504, 500)[/sup] [sup]$TabPhoto  = GUICtrlCreateTabItem("Photos")[/sup] [sup]   $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)[/sup] [sup]   GUICtrlCreateGroup("", -99, -99, 1, 1)[/sup] [sup]   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  [/sup] [sup]#EndRegion ### END Koda GUI section ###[/sup] [sup]GUISetOnEvent($GUI_EVENT_CLOSE,   "SpecialEvents") GUISetOnEvent($GUI_EVENT_MINIMIZE,   "SpecialEvents") GUISetOnEvent($GUI_EVENT_RESTORE,   "SpecialEvents") GUICtrlSetOnEvent($btnAddPhoto,   "AddPhoto")[/sup] [sup]_GDIPlus_Startup()[/sup] [sup]GUISetState(@SW_SHOW)[/sup] [sup]While 1    ; Wait for events WEnd[/sup] [sup] [/sup] [sup]Func AddPhoto()      ; Show the add photos dialog    Local $aFiles = FileOpenDialog("Add Photo", @DesktopDir, "Photos (*.jpg)", 1 + 2, "", $Form)      If @error Then    ; Do nothing    Else      CropImage($aFiles)        EndIf   EndFunc[/sup] [sup] [/sup] [sup]Func CropImage($inFilename)[/sup] [sup]   ; Function written by [email="Prog@ndy"]Prog@ndy[/email] - many thanks[/sup] [sup]   Local $newwidth, $newheight, $x, $y[/sup] [sup]   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)[/sup] [sup]   Local $width  = _GDIPlus_ImageGetWidth($hImg)    Local $height  = _GDIPlus_ImageGetHeight($hImg)      If $width > $height Then    ; Landscape      $x = ($width - $height) /2    $y = 0      $newwidth = $height    $newheight = $height      ElseIf $height > $width Then    ; Portrait      $x = 0    $y = ($height-$width) /2      $newwidth = $width    $newheight = $width  [/sup] [sup]   Else    ; Square    $x = 0    $y = 0    $newwidth = $width    $newheight = $width    EndIf          Local $hGraph = _GDIPlus_GraphicsCreateFromHDC($hDC)[/sup] [sup]   ;_GDIPlus_GraphicsDrawImageRect($hGraph, $hImg, 0, 0, 88, 88)    _GDIPlus_GraphicsDrawImageRectRect($hGraph, $hImg, $x, $y, $newwidth, $newheight, 0, 0, 88, 88)[/sup] [sup]      _GDIPlus_GraphicsDispose($hGraph)    _GDIPlus_ImageDispose($hImg)[/sup] [sup]   Local $tData = DllStructCreate("byte[15488]")[/sup] [sup]   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)[/sup] [sup]   ; use default GDI32 16 bit format: 5-5-5    DllStructSetData($tBITMAPINFOHEADER,  6, 0)[/sup] [sup]   ; 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[/sup] [sup]   _WinAPI_GetDIBits($hLblDC, $hBitmap, 0, 88, DllStructGetPtr($tData), DllStructGetPtr($tBITMAPINFOHEADER), 1)[/sup] [sup]   _WinAPI_ReleaseDC(GUICtrlGetHandle($imgPIcon), $hLblDC)    _WinAPI_DeleteDC($hDC)[/sup] [sup]   _GUICtrlStatic_SetImage($imgPIcon, $hBitmap)   EndFunc[/sup] [sup]Func SpecialEvents()[/sup] [sup]    Select    Case @GUI_CtrlId = $GUI_EVENT_CLOSE    _GDIPlus_Shutdown()             Exit[/sup] [sup]       ;Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE             ;MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)[/sup] [sup]       ;Case @GUI_CtrlId = $GUI_EVENT_RESTORE             ;MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)[/sup] [sup]    EndSelect[/sup] [sup]EndFunc   ;==>SpecialEvents[/sup] [sup]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[/sup] [sup]   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[/sup] [sup]

Edited by NiVZ, 26 April 2012 - 02:37 PM.

  • Zoldex likes this

#3 Zoldex

Zoldex

    Seeker

  • Active Members
  • 30 posts

Posted 21 October 2012 - 12:44 PM

Thanks for sharing this!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users