【发布时间】:2014-05-19 08:46:27
【问题描述】:
我有一张大的 TIFF 图片(5.9 MB,13k X 16k 分辨率),用户将其加载到可滚动面板中,然后他可以放大/缩小、滚动和标记点、区域等。
对于可滚动的双缓冲面板,我使用的是 Bob Powell's awesome ZoomPicBox 的修改 面板仅显示当前视图中的图片部分。
缩小时滚动图像时出现卡顿(即使interpolationMode设置为低)。
有什么可以做的吗(最好没有硬件加速)?
面板的绘制事件:
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 to 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 是控件的私有字段。
构造函数:
public PicBoxPlus()
{
MouseMove += PicBoxPlus_MouseMove;
KeyDown += PicBoxPlus_KeyDown;
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
this.AutoScroll = true;
}
然后我尝试实现 Sinatr 的代码,但出现了问题,因为我得到的只是一张黑色图像(大小合适)。有人知道可能出了什么问题吗?
新的绘画事件:
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 to 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);
}
图像和缩放属性:
public Bitmap Image
{
get { return mCachedImage; }
set
{
mCachedImage = value;
UpdateScaleFactor();
this.Invalidate();
}
}
public Single Zoom
{
get { return mZoom; }
set
{
if (value <= 0||value < 0.001)
{
value = 0.001f;
}
mZoom = value;
UpdateScaleFactor();
ResetCache(); // Sinatr's function
this.Invalidate();
}
}
从主窗体加载图像:
panelMap.Image = (Bitmap)Image.FromFile("pic.tiff");
【问题讨论】:
-
如果重绘代价高昂(发生stutter),那么您必须对其进行优化。例如,尝试缓存转换后的图像(您可以从位图创建
Graphics)并在大小/缩放更改时销毁缓存。 -
能否提供一个图片缓存的例子?