You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入父Grid的TransformedBitmap鼠标坐标转像素坐标问题求解

修复方案

问题根因

异常由你代码最后的模运算逻辑导致:p = new Point((p.X + w) % w, (p.Y + h) % h); 这行代码会把所有负坐标、大于图像尺寸的坐标全部折叠回[0, 原始图像宽度)、[0, 原始图像高度)的区间内,完全丢失了坐标位于图像外的信息,所以才会出现灰色区域的点被误判为在图像范围内的问题。

修复代码

直接删除模运算逻辑,保留逆变换后的原始坐标值即可,负数、大于图像尺寸的数值本身就能直接反映点在图像外的状态,调整后的TheGrid_MouseMove代码如下:

private void TheGrid_MouseMove(object sender, MouseEventArgs e)
{
    // 直接获取鼠标相对于Image控件的坐标,不需要额外Translate转换
    Point p = e.GetPosition(TheImage);
    if (TheImage.Source is BitmapSource bs)
    {
        // 控件坐标映射为当前显示位图的像素坐标
        p = new Point(
            p.X * bs.PixelWidth / TheImage.ActualWidth, 
            p.Y * bs.PixelHeight / TheImage.ActualHeight
        );
        
        bool isInImage = false;
        if (TheImage.Source is TransformedBitmap tb)
        {
            // 逆变换回原始位图的坐标空间
            Matrix inverse = tb.Transform.Value;
            inverse.Invert();
            inverse.OffsetX = 0.0;
            inverse.OffsetY = 0.0;
            p = inverse.Transform(p);
            
            int originalW = tb.Source.PixelWidth;
            int originalH = tb.Source.PixelHeight;
            // 边界校验,判断坐标是否在原始图像有效范围内
            isInImage = p.X >= 0 && p.X < originalW && p.Y >= 0 && p.Y < originalH;
        }
        
        // 输出坐标和边界状态,p值本身不会被折叠,超界区域会保留负数值或大于宽高的数值
        TheLabel.Content = $"像素坐标:{p.ToString()} | 是否在图像内:{isInImage}";
    }
}

业务适配说明

对于ROI选择的需求:

  • 图像内的坐标会落在0 ≤ X < 原始图像宽度、0 ≤ Y < 原始图像高度区间内,可直接使用
  • 超界区域的坐标会保留原始值(负数值、大于对应维度尺寸的数值),既可以准确判断超界状态,也可以保留用户选择超界区域的所有坐标信息。
    如果有截取有效像素的需求,可在需要取值的时候再单独做截断/模运算处理,不要修改原始坐标值即可。

内容的提问来源于stack exchange,提问作者Craig W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:06:03