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