我正在创建一个使用flycapture相机的程序。我创建了一个扩展pictureBox类的类,以便在屏幕上绘制一条由两条线组成的十字准线。我希望能够将十字准线从中心移动到屏幕上的任何其他位置。
问题是当表单调整大小时,十字准线移动到另一个位置,如here所示。我希望十字准线指向与调整大小之前相同的部分(在示例中它不再指向灰色网格)。我正在绘制与 pictureBox 的高度和宽度相关的十字准线。我希望能够在图像上绘制线条,但无论图像的大小如何,图像的高度和宽度始终相同。
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建议的那样,我现在正在绘制图像本身,而不是使用上面的Paint函数。
这是设置的图像:
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;
}
}
我现在有一条与图像一起缩放的线,但现在它一直在闪烁。
答案 0 :(得分:0)
这不准确,但修改为以下内容将使图片框调整大小时保持位置静态;
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);
}
}
}
修改强> 上述解决方案概述了保持线位置的概念。根据下面评论中的讨论,随着对原始意图的调查和测试上述解决方案的额外要求 - 在图像上干净地绘制坐标标记,这已成为OP的更复杂的解决方案。
为此,建议在该场景中使用手动双缓冲机制,因为PictureBox
控件本身支持有限的绘图功能。可以在此处找到手动实现双缓冲解决方案的示例; https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-manually-render-buffered-graphics
不是调用DrawEllipse()
,而是调用DrawLine()
来显示坐标标记。需要注意的是,如果图像仍在PictureBox
中显示,则可能仍需要考虑PictureBoxSizeMode.Zoom
值。