我在窗口上绘制位图,我需要模拟ImageLayout.Zoom功能。
这就是我现在正在使用的:
if (_bitmap.Width > _bitmap.Height)
{
ZoomPercent = (int)(((double)ClientRectangle.Width) / ((double)_bitmap.Width) * 100);
}
else
{
ZoomPercent = (int)(((double)ClientRectangle.Height) / ((double)_bitmap.Height) * 100);
}
..其中ZoomPercent是一个属性,允许我更改位图的绘制比例。例如,如果ZoomPercent = 200,它将以200%或2.0的比例绘制它,因此1000x1000位图将绘制为2000x2000。
在我看来,上面的代码应该可行,但事实并非如此。例如,如果位图是800x600,那么宽度更大,如果ClientRectangle是1000x1000,那么它应该计算1000/800 = 1.25 * 100 = 125.所以125%。这将位图拉伸为1000x750,适合ClientRectangle。但它并不适用于所有情况。
答案 0 :(得分:0)
Bob Powell写了一篇关于此的文章:Zoom and pan a picture.
如果链接死亡,这里是该文章发布的代码:
public class ZoomPicBox : ScrollableControl
{
Image _image;
[
Category("Appearance"),
Description("The image to be displayed")
]
public Image Image
{
get{return _image;}
set
{
_image=value;
UpdateScaleFactor();
Invalidate();
}
}
float _zoom=1.0f;
[
Category("Appearance"),
Description("The zoom factor. Less than 1 to reduce. More than 1 to magnify.")
]
public float Zoom
{
get{return _zoom;}
set
{
if(value < 0 || value < 0.00001)
value = 0.00001f;
_zoom = value;
UpdateScaleFactor();
Invalidate();
}
}
/// <summary>
/// Calculates the effective size of the image
///after zooming and updates the AutoScrollSize accordingly
/// </summary>
private void UpdateScaleFactor()
{
if(_image==null)
this.AutoScrollMinSize=this.Size;
else
{
this.AutoScrollMinSize=new Size(
(int)(this._image.Width*_zoom+0.5f),
(int)(this._image.Height*_zoom+0.5f)
);
}
}
InterpolationMode _interpolationMode=InterpolationMode.High;
[
Category("Appearance"),
Description("The interpolation mode used to smooth the drawing")
]
public InterpolationMode InterpolationMode
{
get{return _interpolationMode;}
set{_interpolationMode=value;}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// do nothing.
}
protected override void OnPaint(PaintEventArgs e)
{
//if no image, don't bother
if(_image==null)
{
base.OnPaintBackground(e);
return;
}
//Set up a zoom matrix
Matrix mx=new Matrix(_zoom, 0, 0, _zoom, 0, 0);
//now translate the matrix into position for the scrollbars
mx.Translate(this.AutoScrollPosition.X / _zoom, this.AutoScrollPosition.Y / _zoom);
//use the transform
e.Graphics.Transform = mx;
//and the desired interpolation mode
e.Graphics.InterpolationMode = _interpolationMode;
//Draw the image ignoring the images resolution settings.
e.Graphics.DrawImage(_image, new rectangle(0, 0, this._image.Width, this._image.Height), 0, 0, _image.Width, _image.Height, GraphicsUnit.Pixel);
base.OnPaint(e);
}
public ZoomPicBox()
{
//Double buffer the control
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer, true);
this.AutoScroll=true;
}
}