【C#/WPF】修改图像的DPI、Resolution

原文: 【C#/WPF】修改图像的DPI、Resolution

问题:
WPF中默认使用的图像的DPI是96。若是咱们使用的图素的DPI不是96时(好比是72),那么WPF会把图片的DPI自动改成96,致使图像加载出来的实际大小Width和Height会比想要的大(原图显示大小会是实际图大小的72/96 = 3/4),好比图片会在Image控件内显示超框了。markdown

如何发现问题的:
这个问题是Debug中从Bitmap身上的HorizontalResolution、VerticalResolution属性发现的。(Resolution本应该为72,却变成了96)。Bitmap在转为BitmapImage 时,会致使原图的DPI从72变为96!spa

思路:想办法将DPI从96修改回设计的72。.net

WPF的Image控件显示图片时,控件要求的Source赋值类型为ImageSource,该类型及其子类均可以用于给Image控件设置图片,继承关系:设计

BitmapImage --> BitmapSource --> ImageSource

即便用以上三种的任一类型均可以给Image控件赋值图源。选择根据实际需求,由于还要考虑到类型间的转换。
因为这些类型不通用(BitmapImage 类暂时只看到WPF在用到),如今要改用通用的Bitmap类型。即操做Bitmap类型,最后再转型为BitmapImage (或BitmapSource / ImageSource)给前台Image控件使用。(能够写一个XAML的转换器,或者Controller层转型)。code

想经过代码动态修改每张图片的DPI,发现BitmapImage类身上与DPI相关的属性基本上都是只读的。而Bitmap类身上的HorizontalResolution和VerticalResolution属性是只读的,但有一个SetResolution()方法。能够使用该方法修改Resolution了。blog

还有一种比较另类的方法。BitmapImage身上DecodePixelWidth和DecodePixelHeight可读可写,并且该属性也会影响到图像显示的真实宽高。那么能够在不改变DPI的状况下,改变这两个属性来实现图像的缩放。代码以下:继承

public static void ModifyBitmapImageDecodePixel(BitmapImage bi, System.Drawing.Bitmap bitmap)
{
    double scale = 72.0 / 96.0; // 由于Bitmap转BitmapImage时,DPI从96变成了72,致使图像变大。
    bi.DecodePixelWidth = (int)(bitmap.Width * scale);
    bi.DecodePixelHeight = (int)(bitmap.Height * scale);
}

小结:修改DPI或Resolution最终均可以修改图像的真实显示大小。图片

本文仅是记录一下WPF有这么一个默认图像DPI是96的坑。get