[ATL/WTL]_[初级]_[关于graphics.DrawImage绘图时显示不正常的问题]
场景
1.使用win32绘图时, 最简单的api是使用 graphics.DrawImage(image,x,y)来绘制, 可是这个api有个坑,它的图片显示完整和设备分辨率(显卡)有关.
说明
1.Windows使用以下约定: 1逻辑英寸(logical inch)== 96像素(pixels) == 72 points.
2.我们创建的程序一般是DPI-Aware 程序, 因为这种程序可以避免DWM自动执行DPI缩放, 它该是多少像素就是多少像素, 不会随着设备DPI的变化而变化, 同时DPI-Aware的程序改进了在更高DPI设备上的呈现; 一般在项目文件x.exe.embed.manifest里会看到类似的声明.
Dots per inch (DPI)
Device-independent pixel (DIPs).
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
3.GDI是通过pixel来绘制指定大小的, 它意味着如果你让GDI绘制200x100的矩形, 那么它就会在屏幕上绘制200x100像素的矩形. 不管DPI如何设置. 然而, GDI 字体大小是随着当前DPI设置而缩放的. 换句话来说就是, 如果你创建了一个72-point的字体, 字体的大小将会在96 DPI里是96像素, 在144 DPI里是144 pixels.
DPI setting DIP size
96 1 pixel
120 1.25 pixels
144 1.5 pixels
4.现在说下graphics.DrawImage的绘图被缩放显示不正常的原因, 当用户设备DPI的值高于96 dpi 时,假设是120 dpi. 这样一张200x100 96dpi的图片实际的大小是 250x125, 而graphics.DrawImage(image,x,y)这个函数并没有指定绘制目标和源矩形, 所以默认是源矩形的200x100,目标矩形的200x100, 而源矩形实际上是250x150了,所以只绘制了图片的一部分. 这部分内容也是推理出来的, 微软官方的DPI and Device-Independent Pixels并没有说明图片在高DPI时是否会缩放, 只说明了字体会缩放.
在96DPI显示正常的图片:
在高DPI显示不正常的图片:
5.获取设备DPI的方法:
void InitializeDPIScale(HWND hwnd)
{
HDC hdc = GetDC(hwnd);
g_DPIScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
g_DPIScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f;
ReleaseDC(hwnd, hdc);
}
解决
1.使用带Rect方式的绘制,graphics.DrawImage(image,Rect)等其他重载函数, 让图片自动缩放.
class Utils
{
public:
static void DrawImage(Gdiplus::Graphics& graphics,Gdiplus::Image* image,
int x,int y)
{
Gdiplus::Rect dest_rect(x,y,image->GetWidth(),image->GetHeight());
graphics.DrawImage(image,dest_rect,0,0,image->GetWidth(),image->GetHeight(),
Gdiplus::UnitPixel);
}
};
参考
DPI and Device-Independent Pixels
Graphics.DrawImage logo scaling incorrectly on a large image
[ATL/WTL]_[初级]_[关于graphics.DrawImage绘图时显示不正常的问题]的更多相关文章
- [ATL/WTL]_[初级]_[选择目录对话框]
场景 1.起因是创建标准选择目录对话框时使用了 SHCreateItemFromParsingName 函数, 这个函数支持vista以上系统. 之后再winxp上运行就报错: 无法定位程序输入点 S ...
- [C/C++标准库]_[初级]_[转换UTC时间到local本地时间]
场景 1.如果有面向全球用户的网站, 一般在存储时间数据时存储的是UTC格式的时间, 这样时间是统一的, 并可以根据当地时区来进行准确的转换. 2.存储本地时间的问题就在于如果换了时区, 那么显示的时 ...
- [Zlib]_[初级]_[使用zlib库压缩和解压STL string]
场景 1.一般在使用文本json传输数据, 数据量特别大时,传输的过程就特别耗时, 因为带宽或者socket的缓存是有限制的, 数据量越大, 传输时间就越长. 网站一般使用gzip来压缩成二进制. 说 ...
- [C/C++11]_[初级]_[std::bind介绍和使用]
场景 1.C++11 引入了std::function 对象, 这个对象可以通过std::bind封装所有的函数, 并通过代理调用这个std::function的方式调用这个函数. 比如通过统一的方式 ...
- [数据库]_[初级]_[sqlite3简单使用]
场景 1.sqlite3在很多小型项目都会用到, 比如用来存储Android的联系人,短信等. 这个小巧的sqlite3是文件型的数据库, 也方便做配置文件和程序打包. 使用sql查询也方面. 所以s ...
- [ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]
场景: 1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件. 2.截取屏幕内容到文件时. 3.不须要增加第3方库时. 说明: 这段代码部分来自网上.第一次学atl ...
- Oracle学习总结_day03_day04_条件查询_排序_函数_子查询
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...
- C Primer Plus_第6章_循环_编程练习
1.题略 #include int main(void) { int i; char ch[26]; for (i = 97; i <= (97+25); i++) { ch[i-97] = i ...
- 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好
HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...
随机推荐
- Tomcat6.0下的jsp、servlet和javabean的配置
第一步:下载jdk和tomcat: 第二步:安装和配置你的jdk和tomcat:执行jdk和tomcat的安装程序,然后设置按照路径进行安装即可.1.安装jdk以后,需要配置一下环境变量,在我的电脑- ...
- gridview导出数据,如果为0开头,丢失0解决方案
1.protected void GridView1_RowDataBound( object sender, GridViewRowEventArgs e ) { if (e.Row.Row ...
- 解决点击cell执行动画导致的重用问题
解决点击cell执行动画导致的重用问题 说明: 动画的细节都是裸露的,并没有封装,靠看官来优化了. 效果: 源码: https://github.com/YouXianMing/UITableView ...
- java开发初识
jdk目录相关介绍: bin:存放的是java的相关开发工具 db:顾名思义jre附带的轻量级数据库 include:存放的是调用系统资源的接口文件 jre:java的运行环境 lib:核心的类库 s ...
- C++用法总结
1.C++的绝对值符号 如果是整形的,就是abs() 如果是浮点型的,是fabs() 这两个函数都从属于库函数math.h #include <cmath> or #include< ...
- Echarts 多曲线“断点”问题解决方法
Echarts 用来做可视化曲线是非常优秀的一个库.建议使用 Echarts 作为项目的可视化图标库时,仔细研究 官方实例,根据需求来选择类似的示例,下载实例模板来开发,节省时间,减少出错,提高效率. ...
- JNLP应用程序无法打开的解决办法
JNLP应用程序无法打开: 1.控制面板-Java-Java 选项卡-查看.用户选项卡勾选对应版本JDK(没有就添加,路径填类似:D:\Program Files\Java\jre6\bin\java ...
- 3631. [JLOI2014]松鼠的新家【树形DP】
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- 联通营业厅API 获取个人信息
string newValue = base.Request["tel"]; string newValue2 = base.Request["pwd"]; s ...
- mysql安装后找不到sock文件
mysql rpm安装方式之后,启动找不到sock文件,经排查是之前安装的由mysql, 需要时yum list installed mysql 或者 rpm -qa |grep -i mysql ...