C语言与canvas——绘制圆

  • 编写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中声明了idmyCanvascanvas元素,在每帧更新时,从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进行页面浏览

运行效果如下(动态):

发布了315 篇原创文章 · 获赞 119 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/w144215160044/article/details/100157414
今日推荐