广告
返回顶部
首页 > 资讯 > 前端开发 > html >JavaScript纯色二维码变成彩色二维码的示例分析
  • 772
分享到

JavaScript纯色二维码变成彩色二维码的示例分析

2024-04-02 19:04:59 772人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关javascript纯色二维码变成彩色二维码的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前置知识drawImage方法可以把图片画到canv

这篇文章给大家分享的是有关javascript纯色二维码变成彩色二维码的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

前置知识

drawImage方法可以把图片画到canvas上,getImageData方法可以获得一个矩形区域所有像素点的信息,返回值的data属性是一个一维数组,储存了所有像素点的信息,一个像素点的信息会占四个元素,分别代表r,g,b和透明度。而像素点在一维数组中的顺序是从左到右,从上到下。最后就是putImageData方法,把更改过的像素信息数组重新扔回画布上。

一些小坑

第一个坑就是canvas用属性去给宽高,别用CSS

第二个坑,做图片处理好像得服务器环境,本地是不行的,听说是基于什么安全考虑,最后我是通过搭本地服务器解决了canvas的报错。

第三个坑,栈溢出,这个目前还没找到原因,后面会详细讲

变色的思路

主要思路来自于《啊哈!算法!》里面深度优先搜索和广度优先搜索的章节,该章节的最后一部分的“宝岛探险”实现了给不同的区域依次编号,把编号看成染色,其实是一样的。

具体实现

其实所谓的彩色二维码,不是那种每个像素点颜色随机的二维码。仔细观察二维码就会发现,黑色的部分是一块一块的,他们分布在白色当中,就好像岛屿分布在海里,我们要做的就是把每个黑色块单独染色。黑色块的实质就是一个一个黑色的像素点。

前面也提到,我们使用canvas是因为可以进行像素操作,所以我们的操作其实是给像素点染色,我们显然不希望给背景色染色,所以背景色需要进行一个判断;前面也提到,背景色好像海洋分割了黑色的颜色块,那也就是说我们读一个像素点进行染色之后,不停的判断它右侧的像素点颜色,当出现背景色的时候就说明到达了边界,可以停止右方向的染色,但是每个像素点其实有四个相连接的方向,当一个像素点右边就是背景色,我们应该也去尝试别的方向的可能性,这个就是深度优先搜索,通过递归,不断的验证当前像素点的下一个位置的颜色,是背景色,那就回来,尝试别的方向;不是背景色,那就染色,然后对染色之后的这个像素点进行四个方向的验证。

有几点提一下,判断是不是背景色,肯定得比对rgba的值,所以颜色参数得做处理,另一个就是像素点信息的数组,每四个元素代表一个像素,所以想要比对正确的像素信息,这部分也要处理。
可能说的有点乱,我们看一下代码

第一部分,canvas

// canvas 部分
var canvas = $("canvas")[0];
var ctx = canvas.getContext("2d");

var img = new Image();
img.src = path; //这里的path就是图片的地址

第二部分,颜色的处理

// 分离颜色参数  返回一个数组
var colorRgb = (function() {
  var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;

  return function(str) {
    var sColor = str.toLowerCase();
    if (sColor && reg.test(sColor)) {
      if (sColor.length === 4) {
        var sColorNew = "#";
        for (var i = 1; i < 4; i += 1) {
          sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
        }
        sColor = sColorNew;
      }
      //处理六位的颜色值 
      var sColorChange = [];
      for (var i = 1; i < 7; i += 2) {
        sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
      }
      return sColorChange;
    } else {
      var sColorChange = sColor.replace(/(rgb\()|(\))/g, "").split(",").map(function(a) {
        return parseInt(a);
      });
      return sColorChange;
    }
  }
})();

第三部分,给初始参数

为了避免多余的操作,我们用一个标记数组来记录判断过的位置

// 参数
var bg = colorRgb("#fff"); //忽略的背景色
var width = 220;
var height = 220;
var imgD; //预留给 像素信息
var colors = ["#368BFF", "#EF2767", "#F17900", "#399690", "#5aa6f7", "#fd417e", "#ffc000", "#59b6a6"];  //染色数组
// 随机colors数组的一个序号
var ranNum = (function() {
  var len = colors.length;
  return function() {
    return Math.floor(Math.random() * len);
  }
})();

