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

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

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

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

BitmapImage --> BitmapSource --> ImageSource

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

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

还有一种比较另类的方法。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的坑。

【C#/WPF】修改图像的DPI、Resolution的更多相关文章

  1. python 修改图像大小和分辨率

    1 概念: 分辨率,指的是图像或者显示屏在长和宽上各拥有的像素个数.比如一张照片分辨率为1920x1080,意思是这张照片是由横向1920个像素点和纵向1080个像素点构成,一共包含了1920x108 ...

  2. Wpf修改控制的大小

    Wpf修改控制的大小 随窗体的改变而改变 在WINFORM中设置控件的Anchor属性就行了 在WPF中没有Anchor属性 但可以在布局中设置 相关属性实现同样的效果 相关属性 Horizontal ...

  3. WPF 修改图片颜色

    原文:WPF 修改图片颜色 本文告诉大家如何修改图片的颜色,如去掉图片的蓝色 在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件. 在阅读本文,我假设大家 ...

  4. 借助Photoshop,Illustrator等设计软件进行WPF图形图像的绘制

    原文:借助Photoshop,Illustrator等设计软件进行WPF图形图像的绘制 本文所示例子是借助第三方设计软件,制作复杂的矢量图形,转成与XAML酷似的SVG,再转换成xaml而实现的. 这 ...

  5. WPF 修改屏幕DPI,会触发控件重新加载Unload/Load

    修改屏幕DPI,会触发控件的Unloaded/Loaded 现象/重现案例 对Unloaded/Loaded的印象: FrameworkElement, 第一次加载显示时,会触发Loaded.元素被释 ...

  6. WPF图形图像相关类

    BitmapMetadata类: 继承自抽象类ImageMetadata,包含图像的原数据信息,如相机型号.图像修改程序名称.拍照日期.拍照地点等.ImageSoure类包含ImageMetadata ...

  7. 支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发

    Windows 10 自 1703 开始引入第二代的多屏 DPI 机制(PerMonitor V2),而 WPF 框架可以支持此第二代的多屏 DPI 机制. 本文将介绍 WPF 框架利用第二代多屏 D ...

  8. 【C#/WPF】图像数据格式转换时,透明度丢失的问题

    问题:工作中涉及到图像的数据类型转换,经常转着转着发现,到了哪一步图像的透明度丢失了! 例如,Bitmap转BitmapImage的经典代码如下: public static BitmapImage ...

  9. WPF修改窗体标题栏的颜色

    WPF程序通常情况下没办法修改窗体标题栏的样式,包括标题栏的背景颜色. 不过借助一个叫Fluent.Ribbon的第三方控件,貌似可以修改标题栏的背景颜色. 可以通过NuGet来安装这个控件:Inst ...

随机推荐

  1. Android API之android.widget.Filterable

      android.widget.Filterable 定义了一种可过滤的行为.Filterable接口通常有android.widget.Adapter来实现.接口Filterable中有个抽象方法 ...

  2. iOS中的#import和class区别

    在ios中我们经常会在.h和.m中引入一些类啊等等一般用的是#import来进行声明,你们可能也见到在.h文件进用@class来声明的,那么#import和@class进行声明 到底有什么的区别呢?下 ...

  3. PHP5.3新特性

    1.首先对之前滥用的语法进行了规范 众所周知PHP在语言开发过程中有一个很好的容错性,导致在数组或全局变量中包含字符串不使用引号是可以不报错的,很多业余的开发者因为懒惰而产生的安全问题十分严重,之所以 ...

  4. Chrome浏览器桌面通知提示功能使用

    http://www.cnblogs.com/meteoric_cry/archive/2012/03/31/2426256.html

  5. 数组插件----linq.js

    优点 1.支持jQuery插件的方式.jquery.linq.min.js. 2.也可以像普通js方法一样使用.linq.min.js. 3.当然用习惯VS的童鞋肯定希望有个良好的智能感知,是的,它支 ...

  6. 【Linux】忘记root密码

    常常有些朋友在配置好了Linux之后,结果root密码给他忘记去!要重新安装吗?不需要的,你只要以单人维护模式登陆即可更改你的root密码!下面以Redhat linux5为例 1)先将系统重新启动, ...

  7. Fragment中获取Activity的Context

    Fragment中获取Activity的Context时只需要this.getActivity()即可.

  8. 推荐系统学习07-Waffles

    介绍 Waffles 英文原意是蜂蜜甜饼,在这里却指代一个很强大的机器学习的开源工具包. Waffles里包括的算法特别多.涉及机器学习的方方面面,推荐系统位于当中的Waffles_recommend ...

  9. CListCtrl控件中显示进度条

    CListCtrl控件的subitem中显示进度条 http://www.codeproject.com/Articles/6813/List-Control-Extended-for-Progres ...

  10. Objective-C学习笔记(四)——OC实现最简单的数学运算

    本篇帖子会实现使用OC的最简单的加减乘除运算.学习的知识点包含变量定义.运算方法,格式化输出等概念.主要学习主要的语法,事实上和C语言的语法还是比較相似的. 具体代码仅仅要写在main方法中即可了.具 ...