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

WPF下如何将鼠标坐标转换为TransformedBitmap对应原始图像像素坐标

问题原因

你的代码错误来源于忽略了TransformedBitmap的自动偏移特性:当你给位图应用旋转、翻转等变换后,变换结果可能会出现负坐标区域,TransformedBitmap会自动将整体内容做平移,让所有内容的坐标都为正值,刚好填满它自身的PixelWidth/PixelHeight尺寸区域。你直接对转换后的像素坐标做逆变换,没有补回这部分自动添加的平移偏移,所以逆变换后的原始坐标计算错误。

解决方案

通过TransformBounds获取变换后的内容边界,补回平移偏移后再做逆变换即可,修正后的TheImage_MouseMove代码如下:

private void TheImage_MouseMove(object sender, MouseEventArgs e)
{
    Point p = e.GetPosition(TheImage);
    if (TheImage.Source is TransformedBitmap tb)
    {
        // 取原始未变换的位图对象
        BitmapSource originalSource = tb.Source;
        // 计算原始位图经过变换后的内容边界
        Rect transformedBounds = tb.Transform.TransformBounds(new Rect(0, 0, originalSource.PixelWidth, originalSource.PixelHeight));
        // 鼠标坐标转成TransformedBitmap对应的像素坐标
        double tx = p.X * tb.PixelWidth / TheImage.ActualWidth;
        double ty = p.Y * tb.PixelHeight / TheImage.ActualHeight;
        // 补回TransformedBitmap自动添加的平移偏移
        Point transformSpacePoint = new Point(tx + transformedBounds.Left, ty + transformedBounds.Top);
        // 逆变换得到原始位图对应的坐标
        Point originalPixelPoint = tb.Transform.Inverse.Transform(transformSpacePoint);
        // 输出,若需要整数像素索引可对X/Y做Round/Floor处理
        TheLabel.Content = originalPixelPoint.ToString();
    }
    else if (TheImage.Source is BitmapSource bs)
    {
        TheLabel.Content = new Point(p.X * bs.PixelWidth / TheImage.ActualWidth, p.Y * bs.PixelHeight / TheImage.ActualHeight).ToString();
    }
}

如果需要获取整数类型的像素索引,对最终的originalPixelPoint的X、Y值做取整处理即可,适配旋转、翻转、缩放等所有Transform支持的变换场景。

内容的提问来源于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 03:27:03