skia是谷歌的一个开源2D引擎,用来实现利用CPU实现2D图形绘制。
下面是老朽写的一个例程,实现功能如下:
1.窗口的创建
2.图片解码
3.在窗口的任意位置绘制指定大小和透明度的图片
4.绘制文字
因为对OpenGL熟悉,所以不怎么喜欢用SDL,而是采用OpenGL创建绘制窗口。先由glfw创建窗口,然后skia负责渲染,最后opengl只负责将skia传过来的pixel画出来。

main函数如下

//
// Created by czh on 18-10-31.
//#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "window.h"
#include "dconfig.h"Window blizzard(SCREEN_WIDTH, SCREEN_HEIGHT);void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mode) {if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (key >= 0 && key < 1024) {if (action == GLFW_PRESS)blizzard.keys[key] = GL_TRUE;else if (action == GLFW_RELEASE)blizzard.keys[key] = GL_FALSE;}
}int main() {glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Blizzard", nullptr, nullptr);glfwMakeContextCurrent(window);glfwSetKeyCallback(window, keyCallback);gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);blizzard.init();while (!glfwWindowShouldClose(window)) {clock_t start = clock();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);blizzard.processInput();blizzard.update();blizzard.render(window);glfwSwapBuffers(window);glfwPollEvents();
#define FPS 1000/33clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#Render time: %d\n", time_ms);if ((FPS - time_ms) > 0) {usleep((FPS - time_ms) * 1000);}}glfwTerminate();return 0;
}

下面是头文件window.h

//
// Created by czh on 18-10-31.
//#ifndef OPENGL_PRO_WINDOW_H
#define OPENGL_PRO_WINDOW_H#include <game.h>
#include "calib/zhu.h"
#include <calib/checkerborad.h>
#include <calib/colormap.h>
#include <calib/zhang.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkPicture.h>
#include <SkTypeface.h>
#include <SkStream.h>
#include <SkCodec.h>
#include <SkAndroidCodec.h>
#include <SkImage.h>class Window : public Game {
public:SpriteRenderer *spriteRender;sk_sp<SkTypeface> font;SkBitmap bmMaster;sk_sp<SkImage> image;SkCanvas *canvas;sk_sp<SkImage> imageServant;SkBitmap bmServant;cv::VideoCapture capture;Window(GLuint width, GLuint height);void init();void destory();void processInput();void update();void render(GLFWwindow *window);SkBitmap loadTexture2DToSkBitmap( std::string file);sk_sp<SkImage> loadTexture2DToSkImage(std::string file);void draw(SkCanvas *canvas, sk_sp<SkImage> image, int posX, int posY, int sizeX, int sizeY, uchar alpha = 0xff);void draw(SkCanvas *canvas, SkBitmap bitmap, int posX, int posY, int sizeX, int sizeY, uchar alpha = 0xff);void drawFront(SkCanvas *canvas, std::string text, int posX, int posY, float size, uint color, uchar alpha = 0xff);
};#endif //OPENGL_PRO_WINDOW_H

最后是window.cpp

