Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. file info. rss. print.
TEACH THE FOX HUNT PICTURES BETTER

Hello everyone! You know, I really spent some time trying to figure out what catching title should I provide for this article when suddenly as an answer from the blue, Rocky, the Office Assistant barked, wagged its tail and nudged its nose like it had found something. An idea immediately struck me so the rest, as they say, is history. If you happen to hate the title, blame it all to Rocky, the dog who can fit a disk right into its collar.

I bet most of you have successfully written applications in Visual FoxPro that can grab and store graphic files of different formats. There are lots of applications out there that need at least simple graphic management: payroll, personnel information system or even financing business, just to name a few. Probably some of you used third party graphic libraries that priced from $150 and up while others might have just utilized VFP’s native image object. While the former may offer more than what you ask for, there’s a price to pay. The latter, on the other hand, costs you nothing but it has nothing much to offer in return.

There’s a little known approach that gives greater capability compared to VFP’s image object without spending a dime. So gear up because we are about to teach the old fox how to hunt for pictures easily, better and – for free. We got two lucky breaks: one, VFP 6 has expanded its features to support other formats: JPGs, DIBs (device-independent bitmap) and GIFs over its predecessors. And, two, the old fox is quite teachable.



There, Boy, Bring Over That Stick To Me…
Our “stick” here is the Kodak Imaging Active-X control that comes with Windows. It is automatically installed during a typical Windows installation. To double-check if it is present in your machine, open your Accessories folders as illustrated in Figure 1. Better yet, use the Explorer and check if there is an IMGEDIT.OCX in your Windows\System directory. If none, you have to install it.
In VFP, click Tools, Option, Controls then the “Active-X controls” option button. Search for “Kodak Image Edit Control” and check it as shown in Figure 2. Click “OK”.




Create or open a form. Click the class viewer button and change the setting to ActiveX Controls. Select the Kodak Image control and drop it in the form. Change its AutoRefresh setting to .T.
In the sample form I created (Figure 3) I renamed the olecontrol as KodakImage. I added eight objects (7 command buttons and 1 combo) to handle the image accordingly aside from the usual stuff. I changed their names as follows:

1. Get Image = btnGetImage
2. Clear = btnClear
3. Zoom Out = btnZoomOut
4. Zoom In = btnZoomIn
5. Fit in the Box = btnFit
6. Reset Size = btnResetSize
7. Flip = btnFlip

The combobox is renamed as cmbRotate whose RowSourceType is set to 1 (Value), RowSource is “Rotate 90º Left,Rotate 180º Left,Rotate 270º Left,Rotate 90º Right,Rotate 180º Right,Rotate 270º Right” and Style is set to 2 (Dropdown List). I set the Enabled property of these controls to .F. at design-time except for btnGetImage since most functions require prior loading of the image.



Here are their corresponding methods:
1. btnGetImage.Click()
Local lcPicFile
lcPicFile = GetPict('BMP;JPG;DIB;GIF','Get Picture','OK')
If !Empty(lcPicFile)
    With ThisForm
        .KodakImage.Image = lcPicFile && dump the source graphic
        .KodakImage.Display && display the source graphic
        ** Enable other objects
        Store .T. To .btnClear.EnAbled,;
                     .btnZoomOut.EnAbled,;
                     .btnZoomIn.EnAbled,;
                     .btnFit.EnAbled,;
                     .btnResetSize.EnAbled,;
                     .btnFlip.EnAbled,;
                     .cmbRotate.EnAbled
    Endwith
Endif


2. btnClear.Click()
With ThisForm
    .KodakImage.ClearDisplay && clear the graphic
    ** Disable other objects
    Store .F. To .btnClear.EnAbled,;
                 .btnZoomOut.EnAbled,;
                 .btnZoomIn.EnAbled,;
                 .btnFit.EnAbled,;
                 .btnResetSize.EnAbled,;
                 .btnFlip.EnAbled,;
                 .cmbRotate.EnAbled
EndWith


3. btnZoomOut.Click()
With ThisForm.KodakImage
    .Zoom = IIf((.Zoom - 10) > 2,.Zoom - 10,2)
EndWith


The zoom value ranges from 2 to 6500 percent according to the documentation. The default is 100. Meaning, you can view the image 65x its original size. Change the decrementing or incrementing interval to any appropriate value other than 10 as you wish. Any value less than 2 will generate an error that’s why we have to trap it. However, my test shows that the maximum zoom value is 6553 as evident on the next code segment.

4. btnZoomIn.Click()
With ThisForm.KodakImage
    .Zoom = IIf((.Zoom + 10) < 6554,.Zoom + 10,6553)
EndWith


5. btnFit.Click()
ThisForm.KodakImage.FitTo(0,.T.)


