Jump to content
Sign in to follow this  
adamski

Pixelated GDI+ Zoom

Recommended Posts

adamski

I have altered the autoit zoom demo code and would like to prevent the image smoothing that happens to the zoomed image. How can I get it to show sharp large zoomed pixels?

Thanks

#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>

Opt("MustDeclareVars", 1)

; ====================================================================================================

===========================
; Description ...: Shows how to magnify an image
; Author ........: Paul Campbell (PaulIA)
; Notes .........:
; ====================================================================================================

===========================

; ====================================================================================================

===========================
; Global variables
; ====================================================================================================

===========================

Global $hBMP, $hGUI1, $hGUI2, $hBitmap, $hGraphic1, $hGraphic2

; ====================================================================================================

===========================
; Main
; ====================================================================================================

===========================

Local $Width = 400
Local $Height = 300

Local $ZoomFactor = 16

; Create a GUI for the zoomed image
$hGUI2 = GUICreate("Zoomed"  , $Width, $Height, 0, 400)
GUISetState()

_GDIPlus_Startup()

; Loop until user exits
do
    
Local $aMousePos = MouseGetPos()
    
; Capture top left corner of the screen
$hBMP = _ScreenCapture_Capture("", 0, 0, -1, -1, False)

; Initialize GDI+ library and load image

$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)

; Draw 2x zoomed image
$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hGUI2)
_GDIPlus_GraphicsDrawImageRectRect($hGraphic2, $hBitmap, $aMousePos[0]-($Width/$ZoomFactor)/2, $aMousePos[1]-($Height/$ZoomFactor)/2, $Width/$ZoomFactor, $Height/$ZoomFactor, 0, 0, $Width, $Height)

; Release resources
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hBitmap)
_WinAPI_DeleteObject($hBmp)

until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_Shutdown()

Share this post


Link to post
Share on other sites
Malkey

I have altered the autoit zoom demo code and would like to prevent the image smoothing that happens to the zoomed image. How can I get it to show sharp large zoomed pixels?

Thanks

#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>

Opt("MustDeclareVars", 1)

; ====================================================================================================


===========================
; Description ...: Shows how to magnify an image
; Author ........: Paul Campbell (PaulIA)
; Notes .........:
; ====================================================================================================


===========================

; ====================================================================================================


===========================
; Global variables
; ====================================================================================================


===========================

Global $hBMP, $hGUI1, $hGUI2, $hBitmap, $hGraphic1, $hGraphic2

; ====================================================================================================


===========================
; Main
; ====================================================================================================


===========================

Local $Width = 400
Local $Height = 300

Local $ZoomFactor = 16

; Create a GUI for the zoomed image
$hGUI2 = GUICreate("Zoomed"  , $Width, $Height, 0, 400)
GUISetState()

_GDIPlus_Startup()

; Loop until user exits
do
    
Local $aMousePos = MouseGetPos()
    
; Capture top left corner of the screen
$hBMP = _ScreenCapture_Capture("", 0, 0, -1, -1, False)

; Initialize GDI+ library and load image

$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)

; Draw 2x zoomed image
$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hGUI2)
_GDIPlus_GraphicsDrawImageRectRect($hGraphic2, $hBitmap, $aMousePos[0]-($Width/$ZoomFactor)/2, $aMousePos[1]-($Height/$ZoomFactor)/2, $Width/$ZoomFactor, $Height/$ZoomFactor, 0, 0, $Width, $Height)

; Release resources
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_ImageDispose($hBitmap)
_WinAPI_DeleteObject($hBmp)

until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_Shutdown()
The better zooming function is "StretchBlt" from "user32.dll"

;#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)

Global $hGUI2, $Width = 400, $Height = 300, $ZoomFactor = 32

$hGUI2 = GUICreate("Zoomed", $Width, $Height, 0, 400)
GUISetState()

Do
    Local $aMousePos = MouseGetPos()
    _MAG($hGUI2, $aMousePos[0] - ($Width / $ZoomFactor) / 2, $aMousePos[1] - ($Height / $ZoomFactor) / 2)
    Sleep(10)
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Modified from http://www.autoitscript.com/forum/index.php?s=&showtopic=53471&view=findpost&p=405045
Func _MAG($MyhWnd, $l, $t)
    Local $MyHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", $MyhWnd); $MyHDC = _WinAPI_GetDC ($MyhWnd)
    If @error Then Return
    Local $DeskHDC = DllCall("user32.dll", "int", "GetDC", "hwnd", 0)   ; $DeskHDC = _WinAPI_GetDC (0)
    If Not @error Then
        DllCall("gdi32.dll", "int", "StretchBlt", "int", $MyHDC[0], "int", 0, "int", 0, "int", $Width, "int", $Height, "int", _
                $DeskHDC[0], "int", $l, "int", $t, "int", $Width / $ZoomFactor, "int", $Height / $ZoomFactor, "long", $SRCCOPY)
                
        DllCall("user32.dll", "int", "ReleaseDC", "int", $DeskHDC[0], "hwnd", 0); _WinAPI_ReleaseDC ($DeskHDC, 0)
    EndIf
    DllCall("user32.dll", "int", "ReleaseDC", "int", $MyHDC[0], "hwnd", $MyhWnd); _WinAPI_ReleaseDC ($MyhWnd, $MyHDC)
