Click here to Skip to main content
15,912,457 members
Please Sign up or sign in to vote.
4.33/5 (3 votes)
See more:
I have an application inwhich an image is loaded in imagebox. Then an small rectangle is created and moved to select and zoom selected area. But when I move the rectangle it is responding very slow for high resolution image (1000 ppi).

Any suggestion is welcome and appreciated.
Posted
Comments
Albin Abel 11-Mar-11 7:24am    
What is your rectangle object. How you are moving it. Without seeing your coding snippets it is difficult to guess the problem. Is it WPF?

This delay should not happen. I had this problem and made sure that any image rendering on top of you detail-rich graphics is constant, no matter what the image is.

First of all, let me tell you the resolution is PPI has nothing to do with the problem. What really matter is the part of the image is rendered on screen how much time your rendering takes. When you move you rectangle over you image, some part of your image is masked, some is showing up. You need to invalidate part of the image which trigger the paint event and takes as much time as it does. The following should help:

1) Do not paint on image box. Paint on some control. You can implements pan/zoom, etc. When changing anything on top which require invalidation, use Control.Invalidate with a parameter (region or rectangle) to minimize invalidated area.

2) Classify your operations into faster and slower and introduce cashed image. It should cash only what is currently shown on your screen at the time. If your image is much bigger, cash 2-3 time more (in each direction) to make scrolling in neighbor position fast. On "slow" operation, such as scrolling away, re-write cash and re-render from source. For "fast" operations, such as your rectangle motion, render from cash only. Introduce the operation of cash invalidation.

3) This advice is alternative: switch to WPF. Many your problems are already resolved, and performance is generally much better if you use things correctly.

—SA
 
Share this answer
 
Comments
Espen Harlinn 11-Mar-11 14:02pm    
Good suggestions, my 5
Sergey Alexandrovich Kryukov 11-Mar-11 19:25pm    
Thank you, Espen,
--SA
Olivier Levrey 11-Mar-11 15:34pm    
Cashing the image is quite I suggested. You advised to cash hidden parts of the image even though OP didn't say a word about scrolling, did he?
Sergey Alexandrovich Kryukov 11-Mar-11 19:31pm    
I don't know about scrolling, I only assume there is a lot of graphical data. If all graphical data fits the maximum available screen or less, this is only a special case of a more general case I consider. What works for more general case will work in more special case at the same speed or better. The general case is: you have big and complex constant (or almost constant image) mapped in screen; and the rendering from original data is relatively slow (I don't even consider the speed of one-to-one rendering of pixels on screen as it is very fast (unless someone uses PutPixel or other stupid techniques)). Image is the constant (or rarely changed, for example, showing different sets of layers), but mapping may change. I consider this just to address as general case as possible. I use scrolling only as an example of the considerable re-rendering from original data due to 100% cash-miss.
--SA
SUNILHNBGU 14-Mar-11 8:51am    
Thanks SAKryukov, Can you please review the sample project, and kindly suggest me with the code of this sample project. link: http://www.codeproject.com/KB/graphics/YLScsZoom.aspx.
To make your application always responsive even for big images, I suggest you reduce the resolution of the image displayed to the user (and keep the original one in memory). For example:
http://www.dreamincode.net/code/snippet1986.htm[^]

Modify that code to never exceed a maximum size.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 11-Mar-11 13:23pm    
Olivier, this can be against requirements. In fact, the problem is not so difficult and can be completely eliminated for some fast operations like the one described. It depends on other requirements though. I use to solve this problem. Even when maximum worse-case time was considerable, fast operations did not depend on the image. The key is not using Image Box and proper cashing. Please see my Answer.
(I didn't vote this time.)
--SA
Olivier Levrey 11-Mar-11 15:32pm    
Why not using PictureBox? I am used to this problem as well and I often use double-buffering or kind of equivalent like I suggested in my answer.
Sergey Alexandrovich Kryukov 11-Mar-11 22:21pm    
PictireBox is not designed for doing anything dynamically and in this case would merely sit in the middle adding no value. It is designed to simplify programming and support if the purpose is just to put some image. Control also has double buffering as an option (should be used), but it does not replace cashing I use. (It is just to reduce flicker as you know.) Anything which serves no purpose is a direct or indirect performance hit, kind of.
--SA
Olivier Levrey 12-Mar-11 5:12am    
Ok for PictureBox, I was just curious about it.
However I do not agree about double-buffering. It is used to avoid flickering, it is true, but it is also efficient to improve performance. Drawing directly to the screen using the Graphics argument from the Paint handler is always slow. If you do your drawings in a memory buffer and once it is ready print it to the screen (so you would you use the Graphics argument from the Paint handler only once for a bit-block transfer), then the performances are improved.
Sergey Alexandrovich Kryukov 12-Mar-11 17:43pm    
Yes, absolutely, if you paint on picture box, but this is redundant operation; if you render just on control, you do all rendering in WM_PAINT anyway. Double buffering is actually extra CPU time in this way but needed to remove flicker. Again, using picture box does not help here.
--SA
I suggest to increase step of increment in mouse.move event, or parametrize it in function of current resolution reached ...

i.e.

C#
private void mouseMove(object sender, MouseEventArgs e)
{
   static int lastx,lasty;
   int delta = 100;
   if (abs(lastx-e.X)>delta || abs(lasty-e.y)>delta)>
     {
        lastx=e.X;
        lasty=e.Y;
        ...
        "your zoom box code"
        ...
     }

}
 
Share this answer
 
v4
Comments
Sergey Alexandrovich Kryukov 11-Mar-11 13:20pm    
It does not help much and can be against requirements.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900