The first parameter is the mode of fit: 0 – best fit, 1 – fit to width, 2 – fit to height and 3 – inch to inch. Passing 3 maintains the graphic’s relative size of the original image. In short, it will reset the image size back to the original. The second parameter is a Boolean whether to repaint the image or not. .T. repaints the image.

6. btnResetSize.Click()
ThisForm.KodakImage.Zoom = 100 && restore the original size


7. btnFlip.Click()
ThisForm.KodakImage.Flip


The Flip method only flips the image vertically. To flip horizontally, use RotateLeft or RotateRight instead.

8. cmbRotate.Valid()
If InList(This.ListItemID,1,2,3)
    ThisForm.KodakImage.RotateLeft(IIf(This.ListItemID=1,900,;
        IIf(This.ListItemID=2,1800,2700)))
Else
    ThisForm.KodakImage.RotateRight(IIf(This.ListItemID=4,900,;
        IIf(This.ListItemID=5,1800,2700)))
EndIf


The RotateLeft and RotateRight methods use the tenths of a degree as a parameter. The valid values are only limited to 90, 180 and 270 degrees. Therefore, you can only pass either of the three: 900, 1800 or 2700.

You can call the Image property of the object like Thisform.KodakImage.Image to get the fullname of the graphic being displayed. You can store the path to a character field or create a copy of the whole picture to a memo or general field.

Fox and Theories
The Kodak Imaging supports the following formats: AWD (Windows 98 only), BMP, DCX, JPG, PCX, TIFF, XIF, GIF, DIB and WIFF. It cannot accommodate ICO, CUR and ANI which VFP’s GetPict() function supports. For me, this is just a minor downside.
The control automatically adds horizontal and vertical scrollbars (if the ScrollBars property is set to .T.) when the image becomes bigger than the frame. The author(s) added tiny features in scrolling. Click the “thumb” (an elevator-like gauge) once – the left button need not stay down --and when you move your mouse up or down, the image goes with it. The same manner happens in horizontal scrolling. Also, when you click once the scrollbars’ arrows and let the mouse cursor stay on top of the arrows, the image continues to scroll in the arrow’s direction until you move your mouse away or the image has no more portions to show. However, the display goes “frenzy” at times which I’m sure is a bug. This odd behavior is intermittent but it can be remedied by clicking the thumb or the arrows again. Read more about this bug here: http://support.microsoft.com/kb/q243255/. It takes to have the IMGEDIT.OCX’s presence in the local machine for the application to run successfully so in theory you need to include this OCX in your distribution disk. But my experience proves otherwise. I ran into problems by doing so probably due to version incompatibility issues. My machine at home runs ME while my clients’ and the one I use in the office have Win98. I removed it from my distribution disk and so far I haven’t gone into the extent of installing it manually on my clients’ machines using Windows’ Add/Remove Programs procedure.


We barely scratch the surface. I know you can play with clipboard’s cut/copy and paste data, perform free-style or shaped drawing, write some tags (text), print the image or even select just a portion of the image to serve whatever purpose you desire. I haven’t tried it myself but I believe it can be done.

Before I Retreat Graciously Towards My Foxhole…
When I was a budding developer I used to show some antics off to friends. When they got impressed and asked me how I did those, my usual reply was “a magician never reveals his secrets.” That’s how I view things… before. I changed and the world as well. Now living under the Information Age, I realized that under normal circumstances, information must be shared -- freely. This way we grow and improve fast. I learned lots of things from other people because they share their knowledge with me in one form or another. I develop whatever I gain from them and now I am given given the chance to return the favor (thanks, Eric) with fervent hope that whatever I impart will be enhanced and somehow will return to me in a more advanced form. When Eric asked me to contribute to this website, I hesitated at first for personal reasons but the challenge is just too noble to ignore.
I want to give kudos to Eric den Doop of the Netherlands, Paul Culbertson of Texas, USA and Ryss Unger of South Africa for starting it all without expecting any financial returns. We are fortunate, you and I, to have this cool and new website where we can air our programming woes and receive help globally for free. So I wish that you, guys, I mean you – the readers – will continue to advocate this good cause as token to these three men.

Download code
Click here to download the code that is discussed in this article. The download is a zipfile. Its size is 493.056 bytes.

ABOUT THE AUTHOR: DALE DEDOROY

Dale Dedoroy Dale is a poor boy who finds joy in programming. He is currently the I.T. Officer of C.W. Mosser Environment Corporation.

FEEDBACK

Ronan Masangcay @ 3/15/2007 3:39:15 PM
This is nice Dale

Mohammed Anwar @ 5/14/2010 1:34:36 PM
i need after selecting the image selected area need to save in tif file.

plz help me. mail id mdanwar_23@yahoo.co.in

z qc @ 8/27/2011 12:34:19 PM
valuable



Your Name: 
Your Feedback: 

Spam Protection:
Enter the code shown: