热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

skia~setDIBitsToDevice~Windows

问题:skia是一个图形库,本身没有在设备上作图的能力,可以通过提供的SkView类,参考实现对不同平台设备上作画。SkOsWindow_Win.cpp:onPaint方法中提供了

问题: skia是一个图形库,本身没有在设备上作图的能力,可以通过提供的SkView类,参考实现对不同平台设备上作画。

  SkOsWindow_Win.cpp: onPaint方法中提供了在windows平台设备上作图的接口,SetDIBitsToDevice();  

,,
 1 SetDIBitsToDevice(
 2                 HDC hdc,                 // 设备环境句柄。
 3                 int XDest,               // 指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
 4                 int YDest,               // 指字目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
 5                 DWORD dwWidth,           // 指定DIB的宽度,按逻辑单位表示宽度。
 6                 DWORD dwHeight,          // 指定DIB的高度,按逻辑单位表示高度。
 7                 int XSrc,                // 指定DIB位图左下角的X轴坐标,按逻辑单位表示坐标
 8                 int YSrc,                // 指定DIB位图左下角的Y轴坐标,按逻辑单位表示坐标。
 9                 UINT uStartScan,         // 指定DIB中的起始扫描线。
10                 UINT cScanLines,         // 指定参数lpvBits指向的数组中包含的DIB扫描线数目。
11                 CONST VOID *lpvBits,     // 指向存储DIB颜色数据的字节类型数组的指针。
12                 CONST BITMAPINFO *lpbmi, // 指向BITMAPINFO结构的指针,该结构包含有关DIB的信息。
13                 UINT fuColorUse          // 指向BITMAPINFO结构中的成员bmiColors是否包含明确的RGB值或对调色板进行索引的值。
14                 )
SetDIBitsToDevice
,,
 1 void SkOSWindow::doPaint(void* ctx) {
 2     this->update(NULL);
 3 
 4     if (kNone_BackEndType == fAttached)
 5     {
 6         HDC hdc = (HDC)ctx;
 7         const SkBitmap& bitmap = this->getBitmap();
 8 
 9         BITMAPINFO bmi;
10         memset(&bmi, 0, sizeof(bmi));
11         bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
12         bmi.bmiHeader.biWidth       = bitmap.width();
13         bmi.bmiHeader.biHeight      = -bitmap.height(); // top-down image
14         bmi.bmiHeader.biPlanes      = 1;
15         bmi.bmiHeader.biBitCount    = 32;
16         bmi.bmiHeader.biCompression = BI_RGB;
17         bmi.bmiHeader.biSizeImage   = 0;
18 
19         //
20         // Do the SetDIBitsToDevice.
21         //
22         // TODO(wjmaclean):
23         //       Fix this call to handle SkBitmaps that have rowBytes != width,
24         //       i.e. may have padding at the end of lines. The SkASSERT below
25         //       may be ignored by builds, and the only obviously safe option
26         //       seems to be to copy the bitmap to a temporary (contiguous)
27         //       buffer before passing to SetDIBitsToDevice().
28         SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
29         bitmap.lockPixels();
30         int ret = SetDIBitsToDevice(hdc,
31             0, 0,
32             bitmap.width(), bitmap.height(),
33             0, 0,
34             0, bitmap.height(),
35             bitmap.getPixels(),
36             &bmi,
37             DIB_RGB_COLORS);
38         (void)ret; // we‘re ignoring potential failures for now.
39         bitmap.unlockPixels();
40     }
41 }
SkOSWindow_win.cpp
,,
 1 //建立逻辑坐标系
 2         paint.setARGB(255, 255, 0, 0);
 3         paint.setStrokeWidth(3);
 4         canvas->drawLine(0, 0, bitmap->width(), 0, paint);
 5         canvas->drawLine(0, 0, 0, bitmap->height(), paint);
 6 
 7         paint.setARGB(255, 255, 200, 200);
 8         canvas->drawText("X/2", 4, bitmap->width() / 2 + 10, 10, paint);
 9         canvas->drawText("Y/2", 4, 5, bitmap->height() / 2, paint);
10 
11         paint.setARGB(255, 255, 200, 0);
12         canvas->drawText("X", 2, bitmap->width()-10, 10, paint);
13         canvas->drawText("Y", 2, 5, bitmap->height(), paint);
建立坐标系
,,
1 //三个概念 窗口区域、画布canvas区域、位图bitmap区域
2             SetDIBitsToDevice(hdc,
3                 0, 0,    //指定逻辑坐标系(即:画布canavs)的坐标原点,左上角(即:右、下为正方向),
4                 bitmap->width(), bitmap->height(),
5                 0, 0,
6                 0,            //画布中起始显示位置
7                 bitmap->height(), bitmap->getPixels(), //扫描的起点与扫描的高度
8                 &lpbmi, DIB_RGB_COLORS);
三个区域

,  ,,

, ,  ,

,, 

,,

通过设置用画笔填充真个绘制区域发现,canvas的绘制区域,一直都是bitmap的区域,而,

,,

在位图的变换中,canvas的逻辑坐标(屏幕左上角的,右、下),而位图的逻辑坐标是左下角(右、上),所有变换在位图的显示变换中有一个倒置的操作。

即:,

skia~setDIBitsToDevice~Windows,,

skia~setDIBitsToDevice~Windows


推荐阅读
  • 本文介绍如何使用Python进行文本处理,包括分词和生成词云图。通过整合多个文本文件、去除停用词并生成词云图,展示文本数据的可视化分析方法。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 本文介绍如何在应用程序中使用文本输入框创建密码输入框,并通过设置掩码来隐藏用户输入的内容。我们将详细解释代码实现,并提供专业的补充说明。 ... [详细]
  • 本文介绍如何通过SQL查询从JDE(JD Edwards)系统中提取所有字典数据,涵盖关键表的关联和字段选择。具体包括F0004和F0005系列表的数据提取方法。 ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
  • andr ... [详细]
  • VPX611是北京青翼科技推出的一款采用6U VPX架构的高性能数据存储板。该板卡搭载两片Xilinx Kintex-7系列FPGA作为主控单元,内置RAID控制器,支持多达8个mSATA盘,最大存储容量可达8TB,持续写入带宽高达3.2GB/s。 ... [详细]
  • 本文介绍如何在Linux服务器之间使用SCP命令进行文件传输。SCP(Secure Copy Protocol)是一种基于SSH的安全文件传输协议,支持从远程机器复制文件到本地服务器或反之。示例包括从192.168.45.147复制tomcat目录到本地/home路径。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文详细介绍了如何在CentOS 7操作系统上安装和配置Grafana,包括必要的依赖项安装、插件管理以及服务启动等步骤。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 本文介绍如何通过SSH协议使用Xshell远程连接到Ubuntu系统。为了实现这一目标,需要确保Ubuntu系统已安装并配置好SSH服务器,并保证网络连通性。 ... [详细]
  • 落樱3D v0.5是一款在Android平台上发布的3D美少女格斗游戏,本次更新带来了多项新功能和优化。 ... [详细]
author-avatar
jing2502857803
这个家伙很懒,什么也没留下!
RankList | 热门文章