// 标记数组 
var book = []; 
for (var i = 0; i < height; i++) { 
  book[i] = []; 
  for (var j = 0; j < width; j++) { 
    book[i][j] = 0; 
  } 
}

第四部分,获取像素信息,对每个像素点进行遍历处理,最后扔回canvas

如果标记过,那就跳过,如果没标记过,那就随机一个颜色,深度优先搜索并染色

img.onload = function() {
  ctx.drawImage(img, 0, 0, width, height);
  imgD = ctx.getImageData(0, 0, width, height);

  for (var i = 0; i < height; i++) {
    for (var j = 0; j < width; j++) {
      if (book[i][j] == 0 && checkColor(i, j, width, bg)) { //没标记过 且是非背景色
        book[i][j] = 1;
        var color = colorRgb(colors[ranNum()]);
        dfs(i, j, color);  //深度优先搜索
      }
    }
  }

  ctx.putImageData(imgD, 0, 0);
}


// 验证该位置的像素 不是背景色为true
function checkColor(i, j, width, bg) {
  var x = calc(width, i, j);

  if (imgD.data[x] != bg[0] && imgD.data[x + 1] != bg[1] && imgD.data[x + 2] != bg[2]) {
    return true;
  } else {
    return false;
  }
}

// 改变颜色值
function changeColor(i, j, colorArr) {
  var x = calc(width, i, j);
  imgD.data[x] = colorArr[0];
  imgD.data[x + 1] = colorArr[1];
  imgD.data[x + 2] = colorArr[2];
}


// 返回对应像素点的序号
function calc(width, i, j) {
  if (j < 0) {
    j = 0;
  }
  return 4 * (i * width + j);
}

关键代码

我们通过一个方向数组,来简化一下操作,我们约定好,尝试的方向为顺时针,从右边开始。

// 方向数组
var next = [
  [0, 1], //右
  [1, 0], //下
  [0, -1], // 左
  [-1, 0] //上 
];

// 深度优先搜索 
function dfs(x, y, color) {
  changeColor(x, y, color);
  for (var k = 0; k <= 3; k++) {
    // 下一个坐标
    var tx = x + next[k][0];
    var ty = y + next[k][1];

    //判断越界
    if (tx < 0 || tx >= height || ty < 0 || ty >= width) {
      continue;
    }


    if (book[tx][ty] == 0 && checkColor(tx, ty, width, bg)) {
      // 判断位置
      book[tx][ty] = 1;
      dfs(tx, ty, color);
    }

  }
  return;
}

我遇到的最后一个坑就是当长宽大于220时就会栈溢出,但是小于这个值就不会有问题,具体的原因还不清楚,猜测可能是判断那里有问题,导致死循环了。

全部代码在这里

// 分离颜色参数  返回一个数组
var colorRgb = (function() {
  var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;

  return function(str) {
    var sColor = str.toLowerCase();
    if (sColor && reg.test(sColor)) {
      if (sColor.length === 4) {
        var sColorNew = "#";
        for (var i = 1; i < 4; i += 1) {
          sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
        }
        sColor = sColorNew;
      }
      //处理六位的颜色值 
      var sColorChange = [];
      for (var i = 1; i < 7; i += 2) {
        sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
      }
      return sColorChange;
    } else {
      var sColorChange = sColor.replace(/(rgb\()|(\))/g, "").split(",").map(function(a) {
        return parseInt(a);
      });
      return sColorChange;
    }
  }
})();

// 验证该位置的像素 不是背景色为true
function checkColor(i, j, width, bg) {
  var x = calc(width, i, j);

  if (imgD.data[x] != bg[0] && imgD.data[x + 1] != bg[1] && imgD.data[x + 2] != bg[2]) {
    return true;
  } else {
    return false;
  }
}

// 改变颜色值
function changeColor(i, j, colorArr) {
  var x = calc(width, i, j);
  imgD.data[x] = colorArr[0];
  imgD.data[x + 1] = colorArr[1];
  imgD.data[x + 2] = colorArr[2];
}


// 返回对应像素点的序号
function calc(width, i, j) {
  if (j < 0) {
    j = 0;
  }
  return 4 * (i * width + j);
}

// 方向数组
var next = [
  [0, 1], //右
  [1, 0], //下
  [0, -1], // 左
  [-1, 0] //上 
];

