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

WinUI 3.0桌面开发:如何让图片上绘制的形状随缩放保持相对位置

WinUI 3 图片标注相对位置自动适配缩放解决方案

最优实现方案(无需手动计算坐标)

核心思路是利用Viewbox的自动等比缩放能力,让图片和标注元素作为整体统一缩放,完全避免手动处理尺寸变化逻辑。

XAML结构修改

将原来Grid第1行第1列的Image控件替换为如下结构:

<Viewbox Grid.Row="1" Grid.Column="1" Stretch="Uniform">
    <!-- Canvas尺寸后续会动态匹配图片原始像素尺寸 -->
    <Canvas Name="drawCanvas">
        <Image Name="myImage" 
               Source="C:\Users\leigh\OneDrive\Documents\Usa.jpg"
               Stretch="Fill"
               ImageOpened="myImage_ImageOpened"
               Width="{Binding ElementName=drawCanvas, Path=Width}"
               Height="{Binding ElementName=drawCanvas, Path=Height}"/>
    </Canvas>
</Viewbox>

配套逻辑代码

1. 同步Canvas尺寸与图片原始尺寸

在图片加载完成事件中,把Canvas的宽高设置为图片的原始像素尺寸:

private void myImage_ImageOpened(object sender, RoutedEventArgs e)
{
    if (myImage.Source is BitmapImage bitmap)
    {
        drawCanvas.Width = bitmap.PixelWidth;
        drawCanvas.Height = bitmap.PixelHeight;
    }
}

2. 动态添加标注

添加标注时直接按原始图片的相对比例计算坐标即可:

// 示例:在图片65%宽度、25%高度位置添加红色圆点标注
var ellipse = new Ellipse()
{
    Width = 20,
    Height = 20,
    Fill = new SolidColorBrush(Colors.Red),
    // 偏移半个标注尺寸,让标注中心对齐目标坐标
    RenderTransform = new TranslateTransform(-10, -10)
};
double targetLeft = drawCanvas.Width * 0.65;
double targetTop = drawCanvas.Height * 0.25;
Canvas.SetLeft(ellipse, targetLeft);
Canvas.SetTop(ellipse, targetTop);
drawCanvas.Children.Add(ellipse);

原理解释

  • Viewbox的Stretch="Uniform"行为和你之前使用的Image缩放逻辑完全一致,会自动等比缩放内部所有内容适配外层Grid单元格大小,不会出现变形。
  • 图片填充满和自身原始尺寸一致的Canvas,所有标注元素的坐标都基于原始图片的尺寸设置,相当于直接在原始图片上绘制标注。
  • 窗口缩放时Viewbox会对Canvas内的图片、标注做整体缩放,二者相对位置永远不会偏移,不需要写任何SizeChanged事件处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:24:03