在PPAPI插件中使用Skia绘图

本文介绍了如何在PPAPI插件中利用Skia进行2D绘图,详细讲述了Skia的关键类库,包括SkPaint、SkCanvas和SkBitmap,并分享了ppapi_skia项目的实现过程,包括源码编译、库链接以及解决库冲突问题。通过示例代码展示了如何在C++和HTML中使用Skia进行绘图,最终实现了简单的绘图效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Windows下从源码编译Skia一文介绍了Skia的编译,现在我们可以尝试在PPAPI插件中来使用Skia了。

foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。

Skia的关键类库

官网https://skia.org/上有文档,可以看。然后下载的源码,可以使用SourceInsight之类的工具来查看。具体不再细说,我这里只提用到的三个关键类:

SkCanvas是画布,你可以在它上面画任意的图元,比如矩形、圆型、文字、弧……

SkPaint则是工具箱,聚合了画笔、颜色等各种绘画时要用的配置选项。

SkBitmap代表了一块图像数据。

你调用SkCanvas的方法绘制图元,这些图元对应的数据一定要有个地方保存或显示,用于保存或显示图像数据的那个角色,被称为backends。SkCanvas的backends,有好几种,我们这个简单的示例ppapi_skia只用到了SkBitmap这种后端。

2D绘图类库的基本设计都差不多,我的《Qt on Android核心编程》一书里对Qt绘图有介绍,两厢比对,就会发现设计得差不多。不过有一点不同,QPainter会保存你设置的绘图选项(颜色、画笔等),而SkCanvas则不会,需要自己设计数据结构和逻辑来保存。

ppapi_skia项目

ppapi_skia项目基于ppapi_simple而来,请先参考PPAPI插件的绘图与输入事件处理这篇文章。

不过为了方便调用Skia(C++类库),我这次用了cpp源文件,ppapi_skia.cpp。(吐槽下,VS2013对于C文件的即时提示太弱……)

我还改了ppapi_simple,使用了FlushCompletionCallback来优化绘图流程。

Skia默认编译出来的是静态库,对于一个简单的PPAPI+Skia插件,我不知道需要链接哪些lib,写好了代码,编译,根据undefined reference错误一通狂找,发现要链接下列lib:

skia_core.lib
skia_ports.lib
skia_utils.lib
skia_effects.lib
skia_skgpu.lib
skia_opts.lib
skia_opts_ssse3.lib
skia_opts_sse41.lib
skia_opts_avx.lib
skia_images.lib
skia_sfnt.lib
libetc1.lib
libSkKTX.lib
opengl32.lib

Windows下从源码编译Skia一文提到编译后的lib文件路径是:E:\sources\skia\out\Release。设置到项目的附加库目录列表中。skia还依赖其他一些库文件,在E:\sources\skia\out\Release\obj\gyp目录下,把这个目录添加到附加库目录列表里。

Skia需要OpenGL,我们得链接Opengl32.lib,Windows SDK里有。

skia编译时加了/MD参数,CEF编译时用的MT,如果你用PPAPI的C++接口,就会冲突了。要么改skia,要么改CEF。skia库小,改它吧。我还没找到怎么在生成构建文件时设置,最简单直接的,就是到E:\sources\skia\out\Release\obj\gyp这里,把*.ninja文件里的/MD都修改为/MT。然后重新编译。

如过用C接口,没关系,把PPAPI的代码生成选项里的运行库修改为MD即可。我偷懒,就用C接口,把ppapi_skia项目的运行库选项设置为了MD。

好,关于工程基本就这样了。

源码

分C++源码和HTML源码。

C++代码

So,源码来了,基于C代码改过来,有点乱,不过可以说明用法。

