今天 12 月了,本来应该开始做外包的项目,但是好歹不好的长智齿了,
下午去拔了牙之后看着电脑发呆了一个下午,看来真的麻药影响 🧠 脑子。
所以,先写篇文章醒醒脑….
前天初步实现了下使用 canvas
来识别图片内容,今天就把它记录下来。
毕竟 canvas
这部分的内容是真的不懂,现学现卖,欢迎吐槽。📧 MailTo
前几天,领导和我说要制作一个年会的活动页面,需要有用户签到展示、企业形象展示、抽奖小游戏。
其中一个需求如下:
Logo 签到墙
年会的签到墙,使用微信扫码签到,然后后台拿到微信授权之后传给我用户的头像昵称,然后我就在前台展示并且完成一些特效。

需要用头像图片拼接组成图形以及文字内容。
这个图形和文字是用户上传的一个纯色内容+透明/白色底的图片。👇

我就直接想到用 canvas 来识别图片内容,
前天晚上初步实现了需求,
直接暴力的按照设置的 size 大小
从左上角不断循环识别到右下角,然后保存有内容的坐标点,
再按照坐标来绘制矩形和图片填充。
这边是我实现的效果 👇
识别成栅格

用户头像填充

识别内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| const MaxHeight = document.body.clientWidth; const MaxHeight = document.body.clientHeight; const size = 10; const points = []; const canvas = document.querySelector("canvas"); canvas.width = MaxHeight; canvas.height = MaxHeight; const ctx = canvas.getContext("2d"); let img = new Image(); img.src = require("assets/img/text.jpg"); let w = maxWidth; let h = 0; img.onload = () => { h = (w / img.width) * img.height; ctx.drawImage(img, 0, 0, w, h); for (let x = 0; x <= w - 10; x += size + 1) { for (let y = 0; y <= h - 10; y += size + 1) { let color = ctx.getImageData(x, y, size, size).data; let count = 0; for (let i = 0; i < color.length; i += 4) { if (color[i] <= 100 || color[i + 1] <= 100 || color[i + 2] <= 100) { count++; } } if (count >= size * size * 0.1) { points.push({ x: x, y: y }); } } } ctx.clearRect(0, 0, maxWidth, maxHeight); };
|
绘制栅格图
1 2 3 4 5
| ctx.fillStyle = "rgba(255,0,0,.55)";
points.forEach(piont => { ctx.fillRect(piont.x, piont.y, this.size, this.size); });
|
填充图片
填充图片和绘制矩形的原理相似所以就不举例了。
考虑到签到的人数有可能达不到坐标的数量,所以在最后可以重新循环用户头像列表来填充满整个栅格区

以上是简单的使用 canvas
试别图片内容,并且栅格化且使用图片填充。
附
- 特殊情况 1:如果识别超过 50% 时,笔画交汇时折角会超过 50%,但是没有处在交汇处的内容可能并没有超过 50%
