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

WPF如何消除Windows缩放影响,获取图像相对坐标?

解决方案:使用WPF官方DPI获取方法转换坐标

在WPF中,官方推荐通过VisualTreeHelper.GetDpi方法获取控件的DPI缩放因子,以此转换鼠标坐标,无需手动计算或读取注册表,完全兼容Windows 10和Windows 11,且不依赖UWP API。

核心思路

VisualTreeHelper.GetDpi会返回当前控件对应的DpiScale对象,其中DpiScaleX和DpiScaleY即为系统对该控件的缩放比例(比如1.5倍缩放时,值为1.5)。将鼠标获取到的缩放后坐标除以对应缩放因子,就能得到不受缩放影响的原始图像相对坐标。

修改后的完整代码

XAML部分(保持原有结构)

<Window x:Class="StackOverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverflow"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="500"
        Width="900">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    
    <Image x:Name="BackgroundImage"
           VerticalAlignment="Top"
           HorizontalAlignment="Left"
           Stretch="None"
           Source="/BingMap.PNG"
           MouseMove="BackgroundImage_MouseMove"/>

    <TextBlock x:Name="TB"
               Grid.Row="2" />
  </Grid>
</Window>

C#代码(修改鼠标移动事件逻辑)

using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace StackOverflow
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }

    private void BackgroundImage_MouseMove(object sender, MouseEventArgs e)
    {
      // 获取鼠标相对于Image控件的缩放后坐标
      var scaledPoint = e.GetPosition(BackgroundImage);
      // 获取Image控件的DPI缩放因子
      var dpiScale = VisualTreeHelper.GetDpi(BackgroundImage);
      // 计算不受缩放影响的原始坐标
      var originalPoint = new Point(
          scaledPoint.X / dpiScale.DpiScaleX,
          scaledPoint.Y / dpiScale.DpiScaleY
      );
      TB.Text = $"缩放后坐标: {scaledPoint.X:n0}, {scaledPoint.Y:n0} | 原始坐标: {originalPoint.X:n0}, {originalPoint.Y:n0}";
    }
  }
}

关键说明

  1. 控件相对坐标:将e.GetPosition(this)改为e.GetPosition(BackgroundImage),直接获取鼠标相对于Image控件的坐标,更贴合图像相对坐标的需求。
  2. 官方API适配:VisualTreeHelper.GetDpi是.NET Framework 4.6.2及以上版本内置的官方API,会自动适配当前系统的缩放设置,无需手动维护缩放值。
  3. 坐标转换逻辑:缩放后的坐标除以对应缩放因子,即可得到与原始图像尺寸匹配的真实坐标(比如1.5倍缩放时,559/1.5≈839,264/1.5=396,与图像原始尺寸完全一致)。

内容的提问来源于stack exchange,提问作者Eric Harmon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:05:31