Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PictureVal Issue

Status
Not open for further replies.

vernpace

Programmer
Feb 22, 2015
209
US
We have an application that displays relatively large images (PNG,JPG,TIF) using an image control (1350x855) with Stretch:Isometric (required for our purposes). We have found that using PictureVal is superior to Picture with respect to quality and image resizing. However, there are performance issues with large images >= 3MBs. Mouse events (MouseDown, MouseEnter, MouseLeave, MouseUp) slow down dramatically. Also, hovering a grid header slows down. We have tried all the techniques for loading PictureVal and found FILETOSTR() to be the best.

We are thinking that there is no solution for this - that this is a possible memory leak that the Fox team didn't catch. However, we may be wrong. Any suggestions are welcome.
 
I'm not sure if this will help, but the VFP Help file recommends using a Blob or Memo field to store the image, rather than an external file. The latter causes a great deal of memory bloat, it seems:

VFP Help for PictureVal said:
Note that Visual FoxPro only uses the memory required to render an image when the image is stored in a memo or blob field. This is a memory efficient way to display images in Visual FoxPro. However, using a file reference in the PictureVal property requires Visual FoxPro to use up to twice the amount of memory as the size of the file. For example, if you reference a 5 MB image file, Visual FoxPro requires up to 10MB of memory to display the file.

Presumably you have already tried that, but I thought it worth pointing out.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

We tried that. Actually, there was no visible performace increase.

Olaf,

We already use GDIPlusX to create alpha-blended images, greyscale images, thumbnails, ... all sorts of things. Interesting you suggest the picture property of the container control. Will try.

Thanks all
 
No, I'm not suggesting the picture property of the container control. I just suggest the container as it spans a rectangle, but then use GDI+ low level to paint a bitmap on it. You therefore will use up GDI+ resources, but also be able to free them. It's more work to do, but once, for a GDI+ based self-made image control with the goal to make it more memory effective.

A completely other way would be thinking about the images themselves. How do they contribute to the resource hunger of the VFP image control? Can they be optimized? I don't think the image file optimization plays the same role as for the web, as the file transfer is not the bottleneck and whatever you display on the screen will be the decompressed RGB bitmap it is. The compressed file size is only the file size, the graphics card will have all the pixels with 3 bytes each, no matter whether and how the image file is compressed. So image file optimizations will not help much.

But since you say you already make use of GDIplusX, watch out for the Task Manager Details tab, where you can pick to show a column about number of GDI objects or GDI handles. Watch out whether your EXE process or the VFP9 IDE uses more and more over time, especially when you watch that in parallel while single-stepping through code.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Olaf,

You need a canvas for a GDIPlusX image and the image control is that canvas. As far as I know, you can't just use GDIPlusX to paint an image on a container - at least not with VFP.

Optimizing images is another story. I tried this a few years ago with some success and retried again today after a minor tweak. Since our image canvas is 1350x855, any images with dimensions greater are resized (using GDIPlusX) to fit the canvas. This works well - for instance, a 3600x2400 7.63MB PNG was resized to 1282x855 2.07MB - no issues for PictureVal and it resizes nicely. For most images, quality reduction is not noticeable. However, quality reduction is noticeable for heavily detailed images - something picky users will complain about. So, we may give users the resizing option.

Other solutions: Scrollable image containers, ActiveX controls, etc. were tried, but didn't jibe with our app design.
 
VFP samples include dawing on the titlebar of a window, I don't think you need a specialty, actually an empty form is/has a canvas you can draw on. A container would just make the coordinates. You don't need to compare this with HTML5 canvas drawing.

Proof of Concept:

Code:
Do system.app && gdiplusx system.app
oDrawing = _screen.system.Drawing

_screen.addobject('Container1','Container')

loBmp = oDrawing.Bitmap.FromFile(GetFile('bmp'))
loRect = loBmp.GetBounds()
loGfx = oDrawing.Graphics.FromHWnd(_screen.HWnd)
loGfx.DrawImage(loBmp,_screen.container1.left,_screen.container1.top,_screen.container1.width, _screen.container1.height, loRect)

Now what's missing is explicitly using memory management methods like

Code:
loGfx.Dispose()
loBmp.Dispose()

No fear, the image will still be there. Code samples you find usually don't include such explicit garbage collection calls.
There's something else that's not as usual, once you wipe the program editor window over that container region, the image disappears, it's not an image control that also handles several Windows events about clipping and redrawing/refreshing.

There's some work to do, if you need to be fully compatible, but in other situations like full screen POS or kiosk systems that can already suffice. And mouse pointer will not wipe away the graphics.

Some more things to consider: Since this draws on a form by its HWND, the rectangle you draw on will not automatically be clipped by overlapping containers, when you draw on the container rectangle, this will not draw on the container "canvas", it has none, it shares the form canvas, you'll see the draw even if the container is on an inactive page of a pageframe, for examüle, so those things would need to be handled by your image control code. But you have more control over the disposing of resources and thus memory usage and garbage collection.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Well, and there's one more obvious alternative, of course: An ActiveX control. I don't see, know, or remember a discussion about such controls, as VFP has its image control and it works alright for usual cases. I think you'd have to search back long ago when some either very old or very modern picture format wasn't supported by VFPs image control. I remember PictureVal introduction also meant first PNG support including alpha transparency, but only SP1 fixed issue with that. There likely are ActiveX image controls that covered that earlier. Or support vector image formats besides standards like JPG.

A very far fetched construct would be using the web browser control showing an image, that'll be overkill and also not good for memory consumption, I fear.

Bye, Olaf.



Olaf Doschke Software Engineering
 
there's one more obvious alternative, of course: An ActiveX control. I don't see, know, or remember a discussion about such controls

There's the Microsoft Forms Image Control, which seems to work with VFP. I've never used it, so I don't know whether it would overcome this problem.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If it's a reproducible phenomenon it should be easy to test. VFP just comes with redistribution licenses for the common controls, but I guess the Forms Image control is available everywhere MS Office is installed. You just find a lot of forum questions about Forms controls and Office 2016 or more modern Office versions, so this would perhaps need to ensure Office Forms controls exist.

Even if you'd not use GDIplusX, VFP uses GDI+ to draw all of its controls and UI. Just starting native VFP 9 IDE I see the VFP9.exe process use ~200 GDI objects. Just moving around _screen a bit to see task manager and VFP in parallel I'm at a few more. Just starting GetFile() to select a picture adds 40 GDI objects even before picking any file.

There's nothing to worry about bigger numbers up to a few thousands, simply see what other processes use. But if it doesn't also reduce when forms close, that would be a sign of a GDI resource leak. You may check out Sys(1104) to let VFP dispose unused memory. I would go for more direct GDI+ related handles and objects, though, once you identified it's a graphics problem. There should also be API functions to see GDI resource usage. There is GetGuiResources:
Last not least, actually the image control seems to remain neutral to GDI resource usage, I don't get a rise when adding an image control or setting its PictureVal.

Bye, Olaf.

Olaf Doschke Software Engineering
 
I guess the Forms Image control is available everywhere MS Office is installed

I think that's right. I know that you can use an ActiveX image control within Excel (separately from Excel's native image control), so I assume that is the Forms control. At least, I can't think what else it might be.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top