EndFunc  ;==>MAG

I think your example at http://www.autoitscript.com/forum/index.ph...st&p=627528

is very clever, innovative.

Share this post


Link to post
Share on other sites
adamski

Excellent, that was clear and very helpful.

Thanks.

I wondered why this was not a function in WinAPI.au3 as then I would have found it - so I made one.

; #FUNCTION# ====================================================================================================

================
; Name...........: _WinAPI_StretchBlt
; Description ...: Copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap.
; Syntax.........: _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iXZoom, $iYZoom, $iROP)
; Parameters ....: $hDestDC  - Handle to the destination device context
;                 $iXDest     - X value of the upper-left corner of the destination rectangle
;                 $iYDest     - Y value of the upper-left corner of the destination rectangle
;                 $iWidth     - Width of the source and destination rectangles
;                 $iHeight   - Height of the source and destination rectangles
;                 $hSrcDC     - Handle to the source device context
;                 $iXSrc       - X value of the upper-left corner of the source rectangle
;                 $iYSrc       - Y value of the upper-left corner of the source rectangle
;                 $iXZoom     - Horizontal zoom factor (< 1 to shrink, > 1 to enlarge, -ive to flip)
;                 $iYZoom     - Vertical zoom factor (< 1 to shrink, > 1 to enlarge, -ive to flip)
;                 $iROP     - Specifies a raster operation code.  These codes define  how  the  color  data  for  the  source
;                 +rectangle is to be combined with the color data for the destination rectangle to achieve the final color:
;                 |$BLACKNESS     - Fills the destination rectangle using the color associated with palette index 0
;                 |$CAPTUREBLT   - Includes any window that are layered on top of your window in the resulting image
;                 |$DSTINVERT     - Inverts the destination rectangle
;                 |$MERGECOPY     - Merges the color of the source rectangle with the brush currently  selected  in  hDest,  by
;                 +using the AND operator.
;                 |$MERGEPAINT   - Merges the color of the inverted source  rectangle  with  the  colors  of  the  destination
;                 +rectangle by using the OR operator.
;                 |$NOMIRRORBITMAP - Prevents the bitmap from being mirrored
;                 |$NOTSRCCOPY   - Copies the inverted source rectangle to the destination
;                 |$NOTSRCERASE - Combines the colors of the source and destination rectangles by using the OR  operator  and
;                 +then inverts the resultant color.
;                 |$PATCOPY     - Copies the brush selected in hdcDest, into the destination bitmap
;                 |$PATINVERT     - Combines the colors of the brush currently selected  in  hDest,  with  the  colors  of  the
;                 +destination rectangle by using the XOR operator.
;                 |$PATPAINT       - Combines the colors of the brush currently selected  in  hDest,  with  the  colors  of  the
;                 +inverted source rectangle by using the OR operator.  The result of this operation is combined with the  color
;                 +of the destination rectangle by using the OR operator.
;                 |$SRCAND       - Combines the colors of the source and destination rectangles by using the AND operator
;                 |$SRCCOPY     - Copies the source rectangle directly to the destination rectangle
;                 |$SRCERASE       - Combines the inverted color of the destination rectangle with  the  colors  of  the  source
;                 +rectangle by using the AND operator.
;                 |$SRCINVERT     - Combines the colors of the source and destination rectangles by using the XOR operator
;                 |$SRCPAINT       - Combines the colors of the source and destination rectangles by using the OR operator
;                 |$WHITENESS     - Fills the destination rectangle using the color associated with index  1  in  the  physical
;                 +palette.
; Return values .: Success    - True
;                 Failure     - False
; Author ........: Adam Cadamally (adamski)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........; @@MsdnLink@@ StretchBlt
; Example .......;
; ====================================================================================================

===========================
Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iXZoom, $iYZoom, $iROP)
    Local $aResult

    $aResult = DllCall("gdi32.dll", "int", "StretchBlt", "int", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, "int", $iHeight, "int", _
            $hSrcDC, "int", $iXSrc, "int", $iYSrc, "int", $iWidth / $iXZoom, "int", $iHeight / $iYZoom, "long", $iROP)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc  ;==>_WinAPI_StretchBlt

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×