// 深度优先搜索 
function dfs(x, y, color) {
  changeColor(x, y, color);
  for (var k = 0; k <= 3; k++) {
    // 下一个坐标
    var tx = x + next[k][0];
    var ty = y + next[k][1];

    //判断越界
    if (tx < 0 || tx >= height || ty < 0 || ty >= width) {
      continue;
    }


    if (book[tx][ty] == 0 && checkColor(tx, ty, width, bg)) {
      // 判断位置
      book[tx][ty] = 1;
      dfs(tx, ty, color);
    }

  }
  return;
}




var bg = colorRgb("#fff"); //忽略的背景色
var width = 220;
var height = 220;
var imgD; //预留给 像素信息数组
var colors = ["#368BFF", "#EF2767", "#F17900", "#399690", "#5aa6f7", "#fd417e", "#ffc000", "#59b6a6"];  //染色数组
// 随机colors数组的一个序号
var ranNum = (function() {
  var len = colors.length;
  return function() {
    return Math.floor(Math.random() * len);
  }
})();

// 标记数组 
var book = []; 
for (var i = 0; i < height; i++) { 
  book[i] = []; 
  for (var j = 0; j < width; j++) { 
    book[i][j] = 0; 
  } 
}


// canvas 部分
var canvas = $("canvas")[0];
var ctx = canvas.getContext("2d");

var img = new Image();
img.src = path; //这里的path就是图片的地址
img.onload = function() {
  ctx.drawImage(img, 0, 0, width, height);
  imgD = ctx.getImageData(0, 0, width, height);

  for (var i = 0; i < height; i++) {
    for (var j = 0; j < width; j++) {
      if (book[i][j] == 0 && checkColor(i, j, width, bg)) { //没标记过 且是非背景色
        book[i][j] = 1;
        var color = colorRgb(colors[ranNum()]);
        dfs(i, j, color);  //深度优先搜索
      }
    }
  }

  ctx.putImageData(imgD, 0, 0);
}

总结

虽然看起来有点长,其实大部分函数都在处理像素点的信息。实现起来,主要就是得对深度优先搜索有所了解,每个像素点都进行深度优先搜索,染过色的自然被标记过,所以当一个新的没标记过的像素点出现时,自然意味着新的颜色块。细节方面,就是注意一下imgD.data和像素点序号之间的对应关系,别的也就还好了。不过注意一点就是,因为像素点很小,所以肉眼觉得不相连的色块也有可能是连在一起的,会染成一样的颜色。

忘了放图了,这里放几张,拿qq截的,把外面的边框不小心也截了,嘛,凑活看看吧

JavaScript纯色二维码变成彩色二维码的示例分析

感谢各位的阅读!关于“JavaScript纯色二维码变成彩色二维码的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: JavaScript纯色二维码变成彩色二维码的示例分析

