- 编写C代码 my_canvas.cpp 实现图像数据的管理与圆的绘制,C代码中包含两个函数,get_img_buf()函数根据传入的参数判断是否需要重新创建缓冲区;
draw_circle()
函数在指定位置以指定半径填充绘制圆。
#ifndef EM_PORT_API
# if defined(__EMSCRIPTEN__)
# include <emscripten.h>
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
# else
# define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
# endif
# else
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype
# else
# define EM_PORT_API(rettype) rettype
# endif
# endif
#endif
#include <stdint.h>
#include <malloc.h>
uint8_t *img_buf = NULL;//指向位于保存位图的缓冲区
int img_width = 0, img_height = 0;
EM_PORT_API(uint8_t*) get_img_buf(int w, int h) {//根据传入的参数判断是否需要重新创建缓冲区
if (img_buf == NULL || w != img_width || h != img_height) {
if (img_buf) {
free(img_buf);
}
img_buf = (uint8_t*)malloc(w * h * 4);
img_width = w;
img_height = h;
}
return img_buf;
}
EM_PORT_API(void) draw_circle(int cx, int cy, int radii) {//在指定位置以指定半径填充绘制圆
int sq = radii * radii;
for (int y = 0; y < img_height; y++) {
for (int x = 0; x < img_width; x++) {
int d = (y - cy) * (y - cy) + (x - cx) * (x - cx);
if (d < sq) {
img_buf[(y * img_width + x) * 4] = 255; //r
img_buf[(y * img_width + x) * 4 + 1] = 0; //g
img_buf[(y * img_width + x) * 4 + 2] = 0; //b
img_buf[(y * img_width + x) * 4 + 3] = 255; //a
}
else {
img_buf[(y * img_width + x) * 4] = 0; //r
img_buf[(y * img_width + x) * 4 + 1] = 255; //g
img_buf[(y * img_width + x) * 4 + 2] = 255; //b
img_buf[(y * img_width + x) * 4 + 3] = 255; //a
}
}
}
}
- 通过命令
emcc my_canvas.cpp –s WASM=1 -o my_canvas.js
生成
my_canvas.js
文件和my_canvas.wasm
文件。 - 编写HTML代码(
my_canvas.html
)实现C程序的网页端显示,html中声明了id为myCanvas
的canvas
元素,在每帧更新时,从Emscripten运行时Module
中取出图像数据,创建ImageData
对象imgData
,并将imgData
通过CanvasRenderingContext2D
对象ctx
更新到canvas
上去。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Emscripten:Canvas</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
Module = {};
Module.onRuntimeInitialized = function() {
var canvas = document.getElementById('myCanvas');
canvas.width = 400;
canvas.height = 400;
window.requestAnimationFrame(update);
}
var radii = 0, delta = 1;
function update() {
var buf_addr = Module._get_img_buf(400, 400);//从module读取数据
Module._draw_circle(200, 200, radii);
radii += delta;
if (radii > 200 || radii < 0) delta = -delta;
var u8o = new Uint8ClampedArray(Module.HEAPU8.subarray(buf_addr,
buf_addr + 400 * 400 * 4));
var imgData = new ImageData(u8o, 400, 400);
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.putImageData(imgData, 0, 0);
window.requestAnimationFrame(update);
}
</script>
<script src="my_canvas.js"></script>
</body>
</html>
- 通过命令
emrun –no_browser –port 8080 my_canvas.html
进行页面浏览
运行效果如下(动态):