//
// Created by czh on 18-10-31.
//#include "window.h"Window::Window(GLuint width, GLuint height) : Game(width, height) {canvas = nullptr;
}void Window::init() {StatusManager::renderMode = Render_2D;StatusManager::init();this->state = GAME_ACTIVE;ResourceManager::loadShader("sprite", ResourceManager::defaultVshader2D, ResourceManager::defaultFshader2D);spriteRender = new SpriteRenderer();spriteRender->init(ResourceManager::getShader("sprite"));glm::mat4 projection = glm::mat4(1.0f);projection = glm::ortho(0.0f, static_cast<GLfloat>(this->width), static_cast<GLfloat>(this->height), 0.0f,-1.0f, 1.0f);glm::mat4 model = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));//movemodel = glm::rotate(model, glm::radians(0.0f), glm::vec3(0.0f, 0.0f, 1.0f));//rotatemodel = glm::scale(model, glm::vec3(SCREEN_WIDTH, SCREEN_HEIGHT, 1.0f)); //scaleResourceManager::getShader("sprite").setMatrix4("projection", projection);ResourceManager::getShader("sprite").setMatrix4("model", model);ResourceManager::getShader("sprite").setVector3f("spriteColor", glm::vec3(1.0, 1.0, 1.0));bmMaster.allocPixels(SkImageInfo::Make(1920, 720, kN32_SkColorType, kPremul_SkAlphaType));bmMaster.eraseColor(0xFF000000);canvas = new SkCanvas(bmMaster);//imageServant = loadTexture2DToSkImage("../res/colorMap.png");bmServant = loadTexture2DToSkBitmap("../res/colorMap.png");
}void Window::destory() {Game::destroy();
}void Window::processInput() {}SkBitmap Window::loadTexture2DToSkBitmap(std::string file) {clock_t start = clock();SkBitmap bitmap;SkString path(file.c_str());sk_sp<SkData> data = SkData::MakeFromFileName(path.c_str());if (!data) {printf("Missing file %s", path.c_str());}auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));SkImageInfo info = codec->getInfo();bitmap.allocPixels(SkImageInfo::Make(info.width(), info.height(), kN32_SkColorType, kPremul_SkAlphaType));SkCodec::Result result = codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes());if (result == SkCodec::kSuccess) {printf("#Codec success\n");} else {printf("#Codec failure\n");}clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#loadTexture2DToSkBitmap time: %d\n", time_ms);return bitmap;
}sk_sp<SkImage> Window::loadTexture2DToSkImage(std::string file) {clock_t start = clock();sk_sp<SkData> data = SkData::MakeFromFileName(file.c_str());sk_sp<SkImage> image = SkImage::MakeFromEncoded(data);clock_t end = clock();int time_ms = (double) (end - start) / CLOCKS_PER_SEC * 1000;printf("#loadTexture2DToSkImage time: %d\n", time_ms);return image;
}void Window::draw(SkCanvas *canvas, sk_sp<SkImage> image, int posX, int posY, int sizeX, int sizeY, uchar alpha) {SkRect rect;rect.setXYWH(posX, posY, posX + sizeX, posY + sizeY);SkPaint paint;paint.setAlpha(alpha);canvas->drawImageRect(image, rect, &paint);
}void Window::draw(SkCanvas *canvas, SkBitmap bitmap, int posX, int posY, int sizeX, int sizeY, uchar alpha) {SkRect rect;rect.setXYWH(posX, posY, posX + sizeX, posY + sizeY);SkPaint paint;paint.setAlpha(alpha);canvas->drawBitmapRect(bitmap, rect, &paint);
}void Window::drawFront(SkCanvas *canvas, std::string text, int posX, int posY, float size, uint color, uchar alpha) {SkPaint paint;paint.setARGB(uchar(color >> 24), uchar(color >> 16), uchar(color >> 8), (uchar)color);paint.setTypeface(SkTypeface::MakeFromFile("../res/fangsong.ttf"));paint.setTextSize(size);paint.setAlpha(alpha);std::string title(text.c_str());canvas->drawText(title.c_str(), title.length(), posX, posY, paint);
}void Window::update() {canvas->clear(0x00000000);static int i = 0;//1.0 decode with bitmapdraw(canvas, bmServant, 0, 0, 1920, 720, 0xff);drawFront(canvas, "abcd12341234哈哈哈", 100, 50, 25, 0xffff0000, 0xff);ResourceManager::loadTexture2D("codec_data", (uchar *) bmMaster.getPixels(), bmMaster.width(), bmMaster.height(), 4);//2.0 decode with image//draw(canvas, imageServant, 0, 0, 1920, 720, 0xff);//drawFront(canvas, "123456789", 100, 50, 25, 0xffff0000, 0xff);//ResourceManager::loadTexture2D("codec_data", (uchar *) bmMaster.getPixels(), bmMaster.width(), bmMaster.height(), 4);
}void Window::render(GLFWwindow *window) {if (this->state == GAME_ACTIVE) {spriteRender->drawSprite(ResourceManager::getTexture2D("codec_data"));usleep(1000 * 30);}
}

效果如图

