[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 ...
随机推荐
- MySQL字符存储:charset-unicode-sets
https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html 10.10.1 Unicode Character Sets MyS ...
- Microsoft Teams 版本与语音落地介绍
我亲爱的小伙伴们,失踪人口回归啦~~ 今天和大家聊的是Microsoft Teams,Teams作为协作的集大成者,可以实现skype for Business的所有功能,还可以在teams里集合Of ...
- 解决由于显卡驱动BUG导致桌面右键卡顿的问题:bat文件源码
@ ECHO OFF%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe&q ...
- HashMap集合特点
>HashMap集合特点 HashMap:是基于哈希表的Map接口实现. 哈希表的作用是用来保证键的唯一性的. 不明白,直接看HashMap的put方法源码 //HashM ...
- C++ 读书笔记2
dfadsfa body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding ...
- 进程分析之CPU
进程分析之CPU 进程分析之CPU 本文转载自:https://github.com/ColZer/DigAndBuried/blob/master/system/cpu.md 在<进程分析之内 ...
- Shell中, 退出整个脚本
常规做法 cat >test.sh<<EOF'' #!/bin/bash exit_script(){ exit 1 } echo "before exit" e ...
- ansible.md
ansible 测试环境配置 注意:192.168.100.201这台机器是主控机,剩下的192.168.100.202.192.168.100.203.192.168.100.210均为测试主机. ...
- python第十四课--排序及自定义函数之自定义函数(案例四)
整理:4中最常见的自定义函数模型1).无参无返回值2).无参有返回值3).有参无返回值4).有参有返回值 #定义无参无返回值自定义函数 def func1(): print('hello method ...
- linux中Vi编辑器使用
1.如需要编辑aaa.txt文件: vi aaa.txt 就可以进入到 aaa.txt文件中, 输入 i 进入到编辑模式, 按 Esc 退出编辑模式 , :wq 保存退出编辑模式 ...