1

我正在创建一个使用 flycapture 相机的程序。我创建了一个扩展pictureBox 类的类,以便在屏幕上绘制一个由两条线组成的十字准线。我希望能够将十字准线从中心移动到屏幕上的任何其他位置。

问题是当窗体调整大小时,十字准线移动到不同的位置,如图所示。我希望十字准线与调整大小之前指向图像的同一部分(在示例中,它不再指向灰色网格)。我正在绘制与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;
    }
}

我现在有一条与图像一起缩放的线,但现在它一直在闪烁。

4

1 回答 1

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()来显示坐标标记。一个警告是,如果图像仍在显示中,PictureBoxPictureBoxSizeMode.Zoom可能仍需要考虑该值。

于 2017-09-22T17:09:23.200 回答