如何在缩放的图像上绘图?

2023-12-12

我有一个图片框Size我的应用程序中为 400X400。这SizeMode图片框的设置为Zoomed。我在图片框中加载了一张700X446的png图像。

enter image description here

我有以下问题,

尽管我沿着红色路径绘制一条黑色直线,但实际上它是沿着加载的图像以透视方式显示的。

我该如何解决这个问题?

P.S.我只想在图像上绘制,而不是整个图片框。

源代码:

 public partial class MainForm : Form
 {
    Bitmap _inputImage = null;
    //Graphics _imageGraphics = null;

    #region ctor
    public MainForm()
    {
        InitializeComponent();

        _inputImage = Bitmap.FromFile(@"E:\cracked.png") as Bitmap;

        this.inputImagePictureBox.Image = _inputImage;
    }
    #endregion

    #region Mouse Up and Down
    Point _startPoint = Point.Empty;

    private void left_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            _startPoint = e.Location;

            Circle tempCircle = new Circle(_startPoint, 10);

            Bitmap tempImage = (Bitmap)_inputImage.Clone();

            Graphics g = Graphics.FromImage(tempImage);

            tempCircle.Draw(g);

            inputImagePictureBox.Image = tempImage;
        }
    }

    private void pressed_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            if (_startPoint != e.Location)
            {
                Line tempLine = new Line(_startPoint, e.Location);

                Bitmap tempImage = (Bitmap)_inputImage.Clone();

                Graphics g = Graphics.FromImage(tempImage);

                tempLine.Draw(g);

                inputImagePictureBox.Image = tempImage;
            }
        }
    }

    Bitmap _savedImage;

    private void left__MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            if (_startPoint != e.Location)
            {
                Line tempLine = new Line(_startPoint, e.Location);

                Bitmap tempImage = (Bitmap)_inputImage.Clone();

                Graphics g = Graphics.FromImage(tempImage);

                tempLine.Draw(g);

                _savedImage = tempImage;

                inputImagePictureBox.Image = tempImage;
            }
            else
            {
                Bitmap tempImage = (Bitmap)_inputImage.Clone();
                Graphics g = Graphics.FromImage(tempImage);

                inputImagePictureBox.Image = tempImage;
            }
        }
    } 
}

您需要解决两个问题:

  • Clip the Graphics实际面积Image而不是整个PictureBox.ClientArea

  • Scale接收和记录鼠标事件时鼠标事件相对于实际图像的坐标,以及当您使用它们在绘图中绘制时再次返回的坐标Paint event.

对于两者我们都需要知道zoom的因素Image;对于剪辑我们​​还需要知道ImageArea为了绘图,我只存储两个鼠标位置。

这是我使用的类级别变量:

PointF mDown = Point.Empty;
PointF mLast = Point.Empty;
float zoom = 1f;
RectangleF ImgArea = RectangleF.Empty;

请注意,我使用floats对于所有人来说,因为我们需要进行一些划分..

首先我们要计算zoomImageArea:

void GetImageScaleData(PictureBox pbox)
{
    SizeF sp = pbox.ClientSize;
    SizeF si = pbox.Image.Size;
    float rp = 1f * sp.Width / sp.Height;   // calculate the ratios of
    float ri = 1f * si.Width / si.Height;   // pbox and image

    if (rp > ri)
    {
        zoom = sp.Height / si.Height;
        float width = si.Width * zoom;
        float left = (sp.Width - width) / 2;
        ImgArea = new RectangleF(left, 0, width, sp.Height);
    }
    else
    {
        zoom = sp.Width / si.Width;
        float height = si.Height * zoom;
        float top = (sp.Height - height) / 2;
        ImgArea = new RectangleF(0, top, sp.Width, height);
    }
}

每次新的调用时都应调用此例程Image已加载并且也可以在任何Resizing of the PictureBox:

private void pictureBox1_Resize(object sender, EventArgs e)
{
    GetImageScaleData(pictureBox1);
}

现在需要存储鼠标位置。既然他们一定是调整大小后可重复使用我们需要将它们转换为图像坐标。这个例程可以做到这一点,也可以再次返回:

