当我在WPF应用程序中显示JPEG时(使用下面的代码),它显示的显着小于我在Windows Picture Viewer中以实际大小打开JPEG的时间。
我已经在运行时钻进了我的ImageSource的属性,我的图像有:
当我使用屏幕标尺测量图像的WPF显示时,我得到约。 313x240像素(如果我能完美地定位标尺,可能会等于ImageSource报告的宽度和高度。)。
我的直觉告诉我这与WPF使用独立于设备的单元(而不是像素)有关,但我无法理解它,我仍然需要知道如何在'实际'显示图像在我的申请中大小为543x713。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<Image Source="Image15.jpg" Stretch="None" />
</StackPanel>
</Window>
答案 0 :(得分:8)
谢谢马克!我根据您的信息做了一些谷歌搜索,发现this article提供了一个解决方案,以获得我想要的结果。现在开始变得有意义......
编辑:Linkrot。粘贴文章中的关键文本以供参考....
<Image Source=”{Binding …}”
Stretch=”Uniform”
Width=”{Binding Source.PixelWidth,RelativeSource={RelativeSource Self}}”
Height=”{Binding Source.PixelHeight,RelativeSource={RelativeSource Self}}” />
这里我们将Stretch设置为Uniform并将Width和Height绑定到PixelWidth和&gt; Source的PixelHeight,实际上忽略了DPI。然而,即使使用SnapToDevicePixels(其仅简单地捕捉边界而不是图像内的像素),图像将不是像素>完美的。但是,3.5 SP1中的WPF将支持NearestNeighbor&gt; BitmapScalingMode,它应该纠正这个。
答案 1 :(得分:4)
使用DPI为96. WPF根据英寸大小缩放图像,而图像查看器显示像素。在大多数Windows系统上,屏幕分辨率假定为96 DPI,因此在图像中使用它将导致一对一的翻译。
答案 2 :(得分:3)
或者,你可以扩展Image并实现MeasureOverride和ArrangeOverride来改变图像DPI的效果:
class DpiAgnosticImage : Image
{
protected override Size MeasureOverride(Size constraint)
{
var bitmapImage = Source as BitmapImage;
var desiredSize = bitmapImage == null
? base.MeasureOverride(constraint)
: new Size(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
var dpiScale = MiscUtil.GetDpiScale(this);
desiredSize = new Size(desiredSize.Width / dpiScale.Width, desiredSize.Height / dpiScale.Height);
desiredSize = ImageUtilities.ConstrainWithoutDistorting(desiredSize, constraint);
if (UseLayoutRounding)
{
desiredSize.Width = Math.Round(desiredSize.Width);
desiredSize.Height= Math.Round(desiredSize.Height);
}
return desiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
return new Size(Math.Round(DesiredSize.Width), Math.Round(DesiredSize.Height));
}
}
在xaml中使用它,就好像它是一个Image:
<Grid>
<local:DpiAgnosticImage
Stretch="None"
Source="{Binding ViewImage}">
<Image.RenderTransform>
<ScaleTransform
x:Name="SomeName"/>
</Image.RenderTransform>
</local:DpiAgnosticImage>
</Grid>
以上代码的缺陷(我知道):
===编辑 - Will的评论表明他想知道GetDpiScale()中的内容
public static Size GetDpiScale(Visual visual)
{
var source = PresentationSource.FromVisual(visual);
var dpiScale = new Size(
source.CompositionTarget.TransformToDevice.M11,
source.CompositionTarget.TransformToDevice.M22);
return dpiScale;
}
答案 3 :(得分:1)
这是.jpg文件本身指定DPI的结果 - WPF只是服从。 Here is a forum post通过一些解决方案详细说明问题: