[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 ...
随机推荐
- [源码] YoCelsius
YoCelsius 视频查看地址 苹果商店免费下载 最美应用介绍 源码地址 未完成的功能 [说明] 1. 本人写了几乎所有的显示控件与动画效果 2. 希望有人能喜欢,下载软件后给个好评 3. ...
- 山寨"每日故宫"应用的图层遮罩效果
山寨"每日故宫"应用的图层遮罩效果 最终效果: 应用中的效果: 素材图片: 源码: // // ViewController.m // 每日故宫 // // Created by ...
- [翻译] JFMinimalNotifications
JFMinimalNotifications This is an iOS UIView for presenting a beautiful notification that is highly ...
- Vue安装以及Vue项目创建以及Vue Devtools安装
这几天一直在学习Vue.js框架. 因为以前没有前端项目的经验,也没学过什么前端框架,所以,对于vue.js的学习有些不知所措. 在vue.js官网看教程,按照教程指点,可以不用脚手架开发,也可以搭建 ...
- November 28th 2016 Week 49th Monday
You only live once, but if you do it right, once is enough. 年华不虚度,一生也足矣. One today can win two tomor ...
- 打开文件 和 字符串中%s 的大坑
ai`....
- GNSS基础(持续更新)
1.整周模糊度成功率 可参考文献:GNSS整周模糊度概率特性 2.正太分布 见百度百科 https://baike.baidu.com/item/%E6%AD%A3%E6%80%81%E5%88%86 ...
- 【原创】uwsgi中多进程+多线程原因以及串行化accept() - thunder_lock说明
如有不对,请详细指正. 最近再研究uwsgi如何部署python app,看uwsgi的文档,里面有太多的参数,但每个参数的解释太苍白,作为菜鸟的我实在是不懂.想搞清楚uwsgi的工作原因以及里面的一 ...
- AOP的本质
AOP的本质是HOOK: HOOK的本质是:新函数包含原函数或新函数替换原函数: 需要解决的问题: 1.新函数的生成: 2.新函数的调用机制: 3.原函数的调用机制: 新函数的生成: 1.将已有的动态 ...
- Azkaban时区问题导致调度差1天
设置了Azkaban调度是每日凌晨一次,如下: 但是调度历史上显示最近一次调度时间是 初步怀疑是因为时区问题导致,查看服务器时区如下 cat /etc/timezone 为Asia/Shanghai. ...