矩阵变换图像上的 C# 光标位置

标签 c#

我需要有关查找用户双击的图像上的位置的帮助。

我可以从 MouseEventArgs 获取控件上的位置,但需要将其转换为图像尺寸。已使用新的自定义控件对图像进行缩放和平移。

Zoom 和平移功能非常迷人(基于 ZoomPicBox by Bob Powell) 我得到了一个位置,但是从我点击的地方它是完全关闭的,它似乎被一个因素关闭了,但我不知道它是什么。 Double Click Event Code,我自己试过了(矩阵前注释掉了),效果一样,Vector2 Comment是我从Xna找到的引用

    protected override void OnMouseDoubleClick(MouseEventArgs e)
    {
        if (e != null)
        {
            if (e.Button == MouseButtons.Left)
            {
                //_ImgDoubleClick.X = (int)(e.Location.X / this.Zoom) - this.AutoScrollPosition.X;
                //_ImgDoubleClick.Y = (int)(e.Location.Y / this.Zoom) - this.AutoScrollPosition.Y;

                using (Matrix mx = new Matrix(_zoom, 0, 0, _zoom, 0, 0))
                {
                    mx.Translate(this.AutoScrollPosition.X / _zoom, this.AutoScrollPosition.Y / _zoom);

                    //Vector2 worldPosition = Vector2.Transform(mousePosition, Matrix.Invert(viewMatrix));
                    mx.Invert();
                    Point worldPosition = VectorTransform(e.Location, mx);

                    _ImgDoubleClick.X = worldPosition.X;
                    _ImgDoubleClick.Y = worldPosition.Y;
                }
            }

        }            
        
        
        base.OnMouseDoubleClick(e);
    }

    //-------------------------------------
    private Point VectorTransform(Point vector, Matrix matrix)
    {
        //var tempX = (matrix.M11 * vector.X) + (matrix.M21 * vector.Y) + matrix.M31;
        //var tempY = (matrix.M12 * vector.X) + (matrix.M22 * vector.Y) + matrix.M32;

        int tempX = (int)((matrix.Elements[0] * vector.X) + (matrix.Elements[2] * vector.Y) + matrix.Elements[4]);
        int tempY = (int)((matrix.Elements[1] * vector.X) + (matrix.Elements[3] * vector.Y) + matrix.Elements[5]);

        return new Point(tempX, tempY);
    }

下面是 On paint 事件

protected override void OnPaint(PaintEventArgs e)
{
//if no image, don't bother
if (_image == null)
{
    base.OnPaintBackground(e);
    return;
}
//Set up a zoom matrix
using (Matrix mx = new Matrix(_zoom, 0, 0, _zoom, 0, 0))
{
    if (e != null)
    {
        //now translate the matrix into position for the scrollbars
        mx.Translate(this.AutoScrollPosition.X / _zoom, this.AutoScrollPosition.Y / _zoom);
        //use the transform
        e.Graphics.Transform = mx;
        //and the desired interpolation mode
        e.Graphics.InterpolationMode = _interpolationMode;
        //Draw the image ignoring the images resolution settings.
        e.Graphics.DrawImage(_image, new Rectangle(0, 0, this._image.Width, this._image.Height), 0, 0, _image.Width, _image.Height, GraphicsUnit.Pixel);
    }
}
//mx.Dispose();
base.OnPaint(e);
}

缩放系数设置

    public float Zoom
    {
        get
        {
            return _zoom;
        }
        set
        {
            if (value < 0 || value < 0.00001)
                value = 0.00001f;
            _zoom = value;
            UpdateScaleFactor();
            Invalidate();
        }
    }

    //----------------------------------
    /// <summary>
    /// Calculates the effective size of the image
    ///after zooming and updates the AutoScrollSize accordingly
    /// </summary>
    private void UpdateScaleFactor()
    {
        if (_image == null)
            this.AutoScrollMinSize = this.Size;
        else
        {
            this.AutoScrollMinSize = new Size(
              (int)(this._image.Width * _zoom + 0.5f),
              (int)(this._image.Height * _zoom + 0.5f)
              );
        }
    }

我控制的 using 语句。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

最佳答案

似乎我一直都是对的,我的错误是我在图像上画回重点,工作代码。

    private void zoomPicBox1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        int x = zoomPicBox1.ImgDoubleClick.X;
        int y = zoomPicBox1.ImgDoubleClick.Y;
        using (Graphics grD = Graphics.FromImage(_bmp))
        //using (Graphics grD = Graphics.FromImage(zoomPicBox1.Image))
        {
            grD.PageUnit = GraphicsUnit.Pixel;
            grD.DrawEllipse(Pens.Black, x - 4, y - 4, 8, 8);
            grD.DrawEllipse(Pens.Black, x - 3, y - 3, 6, 6);
            grD.DrawEllipse(Pens.Black, x - 2, y - 2, 4, 4);
            grD.DrawEllipse(Pens.Black, x - 1, y - 1, 2, 2);
        }
        this.zoomPicBox1.Invalidate();
    }

我的问题是我使用的是点而不是像素

grD.PageUnit = GraphicsUnit.Point;

但我试图在像素上作画。

关于矩阵变换图像上的 C# 光标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28427412/

相关文章:

c# - 使用 visual studio 服务器资源管理器连接到远程 SQL Server 2012

c# - 尝试从 wsdl 生成服务引用时出错

c# - 在构造函数中将泛型转换为接口(interface)

c# - 我的静音按钮正在停止但无法播放

c# - "as"和可空类型的性能惊喜

c# - 接口(interface)的扩展方法是否被视为比不太具体的方法优先级低?

c# - 在 C# 中可以轻松导入和管理哪种文件类型

c# - 我将如何获得以特定前缀开头的所有 MySQL 数据库使用的总磁盘空间?

c# - 3D 点云分割

c# - 在 Unity C# 中修复挤压网格法线?