更新时间:2023-10-27 23:50:40
这是一个 PictureBox
子类,它不仅支持将缩放应用于 Image
到您在其表面绘制的图形.
Here is a PictureBox
subclass that supports the ability to apply zooming not only to the Image
but also to graphics you draw onto its surface.
它包括一个 SetZoom
函数,通过缩放自身和矩阵来放大.
It includes a SetZoom
function to zoom in by scaling both itself and a Matrix.
它还有一个 ScalePoint
函数,您可以使用它从鼠标事件中接收到的像素坐标计算未缩放的坐标.
It also has a ScalePoint
function you can use to calculate the unscaled coordinates from the pixel coordinates you receive in the mouse events.
这个想法是使用 Transformation Matrix
来缩放 Graphics
对象将在 Paint
事件中绘制的任何像素.
The idea is to use a Transformation Matrix
to scale any pixels the Graphics
object will draw in the Paint
event.
我包含了一些用于测试表单的代码.
I include a little code for the form for testing.
public partial class ScaledPictureBox : PictureBox
{
public Matrix ScaleM { get; set; }
float Zoom { get; set; }
Size ImgSize { get; set; }
public ScaledPictureBox()
{
InitializeComponent();
ScaleM = new Matrix();
SizeMode = PictureBoxSizeMode.Zoom;
}
public void InitImage()
{
if (Image != null)
{
ImgSize = Image.Size;
Size = ImgSize;
SetZoom(100);
}
}
public void SetZoom(float zoomfactor)
{
if (zoomfactor <= 0) throw new Exception("Zoom must be positive");
float oldZoom = Zoom;
Zoom = zoomfactor / 100f;
ScaleM.Reset();
ScaleM.Scale(Zoom , Zoom );
if (ImgSize != Size.Empty) Size = new Size((int)(ImgSize.Width * Zoom),
(int)(ImgSize.Height * Zoom));
}
public PointF ScalePoint(PointF pt)
{ return new PointF(pt.X / Zoom , pt.Y / Zoom ); }
}
这是表单中进行测试的代码:
Here is the code in the Form that does the testing:
public List<PointF> somePoints = new List<PointF>();
private void scaledPictureBox1_MouseClick(object sender, MouseEventArgs e)
{
somePoints.Add(scaledPictureBox1.ScalePoint(e.Location) );
scaledPictureBox1.Invalidate();
}
private void scaledPictureBox1_Paint(object sender, PaintEventArgs e)
{
// here we apply the scaling matrix to the graphics object:
e.Graphics.MultiplyTransform(scaledPictureBox1.ScaleM);
using (Pen pen = new Pen(Color.Red, 10f))
{
PointF center = new PointF(scaledPictureBox1.Width / 2f,
scaledPictureBox1.Height / 2f);
center = scaledPictureBox1.ScalePoint(center);
foreach (PointF pt in somePoints)
{
DrawPoint(e.Graphics, pt, pen);
e.Graphics.DrawLine(Pens.Yellow, center, pt);
}
}
}
public void DrawPoint(Graphics G, PointF pt, Pen pen)
{
using (SolidBrush brush = new SolidBrush(pen.Color))
{
float pw = pen.Width;
float pr = pw / 2f;
G.FillEllipse(brush, new RectangleF(pt.X - pr, pt.Y - pr, pw, pw));
}
}
以下是绘制几个点后的结果,显示了在四种不同缩放设置下的相同点;ScaledPictureBox
显然放在 AutoScroll-Panel
中.线条显示如何使用常规绘图命令..
Here are the results after drawing a few points showing the same points in four different zoom settings; the ScaledPictureBox
is obviously placed in an AutoScroll-Panel
. The lines show how to use the regular drawing commands..