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
相关产品推荐
相关产品推荐

