图形以 c# windows 形式绘制不正确
Graphics getting drawn incorrectly in c# windows form
如何确保我的图形绘制在正确的位置?我有一个 windows 表单项目,用户在 pictureBox(面板顶部)中的图像上绘制线条。当图片框处于默认缩放状态时,线条会正确绘制,并且它们会正确响应图像参差不齐的情况。但是,当我尝试在缩放 in/out 时在图像上绘制时,线条的位置发生了偏移(缩小时向上和向左,放大时向下和向右)。 pictureBox 和面板都固定在所有四个边上,而不是停靠。我尝试使用 TranslateTransform( dx, dy ) 方法,但它没有用。我也尝试摆脱我的 CenterBox() 方法。我该如何进行?
这里是缩放代码:
private void trackBar1_Scroll(object sender, EventArgs e) // zoom scale
{
zoom = (float)(0.25 + 0.25 * (trackBar1.Value - 1));
if (trackBar1.Value > 0)
{
pictureBox1.Image = PictureBoxZoom(imgOriginal, new Size(trackBar1.Value, trackBar1.Value));
}
}
public Image PictureBoxZoom(Image img, Size size) //creates zoomed in clone of user image
{
sizeNewx = (Int32) (img.Width * zoom);
sizeNewy = (Int32) (img.Height * zoom);
Bitmap bm = new Bitmap(img, sizeNewx,sizeNewy);
Graphics grap = Graphics.FromImage(bm);
grap.InterpolationMode = InterpolationMode.HighQualityBicubic;
CenterBox(pictureBox1, bm);
return bm;
}
private void CenterBox(PictureBox picBox, Bitmap pic)
{
picBox.Image = pic;
picBox.Location = new Point((picBox.Parent.ClientSize.Width / 2) - (pic.Width / 2),
(picBox.Parent.ClientSize.Height / 2) - (pic.Height / 2));
picBox.Refresh();
}
图形的绘制和缩放方式如下:
private Stack<Line> lines = new Stack<Line>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) //click in box
{
var mouseEventArgs2 = e as MouseEventArgs;
if (e.Button == MouseButtons.Left)
{
lines.Push(new Line { Start = mouseEventArgs2.Location });
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lines.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
lines.Peek().End = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.ScaleTransform(zoom, zoom);
foreach (var line in lines)
{
Pen magenta = new Pen(Color.Magenta, 2);
e.Graphics.DrawLine(magenta, line.Start, line.End);
}
}
好的,找到问题了。问题是你在 mouse move
和 mouse end
中得到的点基本上是 缩放的 ,因为图像被缩放,然后在绘画中你再次缩放它们。所以你需要 un scale them before paint:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) //click in box
{
var mouseEventArgs2 = e as MouseEventArgs;
if (e.Button == MouseButtons.Left)
{
Point[] pnts = new Point[ 1 ];
Matrix scaleMatrix = new Matrix( 1 / zoom, 0, 0, 1 / zoom, 0, 0 ); //un scale
pnts[0]= mouseEventArgs2.Location;
scaleMatrix.TransformPoints( pnts );
lines.Push(new Line { Start = pnts[0] });
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lines.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point[] pnts = new Point[ 1 ];
Matrix scaleMatrix = new Matrix( 1 / zoom, 0, 0, 1 / zoom, 0, 0 ); //un scale
pnts[0]= e.Location;
scaleMatrix.TransformPoints( pnts );
lines.Peek().End = pnts[0];
pictureBox1.Invalidate();
}
}
如何确保我的图形绘制在正确的位置?我有一个 windows 表单项目,用户在 pictureBox(面板顶部)中的图像上绘制线条。当图片框处于默认缩放状态时,线条会正确绘制,并且它们会正确响应图像参差不齐的情况。但是,当我尝试在缩放 in/out 时在图像上绘制时,线条的位置发生了偏移(缩小时向上和向左,放大时向下和向右)。 pictureBox 和面板都固定在所有四个边上,而不是停靠。我尝试使用 TranslateTransform( dx, dy ) 方法,但它没有用。我也尝试摆脱我的 CenterBox() 方法。我该如何进行?
这里是缩放代码:
private void trackBar1_Scroll(object sender, EventArgs e) // zoom scale
{
zoom = (float)(0.25 + 0.25 * (trackBar1.Value - 1));
if (trackBar1.Value > 0)
{
pictureBox1.Image = PictureBoxZoom(imgOriginal, new Size(trackBar1.Value, trackBar1.Value));
}
}
public Image PictureBoxZoom(Image img, Size size) //creates zoomed in clone of user image
{
sizeNewx = (Int32) (img.Width * zoom);
sizeNewy = (Int32) (img.Height * zoom);
Bitmap bm = new Bitmap(img, sizeNewx,sizeNewy);
Graphics grap = Graphics.FromImage(bm);
grap.InterpolationMode = InterpolationMode.HighQualityBicubic;
CenterBox(pictureBox1, bm);
return bm;
}
private void CenterBox(PictureBox picBox, Bitmap pic)
{
picBox.Image = pic;
picBox.Location = new Point((picBox.Parent.ClientSize.Width / 2) - (pic.Width / 2),
(picBox.Parent.ClientSize.Height / 2) - (pic.Height / 2));
picBox.Refresh();
}
图形的绘制和缩放方式如下:
private Stack<Line> lines = new Stack<Line>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) //click in box
{
var mouseEventArgs2 = e as MouseEventArgs;
if (e.Button == MouseButtons.Left)
{
lines.Push(new Line { Start = mouseEventArgs2.Location });
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lines.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
lines.Peek().End = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.ScaleTransform(zoom, zoom);
foreach (var line in lines)
{
Pen magenta = new Pen(Color.Magenta, 2);
e.Graphics.DrawLine(magenta, line.Start, line.End);
}
}
好的,找到问题了。问题是你在 mouse move
和 mouse end
中得到的点基本上是 缩放的 ,因为图像被缩放,然后在绘画中你再次缩放它们。所以你需要 un scale them before paint:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) //click in box
{
var mouseEventArgs2 = e as MouseEventArgs;
if (e.Button == MouseButtons.Left)
{
Point[] pnts = new Point[ 1 ];
Matrix scaleMatrix = new Matrix( 1 / zoom, 0, 0, 1 / zoom, 0, 0 ); //un scale
pnts[0]= mouseEventArgs2.Location;
scaleMatrix.TransformPoints( pnts );
lines.Push(new Line { Start = pnts[0] });
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lines.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point[] pnts = new Point[ 1 ];
Matrix scaleMatrix = new Matrix( 1 / zoom, 0, 0, 1 / zoom, 0, 0 ); //un scale
pnts[0]= e.Location;
scaleMatrix.TransformPoints( pnts );
lines.Peek().End = pnts[0];
pictureBox1.Invalidate();
}
}