PointF scalePoint(PointF pt, bool scale)
{
    return scale ? new PointF( (pt.X - ImgArea.X) / zoom, (pt.Y - ImgArea.Y) / zoom)
                 : new PointF( pt.X * zoom + ImgArea.X, pt.Y * zoom + ImgArea.Y);
}

最后我们可以编写代码Paint event

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    using (Pen pen = new Pen(Color.Fuchsia, 2.5f) { DashStyle = DashStyle.Dot})
        e.Graphics.DrawRectangle(pen, Rectangle.Round(ImgArea));

    e.Graphics.SetClip(ImgArea);
    e.Graphics.DrawLine(Pens.Red, scalePoint(mDown, false), scalePoint(mLast, false));
}

..和鼠标事件:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = scalePoint(e.Location, true);
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        mLast = scalePoint(e.Location, true);
        pictureBox1.Invalidate();
    }
}

enter image description here

对于更复杂的绘图,您可以将坐标存储在List<PointF>并将它们转换回来,就像上面一样......:

List<PointF> points = new List<PointF>();

进而:

e.Graphics.DrawCurve(Pens.Orange, points.Select(x => scalePoint(x, false)).ToArray());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在缩放的图像上绘图? 的相关文章

  • 实体框架 - sql server 表中未设置默认值

    SQL Server 2005 数据库表有一列 createdon 其默认值设置为 getdate 我正在尝试使用实体框架添加记录 createdon 列未更新 我是否错过了实体框架中的任何属性 请提出建议 这是实体框架存在的少数问题之一
  • 任务计划程序控制台输出在哪里? (C# 控制台应用程序)

    我正在运行 C Windows 控制台应用程序 并通过任务计划程序传递几个参数 它全天运行 将其他应用程序创建的平面文件数据加载到 SQL Server 中 该程序间歇性失败 并且我有 Try Catch 逻辑 该逻辑使用 Console
  • C++ 编译器可以对结构中的元素重新排序吗

    C 编译器 特别是 g 可以对结构体的内部元素重新排序吗 我看到一些奇怪的行为 其中我有一个包含如下内容的结构 Struct SomeStruct long someLong long someLongArray 25 unsigned l
  • 查找周边上的点来表示边界/形状

    我有一个简单的二维网格 其格式为myGrid x y 我正在尝试找到一种方法来找到所选网格周围的周长 这样我就有了所选网格的形状 这是我的意思的一个例子 这里的想法是找到所有相关的 角点 也就是图像周边的红点 放入一个列表中 这样我就可以从
  • 运行命令行进程并在该进程仍在运行时获取输出?

    如何运行命令行进程并在该进程仍在运行时获取输出 我的意思是使用自己的进度条运行 CLI 进程 可执行文件本身需要很长时间才能完成操作 所以我想从自己的进程中获取进度信息来显示我的应用程序中的进度 否则我不这样做在进程完成之前没有任何信息来显
  • iPhone 编程游戏

    使用 Objective C 还是 C 为 iPhone 编写游戏最好 像 Flight Control 这样的游戏会用什么语言编写 图形应采用什么格式才能在 iPhone 上正确显示并快速加载 像 Flight Control 这样的游戏
  • C# 从整数反序列化枚举

    是否可以从 C 中的 int 反序列化枚举 例如如果我有以下课程 class Employee public string Name get set public int EmployeeTypeID get set 我可以轻松地从 XML
  • 带有 Prism 区域适配器的 AvalonDock

    我看到了一些关于 SO 的问题 但似乎没有一个适合我 我希望能够使用伟大的使用 Prism 4 但是 所有示例区域适配器均适用于 Avalondock 1 x 系列 我无法使其工作 有人有关于如何为 AvalonDock 的 LayoutD
  • C# 中 value 为匿名类型的字典

    是否可以在 C 中创建一个System Collections Generic Dictionary
  • 在浏览器中测试wcf服务

    我无法在浏览器中调用基本的 wcf web 方法 即使使用
  • 在 4.x 内核上的 64 位内存中查找系统调用表

    我正在尝试编写一个简单的内核模块来查找 Linux 中的 sys call table 但遇到了一些麻烦 我在这里找到了 32 位 Linux 的基本指南 https memset wordpress com 2011 03 18 sysc
  • ASP.NET Core中间件如何进行DI?

    我正在尝试将依赖项注入到我的中间件构造函数中 如下所示 public class CreateCompanyMiddleware private readonly RequestDelegate next private readonly
  • 允许使用 AutoMapper 或类似工具映射动态类型吗?

    我已经开始使用https github com robconery massive https github com robconery massive对于一个项目 我想知道是否有任何映射工具可以支持动态到静态类型的映射 我以前使用过 Au
  • 从资源文件获取 DisplayName [重复]

    这个问题在这里已经有答案了 我在 App GlobalResources 文件夹中有特定于文化的资源文件 现在我需要从此资源文件中读取 DisplayName 属性的值 我在用 Display Name MerchantName Resou
  • 为什么 istream/ostream 慢

    于 50 40http channel9 msdn com Events GoingNative 2013 Writing Quick Code in Cpp Quickly http channel9 msdn com Events Go
  • 实例着色器矩阵的设置

    我想绘制实例立方体 我可以打电话GL DrawArraysInstanced PrimitiveType Triangles 0 36 2 成功地 我的问题是所有立方体都绘制在相同的位置和相同的旋转 我如何为每个立方体单独更改它 要创建不同
  • 所有区域的启用保护模式必须设置为相同的值(启用或禁用)

    我正在尝试使用Selenium Internet Explorer驱动程序 但当我尝试实例化它时它崩溃了 TestInitialize public void TestInitialise ieDriver new InternetExpl
  • 为 winforms ComboBox 中的单个项目着色?

    我遇到了一个困境 我有一个表单 其中包含许多组合框 其中包含在某些情况下可能无效 过时的信息 选项 项目 我不能简单地从项目中删除过时的信息 但我确实想在选项无效时为用户提供视觉线索 我正在考虑对项目进行着色 可能是红色 来指示它们是否无效
  • wpf中的图像问题(图像不显示)

    我不明白为什么我无法在 WPF 中显示图像 也许我不小心修改了我的资源文件夹 这就是我没有显示的原因 所以我创建了一个新的 wpf 应用程序 我有这个 当我运行该程序时 我的图片显示为 为什么当我尝试在程序中执行相同的操作时 图像没有显示
  • 文件按文件名模式存在

    我在用 File Exists filepath 我想做的是将其替换为模式 因为文件名的第一部分发生了变化 例如 该文件可以是 01 peach xml 02 peach xml 03 peach xml 如何根据某种搜索模式检查文件是否存

随机推荐

  • 定期画线

    我现在的情况是 我想在一段时间内一条一条地画线 我尝试使用线程来做到这一点 但它对我不起作用 目标是我有 5 行 这些线应该一根接一根地绘制 延迟 5 秒 在 onDraw 方法中使用 Thread sleep 5000 但所有线都是在 5
  • 使用 HTML 表单验证仅验证可见字段?

    我有两组表单字段 每组中都有一些具有必填属性的字段 但是 根据用户选择的内容 一组可能会被隐藏 并且这些字段不应包含在 HTML 表单验证中 到目前为止 如果我的表单中只有一个可见容器并且我填充了所有必填字段 我的表单将不会提交 由于某种原
  • Apache POI:如何添加对角边框

    我想用Apache POI画画Diagonal Border但我找不到任何函数可以支持该功能 我试过这个设置边框对角线但它不起作用 XSSFSheetConditionalFormatting my cond format layer my
  • Cakephp:插入tinyint字段时。仅获取“0”或“1”

    我是 cakephp 的菜鸟 从事开源项目 问题是 当我为某个表插入一个值 is adjusted tinyint 时 我的 php 代码成功执行 但该表仅采用 0 或 1 作为其值 示例代码 reward ta customer rewa
  • 使用 iPhone 进行移动设备管理

    任何人都可以给我提供一些有关 iOS4 的 iphone 设备管理的信息吗 1 如何实现它以及它将如何工作 2 它是否可以仅与企业许可证持有者一起使用 或者我们可以简单地实施开发人员许可证 3 任何具体文档或帮助 Thanks 1 如何实现
  • Swift:将图像添加到 CAShapeLayer

    我有一个带有填充颜色的 CAShapeLayer 并且想要在此形状的中心添加一个图标 var shape CAShapeLayer shape fillColor UIColor white 0 90 alpha 1 CGColor var
  • 如何将按位运算应用于 JS 数字的实际 IEEE 754 表示?

    在 JavaScript 中 每当您执行按位运算时 例如x lt lt 2 在实际发生移位之前 64 位浮点表示形式会转换为 32 位无符号整数 我有兴趣将这种转换应用于实际的 未改变的 IEEE 754 位表示 这怎么可能 您可以尝试先将
  • 生成 ASCII 艺术文本的 PHP 库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在尝试制作一个与使用 ASCII 艺术文本的其他系统不同的验证码系统 类似可以查到的here 有谁知道可以生成类似内容的库 您链接使用的 ASC
  • Codeigniter - 在特定视图上加载特定的 JS 库

    我正在尝试加载谷歌地图 API 即
  • 如何在 django 模板中执行查询过滤

    我需要从 django 模板中执行过滤查询 以获取与视图中的 python 代码等效的一组对象 queryset Modelclass objects filter somekey foo 在我的模板中我想做 for object in d
  • 无法解析绑定。敲除错误

    这是我学习淘汰赛的第二天 尝试附加 deleteItem 以进行按钮单击 它给出以下错误 Error 未捕获的错误 无法解析绑定 消息 ReferenceError deleteItem 未定义 绑定值 点击 deleteItem Java
  • 无法从本地 App Engine 开发服务器访问 BigQuery

    这具体是一个与 python Google App Engine 应用程序和 Google BigQuery 之间的服务器到服务器身份验证相关的问题 但可能与其他云服务相关 太棒了 是否可以让 App Engine 本地开发服务器通过远程
  • 如何使用 GatsbyJS 根据路由渲染组件?

    我在用着GatsbyJS我正在尝试渲染一个不同的header根据URL的路由 例子 mydomain com gt 应该渲染HeaderLanding mydomain com blog gt 应该渲染HeaderMain 有谁知道创建条件
  • 尝试后 sys.exit 无法按预期工作:

    我尝试了以下脚本 我的本意是如果下面代码段中的命令 command a 执行成功 则程序结束 否则 它会执行附加处理 usr bin python import subprocess try command command a subpro
  • 如何创建 JSON 以匹配/序列化到 WCF Rest 服务中的 DataContract

    界面 namespace SQRT WCF DataContract public class PlaceOrder DataMember public string claimID get set DataMember public st
  • JQuery 3.5.1 并拒绝执行内联脚本,因为它违反了以下内容安全策略指令:

    我将 jQuery 从 2 1 1 升级到 3 5 1 我开始在 jQuery 中看到这个问题 拒绝执行内联脚本 因为它违反了以下规定 内容安全策略指令 script src self 随机数 YURLOAQRrIwdGEqYSSpHx9Y
  • IBM Watson 视觉识别 - API 密钥无效

    我正在尝试通过 IBM Watson 的 API 来使用视觉识别 这是我发送的 POST 请求 https gateway a watsonplatform net visual recognition api v3 classify ap
  • MATLAB:选择给定范围之外的所有数组

    我想对不属于特定范围的数组内容执行指标 例如 我有一个 1000 行 2 列的数组 我想对一列 假设为第 2 列 中不属于第 50 150 250 300 400 700 和 900 950 行的所有元素执行mean 计算 因此 平均值应根
  • 使用多个帐户登录时,如何一一避免 Changes.list 缩略图上出现 404 错误?

    当我登录多个帐户并对changes list 进行API 调用时 我收到图像缩略图的404 错误 重现该问题的完整步骤如下 使用两个帐户登录 一个是个人 Gmail 帐户 一个是 Google Apps 帐户 分别为 User gmail
  • 如何在缩放的图像上绘图?

    我有一个图片框Size我的应用程序中为 400X400 这SizeMode图片框的设置为Zoomed 我在图片框中加载了一张700X446的png图像 我有以下问题 尽管我沿着红色路径绘制一条黑色直线 但实际上它是沿着加载的图像以透视方式显