用skia实现2D绘制相关推荐

  1. Github 每日精选:可在Java 中绑定 skia 的 2D 图形库Skija;自动对对联系统seq2seq-couplet

    大家好,我是开源菌!天气转凉,有点不想打字,但依然阻挡不了我给大家安利开源项目的冲动.刚刚瞄了一眼今天的榜单,重新上架的 youtube-dl 插件再次登顶第一宝座,好不威风. 1.Skija:可在J ...

  2. 2d绘制 c# dx_C# 从零开始写 SharpDx 应用 绘制基础图形

    本文告诉大家通过 SharpDx 画出简单的 2D 界面 本文属于 SharpDx 系列 博客,建议从头开始读 本文分为两步,第一步是初始化,第二步才是画界面 初始化 先创建 RenderForm 用 ...

  3. 微信小程序 canvas type = 2d 绘制海报心得(包括怎么绘制图片和圆角图片和圆角矩形等)

    微信小程序 canvas type=2d 使用心得 为了方便这里我封装成了一个component 然后说说怎么使用最新的方法(使用方法类似于html中的canvas可以进行参考)获取--canvas ...

  4. 使用Java 2D绘制黑白太极图案

    一:基本原理 利用Java 2D的Area对象对绘制形状几何操作的支持,完成太极图案的绘制,使用Paint来 完成对不同颜色的填充.Java 2D图形API Area对Shape支持四种几何操作: - ...

  5. 微信小程序canvas 2d 绘制图片与文字 导出图片

    wxml内容 如下 <canvas id="myCanvas" type="2d"style="width: {{ canvas.width } ...

  6. 小程序 canvas 2d 绘制海报

    效果图 canvas api 准备 绘制图片 context.drawImage(image, dx, dy, dWidth, dHeight); image:绘制在Canvas上的元素,可以是各类C ...

  7. 小程序 canvas 2d 绘制图片并保存

    获取canvas实例,使用的官方的代码.用一个变量canvas保存实例,后续保存时会调用. data () {return {canvas: null // 实例} }, onReady() {con ...

  8. Unity 依据Polygon Collider 2D 绘制 mesh

    参考文章: mesh的简介 创建mesh 简单多边形三角化(暴力)(削耳朵) 偶尔需要依据多边形创建平面mesh,所以在网上浏览了很多资料,再修修补补才凑出一段代码. [ContextMenu(&qu ...

  9. Quart 2D 绘制图形简单总结

    0  CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文 1 CGContextMoveToPoint 开始画线 2 CGConte ...

最新文章

  1. Protocol Buffers 在 iOS 中的使用
  2. jQuery 事件绑定
  3. python中5个json库的速度对比
  4. threadpoolexecutor参数_ThreadPoolExecutor的使用
  5. angularjs--控制器的显示与隐示使用
  6. Terracotta - 分布式共享对象
  7. 1、java 的安装及资料下载
  8. brctl 命令详解
  9. 为什么闹钟设置了却不响_手机闹钟不响是怎么回事 怎么设置闹钟【图文】
  10. plot函数二维绘图
  11. 照片制作手机壳,定制手机壳diy需要什么设备?
  12. 卡尔曼滤波Kalman Filtering:介绍
  13. 保姆式RecyclerView下拉刷新、上拉加载更多Kotlin
  14. 气象绘图(二)——散点图
  15. 玩转百度即用API(5)——空气质量指数查询
  16. 基于android平台的条码扫描软件的设计与实现,基于android平台的条码扫描软件的设计与实现...
  17. 细述个人建站那点心酸往事
  18. ico图标和制作网站(比特虫)
  19. java计算三角形的外心_hdu 6006(java 大数,三角形的外心)
  20. eclipse如何去掉无用的validation、优化eclipse

热门文章

  1. xampp服务器默认配置文件,服务器xampp安装教程与配置
  2. pyside 蒙版的基本使用-pyqt 掩码 掩模 圆形头像 mask 图像
  3. SpringBoot在东方通服务器TongWeb上显示pdf
  4. 获取浏览器打开的网页的网址
  5. 将英文词典dict.txt导入到数据库中
  6. 特征工程:8种常用类别型数据处理方法
  7. UML之行为图(活动图、状态图、交互图)
  8. 换脸ai的方法分享!这几个换脸APP巨好用。​
  9. NVIDIA GPU A100 Ampere(安培) 架构深度解析
  10. javascript 定义 数组