c# - How to prevent Graphical stutter when scrolling a large zoomed out picture -


i have large tiff picture (5.9 mb , 13k x 16k reolution) user loads scrollable panel can zoom in/out of, scroll , mark points, regions etc on.

for scrollable double buffered panel using modification of bob powell's awesome zoompicbox panel displays part of picture in view.

the stutter occurs when scrolling image when zoomed out (even if interpolationmode set low)

is there can done (preferably without hardware acceleration)?

the paint event of panel :

protected override void onpaint(system.windows.forms.painteventargs e)     {         if (_image == null)         {             base.onpaintbackground(e);             return;         }          //scale         system.drawing.drawing2d.matrix scalemat = new system.drawing.drawing2d.matrix(_zoom, 0, 0, _zoom, 0, 0);         //move position of scrollbas         scalemat.translate(this.autoscrollposition.x / (_zoom), this.autoscrollposition.y / (_zoom));           e.graphics.transform = scalemat;         e.graphics.interpolationmode = _interpolationmode;          e.graphics.drawimage(_image, new rectangle(0, 0, _image.width, _image.height), 0, 0, _image.width, _image.height, graphicsunit.pixel);           base.onpaint(e);     } 
  • _zoom ,_image , _interpolationmode private fields of control

the constructor:

 public picboxplus()         {             mousemove += picboxplus_mousemove;             keydown += picboxplus_keydown;             this.setstyle(controlstyles.allpaintinginwmpaint | controlstyles.userpaint | controlstyles.resizeredraw | controlstyles.optimizeddoublebuffer, true);              this.autoscroll = true;         } 

edit : attempting caching

i tried implementing sinatr's code wrong, because black image (of right size). has idea wrong?

the new paint event:

 protected override void onpaint(system.windows.forms.painteventargs e)         {             if (mcachedimage == null)             {                 base.onpaintbackground(e);                 return;             }              //scale             system.drawing.drawing2d.matrix scalemat = new system.drawing.drawing2d.matrix(mzoom, 0, 0, mzoom, 0, 0);             //move position of scrollbas             scalemat.translate(this.autoscrollposition.x / (mzoom), this.autoscrollposition.y / (mzoom));              try             {                 if (mcachedimage == null)                 {                     mcachedimage = new bitmap(this.clientsize.width, this.clientsize.height);                     using (var cachegraphics = graphics.fromimage(mcachedimage))                     {                         cachegraphics.transform = scalemat;                         cachegraphics.interpolationmode = _interpolationmode;                         cachegraphics.drawimage(mcachedimage, new rectangle(0, 0, mcachedimage.width, mcachedimage.height), 0, 0, mcachedimage.width, mcachedimage.height, graphicsunit.pixel);                      }                      e.graphics.drawimage(mcachedimage, point.empty);                 }             }             catch (exception ex)             {                 throw ex;             }              base.onpaint(e);         } 

the image , zoom properties:

public bitmap image     {         { return mcachedimage; }         set         {             mcachedimage = value;             updatescalefactor();             this.invalidate();         }     }  public single zoom {     { return mzoom; }     set     {         if (value <= 0||value < 0.001)         {             value = 0.001f;         }          mzoom = value;         updatescalefactor();         resetcache(); // sinatr's function         this.invalidate();     } } 

loading image main form:

panelmap.image = (bitmap)image.fromfile("pic.tiff"); 

is not tested, should give idea.

bitmap _cached = null;  override void onpaint(painteventargs e) {     if(_cached == null)     {         _cached = new bitmap(this.clientsize.width, this.clientsize.height);         using(var graphics = graphics.fromimage(_cached)         {              // draw graphics once -> cached in _cached bitmap         }     }     e.graphics.drawimage(_cached, point.empty); }  // call if _zoom or clientsize changed void resetcache() {     _cache = null;     this.invalidate(); // mandatory _zoom change } 

also, don't know how present zoomed-in picture, there offset can move (pan) image.


Comments

Popular posts from this blog

how to proxy from https to http with lighttpd -

android - Automated my builds -

python - Flask migration error -