Enable crop and zooming in on your digital photograph display form
I wanted to add the ability to zoom into a portion of a photograph on my photo viewer. Below is some code that processes the MouseUp, MouseDown and MouseMove events to add a yellow dotted-dash selection rectangle using a Shape control that the mouse can resize over the desired portion of a picture to crop/zoom.
Using the image control with Stretch set to Isometric means to keep the image’s original proportions (so skinny people stay skinny). That means that if the image control’s aspect ratio (width/height) is different from that of the original picture, either the top/bottom edges or the left/right edges of the image surface will be blank. Thus, calculating the crop rectangle gets a little complicated.
An additional complication arises when the ShowWindow is set to show the form as a top level form. The hWnd needed to draw the image is the client window of the form. WindowFromPoint is called to get the window from an x/y position.
The DrawImagePortionScaled routine of _gdiplus.vcx is called to do the scaling and drawing.
Now I can zoom in on that book on the bookcase in the background of the photo to read the title and author!
PUBLIC x
x=NEWOBJECT("pform")
DEFINE CLASS pform as form
left=00
width=600
height=300
ShowWindow=1
allowoutput=.f.
ADD OBJECT img as myimage
PROCEDURE init
this.img.visible=1
this.img.picture="d:\kids.jpg"
this.img.height=thisform.height
this.img.width=thisform.width
this.visible=1
DECLARE integer ValidateRect IN WIN32API integer, integer
ENDDEFINE
DEFINE CLASS myimage as Image
stretch=1
nState=0
PROCEDURE mousemove(nBut,nShift,x,y)
IF this.nState=1
IF x > thisform.dr.Left
thisform.dr.width=x - thisform.dr.Left
ENDIF
IF y > thisform.dr.Top
thisform.dr.height = y -thisform.dr.Top
ENDIF
ENDIF
PROCEDURE mousedown(nBut,nShift,x,y)
IF this.nState>0
thisform.dr.visible=0
this.picture=this.picture
this.nState=0
RETURN
ENDIF
IF VARTYPE(thisform.dr)='U'
thisform.AddObject("dr","myshape")
ENDIF
thisform.dr.top=y
thisform.dr.left = x
thisform.dr.height=1
thisform.dr.width=1
thisform.dr.visible=1
this.nState=1
PROCEDURE mouseup(nBut,nShift,x,y)
IF this.nState#1
RETURN
ENDIF
this.nState =2
thisform.dr.visible=.f.
thisform.img.picture=thisform.img.picture &&paint over sel rect
SET CLASSLIB TO HOME()+"ffc\_gdiplus"
LOCAL oGraphics as gpGraphics OF (HOME()+"ffc\_gdiplus")
LOCAL oRectDest as gpRectangle OF (HOME()+"ffc\_gdiplus")
LOCAL oImage as gpImage OF (HOME()+"ffc\_gdiplus")
oImage=CREATEOBJECT("gpImage",thisform.img.picture)
oGraphics=CREATEOBJECT("gpgraphics")
wRatio=oImage.ImageHeight/oImage.ImageWidth && 1704/2272 .75
pRatio=thisform.img.Height/thisform.img.Width && 300/600 .5
*Must compensate for Stretch=1 (Isometric)
IF wRatio>pratio
wwidth=thisform.img.height/wRatio
wleft=thisform.img.left+(thisform.img.width - wwidth)/2
wtop=thisform.img.top
wheight=thisform.img.height
oRectSrc=CREATEOBJECT("gpRectangle",;
(thisform.dr.left-wleft)*oImage.ImageWidth/wWidth,;
(thisform.dr.top - thisform.img.top) *oImage.ImageHeight/thisform.img.height,;
thisform.dr.width*oImage.ImageWidth/wWidth,;
thisform.dr.Height * oImage.ImageHeight/thisform.img.height)
ELSE
wwidth=thisform.img.width
wleft=thisform.img.left
wheight=thisform.img.width*wRatio
wTop=thisform.img.top+(thisform.img.height-wheight)/2
oRectSrc=CREATEOBJECT("gpRectangle",;
thisform.dr.left * oImage.ImageWidth/thisform.img.width,;
(thisform.dr.top-wtop) *oImage.ImageHeight/wheight,;
thisform.dr.width * oImage.ImageWidth/thisform.img.width,;
thisform.dr.Height *oImage.ImageHeight/wheight)
ENDIF
oRectDest=CREATEOBJECT("gpRectangle",wleft,wtop,wwidth,wHeight)
hWnd=SYS(2327, SYS(2325, SYS(2326,THISFORM.hwnd))) && From Craig Boyd
oGraphics.CreateFromHWND(hWnd)
oGraphics.DrawImagePortionScaled(oImage,oRectDest,oRectSrc,2)
ValidateRect(hWnd,0)
ENDDEFINE
DEFINE CLASS myshape as Shape
bordercolor=65535
BackStyle=0 && transparent
BorderStyle=4
ENDDEFINE