本文链接: https://www.lsjlt.com/news/78074.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript纯色二维码变成彩色二维码的示例分析
    这篇文章给大家分享的是有关JavaScript纯色二维码变成彩色二维码的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前置知识drawImage方法可以把图片画到canv...
    99+
    2022-10-19
  • 如何用CSS给普通黑色二维码添上彩色渐变
    本文小编为大家详细介绍“如何用CSS给普通黑色二维码添上彩色渐变”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何用CSS给普通黑色二维码添上彩色渐变”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,...
    99+
    2022-10-19
  • 基于Android实现个性彩色好看的二维码
    我编码的风格,先给大家展示下效果图,亲们感觉效果还不错,很满意的话,请继续往下阅读。 之前呢,也写过用安卓实现二维码生成彩色的二维码和带logo的二维码,也知道可以使用...
    99+
    2022-06-06
    二维 二维码 Android
  • 二维码图片生成器QRCode.js的示例分析
    这篇文章给大家分享的是有关二维码图片生成器QRCode.js的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。QRCode.js是一个实现生成二维码(QRCode)的js插...
    99+
    2022-10-19
  • js生成二维码的示例代码
    前段时间项目中需要开发扫描二维码查看信息的功能,在网上查了一些资料,把用过的方法进行总结需要导入一个qrcode的js 插件。 插件链接: qrcode.js下载地址,点击即可下载 ...
    99+
    2022-11-11
  • PHP实现生成二维码的示例代码
    目录前言1、目前有2种类型的二维码2、用户扫描带场景值二维码时,可能推送以下两种事件3、创建二维码ticket4、临时二维码请求说明5、永久二维码请求说明6、临时二维码和永久二维码生...
    99+
    2022-11-13
  • canvas中二维码邀请函生成插件的示例分析
    这篇文章将为大家详细讲解有关canvas中二维码邀请函生成插件的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。效果图:我看见效果后第一反映就是,肯定canvas进...
    99+
    2022-10-19
  • Python实现动态二维码生成的示例代码
    目录1.MyQR普通的二维码制作带背景图片的二维码制作带动图背景的二维码制作2.qrcode简单的二维码制作带背景图片的二维码制作大家好,我是辰哥~ 今天给大家分享两个制作二维码的P...
    99+
    2022-11-11
  • python应用之qrcode生成二维码的示例
    本文将为大家详细介绍“python应用之qrcode生成二维码的示例”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“python应用之qrcode生成二维码的示例”能够给你意想不到的收获,请大家跟着小编的思路慢...
    99+
    2023-06-06
  • Qt结合libqrencode生成二维码的实现示例
    目录0.前言1.编译 libqrencode2.Qt 中使用 libqrencode 0.前言 libqrencode 是一个生成二维码的 c 语言库,二维码的容量可达 7...
    99+
    2022-11-12
  • Java使用Zxing二维码生成的简单示例
    目录1、二维码简介2、ZXing简介3、示例3.1 搭建一个maven项目,引入Zxing依赖包3.2 创建QrCodeUtil.java 类总结1、二维码简介 二维条形码是用某种特...
    99+
    2023-01-17
    Java二维码生成 java代码生成二维码 java zxing二维码生成
  • 基于Koa2开发微信二维码扫码支付的示例分析
    这篇文章主要介绍基于Koa2开发微信二维码扫码支付的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!两种模式打开微信支付的文档,我们可以看到两种支付模式:模式一和模式二。这二者...
    99+
    2022-10-19
  • 基于JS实现二维码名片生成的示例代码
    目录演示技术栈源码cssjs演示 技术栈 这里用到了一个二维码生成库qrcode.js下面是简单介绍: //初始化QRCode对象 var qrcode = new QRCode...
    99+
    2022-11-13
  • Java生成读取条形码和二维码的简单示例
    条形码 将宽度不等的多个黑条和白条,按照一定的编码规则排序,用以表达一组信息的图像标识符 通常代表一串数字 / 字母,每一位有特殊含义 一般数据容量30个数字 / 字母 二维码 ...
    99+
    2022-11-12
  • vue中生成条形码(jsbarcode)和二维码(qrcodejs2)的简单示例
    目录1.条形码插件jsbarcode2.二维码插件总结1.条形码插件jsbarcode 安装:npm install jsbarcode --save 引入:在需要生成条形码的页面引...
    99+
    2022-12-27
    Vue生成二维码 vue 生成条形码 vue qrcode生成二维码
  • SpringBoot二维码生成base64并上传OSS的实现示例
    目录基础环境代码实现1.添加依赖2.工具类3.测试生成4.base64 转换为图片在线工具5.base64图片上传oss基础环境 SpringBoot、Maven 代码实现 1.添加...
    99+
    2022-11-13
  • vue生成二维码QR Code的简单实现方法示例
    目录qrcodejs2vue-qrqrcodejs2 下载qrcodejs2 cnpm i -S qrcodejs2 使用 <template> <span...
    99+
    2022-11-13
  • 使用javascript解析二维码的三种方式分别是什么
    使用javascript解析二维码的三种方式分别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、使用javascript解析二维码1、二维码是什么二维码就是将我们能...
    99+
    2023-06-25
  • 二维码的生成与识别如何应用于大数据分析?
    随着移动互联网的快速发展,二维码已经成为了人们生活中不可或缺的一部分,它不仅可以帮助我们快速获取信息,还可以用于支付、入口等方面。但是,除了这些基本的应用之外,二维码还有着更加广泛的应用领域,例如在大数据分析中的应用。 一、二维码的生成 ...
    99+
    2023-08-22
    二维码 大数据 编程算法
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作