由于图像中的 dpi 差异 Canvas 中的项目与其计算的位置不匹配 XAML
Items in Canvas mismatching their calculated positions due to dpi difference in image XAML
我在尝试将方块放在 Canvas 的正确位置时遇到问题,其中包含图像(从 API 接收为 byte[])。有些矩形正确显示,有些有些偏离,有些完全偏离,甚至没有接近应有的位置。
<Viewbox>
<Canvas Height="{Binding ActualHeight, ElementName=img}" Width="{Binding ActualWidth, ElementName=img}">
<Image Name="img" Source="{Binding Image.Image, ElementName=uc}" Stretch="None" />
<Rectangle Canvas.Left="{Binding Image.ImageAttributes.Rect.X, ElementName=uc}" Canvas.Top="{Binding Image.ImageAttributes.Rect.Y, ElementName=uc}" Visibility="{Binding ShowBox, Converter={StaticResource BoolToVisibilityConverter} }" Width="{Binding Image.ImageAttributes.Rect.Width, ElementName=uc}" Height="{Binding Image.ImageAttributes.Rect.Height, ElementName=uc}" Stroke="Red" StrokeThickness="1">
<Rectangle.LayoutTransform>
<RotateTransform Angle="{Binding Image.ImageAttributes.Roll, ElementName=uc}"/>
</Rectangle.LayoutTransform>
</Rectangle>
</Canvas>
</Viewbox>
起初我认为这可能是因为我从 API 中获取了错误的数据值或者后端有问题。经过一天多的调试,我终于弄明白了,这是由于图像中的 DPI。例如:
假设通常某些图像尺寸为 300 x 450,但在 xaml 中 actualHeight/actualWidth 被设置为 400x600。那是因为图像的 dpi 是 72 而 xaml 中的默认 dpi 似乎是 96 (300 / 72 * 96 = 400)。但是 Rectangle 没有考虑到图像尺寸发生变化并绘制在它应该在的地方的事实(例如,来自 DB 的绝对值是:X:30、Y:45、Height:90、 Width:90 现在应该在 X:40、Y:60、Height:120、Width:120 中绘制才正确)尺寸更改后。
我的问题是:有没有办法在显示图像之前对 dpi 进行标准化,或者在将图像发送到 API 进行处理并添加到数据库之前对其进行标准化?
如果没有,我如何调整大小或获取 dpi 差异来计算 Canvas 中其他项目的新值?
返回不要留下未回答的问题。这是解决方案:
<Viewbox>
<Grid>
<Canvas Name="cnvImage" Height="{Binding Height, ElementName=img}" Width="{Binding Width, ElementName=img}">
<Image Name="img" Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" Height="{Binding Source.PixelHeight, RelativeSource={RelativeSource Self}}" Source="{Binding NImage, ElementName=uc}"/>
</Canvas>
<Canvas Name="grAttribute" Height="{Binding Height, ElementName=cnvImage}" Width="{Binding Width, ElementName=cnvImage}">
</Canvas>
</Grid>
</Viewbox>
不需要重新评估或重新计算任何东西。
要完成这项工作,您需要分配
Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" Height="{Binding Source.PixelHeight, RelativeSource={RelativeSource Self}}"
此外,我将矩形的创建拆分到我的 wpf,所以我现在有 2 个 canvas,但这与问题无关。
我在尝试将方块放在 Canvas 的正确位置时遇到问题,其中包含图像(从 API 接收为 byte[])。有些矩形正确显示,有些有些偏离,有些完全偏离,甚至没有接近应有的位置。
<Viewbox>
<Canvas Height="{Binding ActualHeight, ElementName=img}" Width="{Binding ActualWidth, ElementName=img}">
<Image Name="img" Source="{Binding Image.Image, ElementName=uc}" Stretch="None" />
<Rectangle Canvas.Left="{Binding Image.ImageAttributes.Rect.X, ElementName=uc}" Canvas.Top="{Binding Image.ImageAttributes.Rect.Y, ElementName=uc}" Visibility="{Binding ShowBox, Converter={StaticResource BoolToVisibilityConverter} }" Width="{Binding Image.ImageAttributes.Rect.Width, ElementName=uc}" Height="{Binding Image.ImageAttributes.Rect.Height, ElementName=uc}" Stroke="Red" StrokeThickness="1">
<Rectangle.LayoutTransform>
<RotateTransform Angle="{Binding Image.ImageAttributes.Roll, ElementName=uc}"/>
</Rectangle.LayoutTransform>
</Rectangle>
</Canvas>
</Viewbox>
起初我认为这可能是因为我从 API 中获取了错误的数据值或者后端有问题。经过一天多的调试,我终于弄明白了,这是由于图像中的 DPI。例如: 假设通常某些图像尺寸为 300 x 450,但在 xaml 中 actualHeight/actualWidth 被设置为 400x600。那是因为图像的 dpi 是 72 而 xaml 中的默认 dpi 似乎是 96 (300 / 72 * 96 = 400)。但是 Rectangle 没有考虑到图像尺寸发生变化并绘制在它应该在的地方的事实(例如,来自 DB 的绝对值是:X:30、Y:45、Height:90、 Width:90 现在应该在 X:40、Y:60、Height:120、Width:120 中绘制才正确)尺寸更改后。
我的问题是:有没有办法在显示图像之前对 dpi 进行标准化,或者在将图像发送到 API 进行处理并添加到数据库之前对其进行标准化? 如果没有,我如何调整大小或获取 dpi 差异来计算 Canvas 中其他项目的新值?
返回不要留下未回答的问题。这是解决方案:
<Viewbox>
<Grid>
<Canvas Name="cnvImage" Height="{Binding Height, ElementName=img}" Width="{Binding Width, ElementName=img}">
<Image Name="img" Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" Height="{Binding Source.PixelHeight, RelativeSource={RelativeSource Self}}" Source="{Binding NImage, ElementName=uc}"/>
</Canvas>
<Canvas Name="grAttribute" Height="{Binding Height, ElementName=cnvImage}" Width="{Binding Width, ElementName=cnvImage}">
</Canvas>
</Grid>
</Viewbox>
不需要重新评估或重新计算任何东西。
要完成这项工作,您需要分配
Width="{Binding Source.PixelWidth, RelativeSource={RelativeSource Self}}" Height="{Binding Source.PixelHeight, RelativeSource={RelativeSource Self}}"
此外,我将矩形的创建拆分到我的 wpf,所以我现在有 2 个 canvas,但这与问题无关。