C# 调整窗体大小时,为什么线条不与图像的同一部分相交?
我正在创建一个使用flycapture相机的程序。我创建了一个类,它扩展了pictureBox类,以便在屏幕上绘制由两条线组成的十字线。我希望能够将十字线从中心移动到屏幕上的任何其他位置 问题是,调整窗体大小时,十字线将移动到不同的位置,如图所示。我希望十字线指向图像的同一部分,与调整大小之前相同(在本例中,它不再指向灰色网格)。我画的十字线与图片盒的高度和宽度有关。我希望能够在图像上画线,但无论图像大小,图像的高度和宽度始终相同C# 调整窗体大小时,为什么线条不与图像的同一部分相交?,c#,winforms,visual-studio,flycapture,C#,Winforms,Visual Studio,Flycapture,我正在创建一个使用flycapture相机的程序。我创建了一个类,它扩展了pictureBox类,以便在屏幕上绘制由两条线组成的十字线。我希望能够将十字线从中心移动到屏幕上的任何其他位置 问题是,调整窗体大小时,十字线将移动到不同的位置,如图所示。我希望十字线指向图像的同一部分,与调整大小之前相同(在本例中,它不再指向灰色网格)。我画的十字线与图片盒的高度和宽度有关。我希望能够在图像上画线,但无论图像大小,图像的高度和宽度始终相同 using System; using System.Colle
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FlyCapture2SimpleGUI_CSharp
{
class IMSPictureBox : PictureBox
{
private Color colorSetting = Color.Black;
private float width = 1.0f;
public IMSPictureBox()
{
this.Paint += IMSPictureBox_Paint;
}
private void IMSPictureBox_Paint(object sender, PaintEventArgs e)
{
//Draw if image has loaded
if (this.Image != null)
{
//Draw horizontal line
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
new Point(0, this.Size.Height / 2 + 100),
new Point(this.Size.Width, this.Size.Height / 2 + 100));
//Draw vertical line
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
new Point(this.Size.Width / 2 + 100, 0),
new Point(this.Size.Width / 2 + 100, this.Size.Height));
}
}
}
}
编辑:
正如DiskJunky所建议的,我现在在图像本身上绘制,而不是使用上面的绘制功能
以下是图像设置:
private void UpdateUI(object sender, ProgressChangedEventArgs e)
{
UpdateStatusBar();
pictureBox1.SetImage = m_processedImage.bitmap;
pictureBox1.Invalidate();
}
以下是在图像上绘制的线条:
public System.Drawing.Image SetImage
{
set
{
using (Graphics g = Graphics.FromImage(value))
{
g.DrawLine(new Pen(Color.Red, 3.0f), new Point(0, 0), new Point(value.Width, value.Height));
g.Dispose();
}
this.Image = value;
}
get
{
return this.Image;
}
}
我现在有一条线可以随图像缩放,但现在它不断闪烁。这并不准确,但修改为以下内容会在图片框调整大小时保持位置静止
class IMSPictureBox : PictureBox
{
private Color colorSetting = Color.Black;
private float width = 1.0f;
private Tuple<Point, Point> _verticalLine;
private Tuple<Point, Point> _horizontalLine;
public IMSPictureBox()
{
this.Paint += IMSPictureBox_Paint;
}
private void IMSPictureBox_Paint(object sender, PaintEventArgs e)
{
//Draw if image has loaded
if (this.Image != null)
{
//Draw vertical line
if (_verticalLine == null)
{
_verticalLine = new Tuple<Point, Point>(new Point(100, 0), new Point(100, this.Size.Height);
}
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
_verticalLine.Item1,
_verticalLine.Item2);
//Draw horizontal line
if (_horizontalLine == null)
{
_horizontalLine = new Tuple<Point, Point>(new Point(0, 100), new Point(this.Size.Width, 100);
}
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
_horizontalLine.Item1,
_horizontalLine.Item2);
}
}
}
类IMSPictureBox:PictureBox
{
私有颜色colorSetting=Color.Black;
专用浮动宽度=1.0f;
私有元组;
私有元组水平线;
公共IMSPictureBox()
{
this.Paint+=IMSPictureBox_Paint;
}
私有void IMSPictureBox_Paint(对象发送方,PaintEventArgs e)
{
//如果图像已加载,则绘制
如果(this.Image!=null)
{
//画垂直线
如果(_verticalLine==null)
{
_verticalLine=新元组(新点(100,0),新点(100,this.Size.Height);
}
e、 拉丝(
新笔(此.colorSetting,此.width),
_verticalLine.1,
_轮生植物(第2项);
//画水平线
如果(_horizontalLine==null)
{
_水平线=新元组(新点(0,100),新点(this.Size.Width,100);
}
e、 拉丝(
新笔(此.colorSetting,此.width),
_horizontalLine.1项,
_水平线(第2项);
}
}
}
编辑
上述解决方案概述了保留线位置的概念。根据下面评论中的讨论,这已发展成为OP的一个更复杂的解决方案,因为调查和测试上述解决方案的原始目的(在图像上清晰地绘制坐标标记)产生了附加要求
为此,建议在该场景中使用手动双缓冲机制,因为PictureBox
控件本身支持有限的绘图功能。可以在此处找到手动实现双缓冲解决方案的示例
将调用
DrawLine(),而不是调用drawlipse()
显示坐标标记。一个警告是,如果图像仍显示在PictureBox
中,则可能仍需要考虑PictureBoxSizeMode.Zoom
值。这不准确,但修改为以下内容将在图片框调整大小时保持位置静态
class IMSPictureBox : PictureBox
{
private Color colorSetting = Color.Black;
private float width = 1.0f;
private Tuple<Point, Point> _verticalLine;
private Tuple<Point, Point> _horizontalLine;
public IMSPictureBox()
{
this.Paint += IMSPictureBox_Paint;
}
private void IMSPictureBox_Paint(object sender, PaintEventArgs e)
{
//Draw if image has loaded
if (this.Image != null)
{
//Draw vertical line
if (_verticalLine == null)
{
_verticalLine = new Tuple<Point, Point>(new Point(100, 0), new Point(100, this.Size.Height);
}
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
_verticalLine.Item1,
_verticalLine.Item2);
//Draw horizontal line
if (_horizontalLine == null)
{
_horizontalLine = new Tuple<Point, Point>(new Point(0, 100), new Point(this.Size.Width, 100);
}
e.Graphics.DrawLine(
new Pen(this.colorSetting, this.width),
_horizontalLine.Item1,
_horizontalLine.Item2);
}
}
}
类IMSPictureBox:PictureBox
{
私有颜色colorSetting=Color.Black;
专用浮动宽度=1.0f;
私有元组;
私有元组水平线;
公共IMSPictureBox()
{
this.Paint+=IMSPictureBox_Paint;
}
私有void IMSPictureBox_Paint(对象发送方,PaintEventArgs e)
{
//如果图像已加载,则绘制
如果(this.Image!=null)
{
//画垂直线
如果(_verticalLine==null)
{
_verticalLine=新元组(新点(100,0),新点(100,this.Size.Height);
}
e、 拉丝(
新笔(此.colorSetting,此.width),
_verticalLine.1,
_轮生植物(第2项);
//画水平线
如果(_horizontalLine==null)
{
_水平线=新元组(新点(0,100),新点(this.Size.Width,100);
}
e、 拉丝(
新笔(此.colorSetting,此.width),
_horizontalLine.1项,
_水平线(第2项);
}
}
}
编辑
上述解决方案概述了保留线位置的概念。根据下面评论中的讨论,这已发展成为OP的一个更复杂的解决方案,因为调查和测试上述解决方案的原始目的(在图像上清晰地绘制坐标标记)产生了附加要求
为此,建议在该场景中使用手动双缓冲机制,因为PictureBox
控件本身支持有限的绘图功能。可以在此处找到手动实现双缓冲解决方案的示例
将调用
DrawLine(),而不是调用drawlipse()
显示坐标标记。一个警告是,如果图像仍显示在PictureBox
中,则可能仍需要考虑PictureBoxSizeMode.Zoom
值。您的计算是基于图片框的大小绘制的,而不是图像的大小。调整表单的大小会调整图像的大小它触发了绘制
事件,现在坐标不同了。您可以将点
细节存储为类变量,而不是在绘制事件中的每个绘制
上重新计算。这是您的表单,而不是picturebox。处理笔。代码忽略picturebox.SizeM