基于Canvas 实现图片转点阵图
要实现什么##
同事想做一张世界地图的背景图,但是网上找的图片都太low了。他想用那种密集的点阵组成的世界地图。作为程序员,想法当然是通过图片处理,识别像素点,然后生成新的图片。

目标是这样的:

实现思路##
其实稍微想一下就很容易想明白:
1. 获取图片数据
2. 分析像素点,判断是不是空白 (每个像素点的rgb色值不是255或某个阈值: r<255 || g<255 || b<255),就替换成指定颜色像素点
3. 把图片划分成像素块, 某一个像素块里空白面积小于 50%(看需求设定阈值),判断为填充点,否则变为透明。
4. 重新绘制图片。
不拘泥于语言,基本思路都是这样。下面是一个Canvas版本:
<!DOCTYPE html>
<html lang="zh-CN" class=" no-touch"><head>
<head><title>Canvas 转点阵</title></head>
<body>
<img src="./timg.jpg" id='img' style="display:none;" />
<div id="container" style="width:1200px;height:1038px">
<canvas id="cvs" width="1200" height="1038"></canvas>
</div>
<script type="text/javascript">
// 判断像素块是否空白or像素覆盖
function isCover(imgdata, width, x, y) {
var covered = 0;
// 像素快为 8*8
for (var i=x; i<x+8; i++) {
for (var j=y; j<y+8; j++) {
var idx = i*4*width + 4*j;
// 阈值设为192
if (imgdata[idx]<192 || imgdata[idx+1]<192 || imgdata[idx+2]<192 ) {
covered++;
}
// 覆盖面积超过 45/64
if (covered > 45) {
return true;
}
}
}
return false;
}
// 填充像素块
function drawPoints(imgdata, width, x, y, clear=false) {
for (var i=x; i<x+8; i++) {
for (var j=y; j<y+8; j++) {
var idx = i*4*width + 4*j;
if (i >=x+2 && i<x+6 && j>=y+2 && j<y+6 && !clear) {
// 画小方块
imgdata[idx] = 168;
imgdata[idx+1] = 168;
imgdata[idx+2] = 168;
imgdata[idx+3] = 192;
} else {
// 置为空白
imgdata[idx] = 255;
imgdata[idx+1] = 255;
imgdata[idx+2] = 255;
imgdata[idx+3] = 0;
}
}
}
return imgdata;
}
// 点阵转换
function convertPointArray(img) {
for (var i=0; i<img.height; i=i+8) {
for (var j=0; j<img.width; j=j+8) {
var isCovered = isCover(img.data, img.width, i, j);
if (isCovered) {
img.data = drawPoints(img.data, img.width, i, j);
} else {
// 其他区域直接清空
img.data = drawPoints(img.data, img.width, i, j, true);
}
}
}
return img;
}
function _init() {
var cvs = document.getElementById('cvs'),
ctx = cvs.getContext('2d'),
img = new Image();
img = document.getElementById('img');
img.crossOrigin = "*";
img.onload = function() {
// 把图片放到canvas 画布上
ctx.drawImage(img, 0, 0, cvs.width, cvs.height);
// 获取像素数据
var imageData = ctx.getImageData(0, 0, cvs.width, cvs.height);
// 转换
imageData = convertPointArray(imageData);
// 擦除原来的图片
ctx.clearRect(0, 0, cvs.width, cvs.height);
// 重新绘图
ctx.putImageData(imageData, 0, 0);
}
}
_init();
</script>
</body>
</html>
基于Canvas 实现图片转点阵图的更多相关文章
- 基于 canvas 将图片转化成字符画
字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢? HTML5 让这个可能变成了现实,通过 canvas,可以很轻松实现这个功能. 其实原理很简单:扫描图片相应位置的像素点,再计算出其灰 ...
- 基于canvas将图片转化成字符画
字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置的像素点,再计算出其灰度值,根 ...
- 一款基于jQuery的图片分组切换焦点图插件
这是一款基于jQuery的图片切换焦点图插件,这款jQuery焦点图插件的特点是图片可以分组切换,也就是说一次可以切换多张图片,相比其他焦点图插件,它能节省更多的空间,可以向用户展示更多的图片,非常实 ...
- 基于canvas图像处理的图片展示demo
图片展示网页往往色彩繁杂,当一个网页上有多张图片的时候用户的注意力就很不容易集中,而且会造成网站整个色调风格的不可把控. 能不能把所有的预览图变成灰度图片,等用户激活某张图片的时候再上色呢? 以前,唯 ...
- 基于canvas图像处理的图片 灰色图像
图片展示网页往往色彩繁杂,当一个网页上有多张图片的时候用户的注意力就很不容易集中,而且会造成网站整个色调风格的不可把控. 能不能把所有的预览图变成灰度图片,等用户激活某张图片的时候再上色呢? 以前,唯 ...
- 基于HTML5实现的Heatmap热图3D应用
Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. 已有众多文章分享了生成Heatmap热图原 ...
- HTML5利用canvas,把多张图合并成一张图片
需求分析,根据当前网页中的几张图片,在手机上长按,保存图片到相册或者发送给好友. drawCanvas(){ var self = this; var imgsrcArray = [ require( ...
- 基于canvas的二维码邀请函生成插件
去年是最忙碌的一年,实在没时间写博客了,看着互联网行业中一个又一个人的倒下,奉劝大家,健康要放在首位,保重身体.好了,言归正传,这是17年的第一篇博文,话说这天又是产品同学跑过来问我说:hi,lenn ...
- [JavaScript] canvas 合成图片和文字
Canvas Canvas 是 HTML5 新增的组件,就像一个画板,用 js 这杆笔,在上面乱涂乱画 创建一个 canvas <canvas id="stockGraph" ...
随机推荐
- 问题杂烩(scrollTop/背景透明度动画)
今天给同学找我帮忙写js,是公司里的活..我是不是应该跟他要钱哈哈,不过一顿饭肯定是免不了的了. 言归正传,今天写了三个小东西,因为兼容性的问题,用jq写的(很是别扭的说,但是没办法啊,一边看api一 ...
- 大数据_学习_01_Hadoop 2.x及hbase常用端口及查看方法
二.参考资料 1.Hadoop 2.x常用端口及查看方法
- Git_学习_01_ 常用 Git 命令清单
我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...
- Struts2 - 值栈(ValueStack)
1. 关于值栈: 1). helloWorld 时, ${productName} 读取 productName 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的. 2). ...
- 批量处理JDBC语句提高处理速度
当需要成批插入或者更新记录时.可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理.通常情况下比单独提交处理更有效率 JDBC的批量处理语句包括下面两个方法: – ...
- Asp.net工作流workflow实战(一)
最近开发一个项目用到了工作流引擎,之前研究过微软的workflow所有就用它了,距离上次用有一段时间了,好多东西有点模糊了,就在此处一遍写代码一遍回忆. 首先,在我的项目中新建了.netframwor ...
- Java常见设计模式之代理模式
指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理.比如生活中的通过代理访问网络,客户通过网络代理连接网络(具体业务),由代理服务器完成用户权限和访问限制等与 ...
- Python-Redis的Hash操作
Redis的hash是一个string类型的field和value的映射表,特别适合用于存储对象,每个hash可以存储40多亿键值对 hset(name, key, value):创建一个name的类 ...
- Oracle中生成UUID
Oracle中生成跨系统的唯一识别符UUID非常方便,比生成序列还简单,直接用sys_guid()就行, 例如select sys_guid() from dual 会产生一个跟MAC地址.生成时间相 ...
- windows linux 使用python执行系统命令并将结果保存到变量
最近需要用到os.system 发现不能赋值到变量 后查有更新的模块,如下: os.system os.spawn* os.popen* popen2.* commands.* 重新使用content ...