/*
* Copyright (c) 2016 foruok@程序视界. All rights reserved.
* 2016-1-16, edited by foruok.
* 如需转载,请关注微信订阅号“程序视界”,回复foruok获取其联系方式
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <tchar.h>

#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/c/ppb_image_data.h"
#include "ppapi/c/ppb_instance.h"
#include "ppapi/c/ppb_view.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance
<think>我们正在讨论PyQt5中启用GPU加速的问题。根据引用[2],在图表数据点很多时,使用OpenGL进行GPU加速可以显著提高渲染性能。具体到QChart,我们可以通过设置QChartView来启用OpenGL加速。步骤:1.确保安装了支持OpenGL的PyQt5版本。2.在创建QChartView实例后,调用其setRenderHint方法,并传入QPainter.Antialiasing以启用抗锯齿,同时还可以通过设置OpenGL加速选项来启用GPU加速。3.另外,QChart类本身也提供了setUseOpenGL方法,将其设置为True即可启用OpenGL加速。注意:启用OpenGL加速需要硬件和驱动程序的支持。示例代码:假设我们有一个QChart对象,我们可以这样做:chart_view =QChartView(chart)chart_view.setRenderHint(QPainter.Antialiasing)#可选,用于抗锯齿chart.setUseOpenGL(True)#启用OpenGL加速但是,引用[2]中提到的是使用OpenGL加速图表绘制,所以主要针对QChart。对于其他图形组件,可能需要不同的方法。另外,引用[2]中提到的测试表明,使用OpenGL加速后,图表的FPS(每秒帧率)会有数量级的提高。因此,在PyQt5中实现GPU加速,主要是在绘图操作中利用OpenGL。对于自定义的绘图,可以使用QOpenGLWidget作为绘图的画布,然后使用OpenGLAPI进行绘制。总结:1.对于QChart:使用chart.setUseOpenGL(True)来启用加速。2.对于自定义绘图使用QOpenGLWidget作为绘图的容器,并在其中使用OpenGL命令。注意:使用OpenGL加速可能会增加内存消耗,但在处理大量数据时性能提升明显。相关问题:1.如何在PyQt5中使用QOpenGLWidget进行自定义绘图?2.启用OpenGL加速后,如何测试性能提升?3.除了OpenGL,PyQt5还支持哪些硬件加速技术?</think>### PyQt5 GUI应用中启用GPU加速的方法 在PyQt5中启用GPU加速主要通过以下两种方式实现: #### 1. 针对QChart的OpenGL加速 当使用`QChart`绘制数据密集型图表时(如数万数据点),可通过OpenGL进行GPU渲染加速: ```python from PyQt5.QtChart import QChart, QChartView from PyQt5.QtWidgets import QApplication from PyQt5.QtGui import QPainter app = QApplication([]) chart = QChart() chart.setTitle("GPU加速示例") # 关键步骤:启用OpenGL加速 chart.setUseOpenGL(True) # 🚀 启用GPU加速 chart_view = QChartView(chart) chart_view.setRenderHint(QPainter.Antialiasing) # 启用抗锯齿 chart_view.show() app.exec_() ``` **效果**:在引用[2]的测试中,启用OpenGL后图表渲染FPS(每秒帧率)有数量级提升[^2]。 #### 2. 使用QOpenGLWidget进行自定义渲染 对于需要高性能自定义绘图的场景: ```python from PyQt5.QtWidgets import QOpenGLWidget from PyQt5.QtGui import QOpenGLShaderProgram, QOpenGLShader class GLWidget(QOpenGLWidget): def initializeGL(self): # 初始化OpenGL上下文 self.program = QOpenGLShaderProgram() self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertex_shader) self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragment_shader) self.program.link() def paintGL(self): # 使用GPU进行绘制 self.program.bind() # 添加OpenGL绘制命令... self.program.release() ``` ### 关键注意事项 1. **硬件要求**: - 需要支持OpenGL 2.0+的GPU - 安装最新显卡驱动(NVIDIA/AMD/Intel) 2. **性能优化建议**: - 批量处理绘制调用(减少GPU状态切换) - 使用顶点缓冲区对象(VBO)存储几何数据 - 在`paintGL()`中避免CPU密集型计算 3. **调试工具**: - 使用`glGetError()`检查OpenGL错误 - 通过`QOpenGLDebugLogger`获取实时调试信息 ### 验证加速效果 可通过帧率计数器验证加速效果: ```python class GLWidget(QOpenGLWidget): def paintGL(self): start_time = time.time() # ...绘制操作... fps = 1 / (time.time() - start_time) print(f"当前帧率: {fps:.1f} FPS") ``` ### 适用场景 - 科学数据可视化(如引用[2]中的图表渲染)[^2] - 实时视频处理(如引用[4]中的YOLOv5检测界面)[^4] - 3D模型渲染和CAD应用 - 大规模地理信息可视化 > **注意**:在嵌入式设备或旧硬件上,需通过`QOpenGLContext.supportsOpenGL()`检测OpenGL支持情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

foruok

你可以选择打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值