How to convert a solid color QR code into a color QR code (JavaScript)

Source: Internet
Author: User
This article describes how to convert a JavaScript solid-color QR code into a color QR code, which has some reference value, interested friends can refer to this article for details about the JavaScript solid color QR code into a color QR code solution, with a certain reference value, interested friends can refer

This article mainly discusses how to color a solid QR code.

Some time ago, the company had such a business requirement that customers did not like the solid color QR code generated in the background, pure blue, pure purple, and pure green. They wanted color QR codes. Then this task is all on my head. Because it is image processing, the main idea is to rely on canvas and canvas to perform pixel operations. So I made some attempts and stepped on a small pitfall, the specific records are as follows.

Prerequisites

DrawImageYou can draw an image on the canvas,GetImageDataThe data attribute of the returned value is a one-dimensional array that stores the information of all pixels. The information of one pixel occupies four elements, representing r, respectively, g, B, and transparency. The order of pixels in a one-dimensional array is from left to right, from top to bottom. FinallyPutImageDataMethod to return the modified array of pixel information to the canvas.

Some pitfalls

The first pitfall is that canvas uses attributes to give width and height, and css is not used;

In the second pitfall, image processing seems like a server environment, which is not suitable for local use. I heard that the canvas error was solved by setting up a local server.

The third pitfall is stack overflow. No reason is found yet. I will explain it in detail later.

Changing colors

The main idea is "Aha! Algorithm! In the deep-Priority Search and breadth-first search sections, the "Island Adventure" in the last part of this chapter numbers different regions in sequence and regards the numbers as dyeing, which is actually the same.

Implementation

In fact, the so-called color QR code is not the random color of each pixel. After carefully observing the QR code, we will find that the black part is one piece. They are distributed in white, as if the islands are in the sea. What we need to do is to dye each black block separately. The essence of a Black Block is a black pixel.

As mentioned above, canvas is used for Pixel operations, so our operation is to dye the pixel. We obviously do not want to dye the background color, so we need to make a judgment on the background color; as mentioned above, the background color seems to have a black color block separated by the ocean. That is to say, after we read a pixel for dyeing, we constantly judge the color of the pixel on the right, when the background color appears, it indicates that the border is reached and the color in the right direction can be stopped. However, each pixel actually has four connected directions. When the right side of a pixel is the background color, we should also try the possibility of another direction. This is the deep priority search. Through recursion, we will constantly verify the color of the next position of the current pixel, which is the background color. Then we will return, try other directions. If it is not the background color, then dye the color and verify the colored pixel in four directions.

To determine whether it is a background color, you must compare the value of rgba. Therefore, the color parameter must be processed, and the other is the array of pixel information. Each of the four elements represents one pixel, therefore, to compare the correct pixel information, this part should also be processed.
It may be a bit messy. Let's take a look at the code.

Part 1, Canvas

// Var canvas = $ ("canvas") [0]; var ctx = canvas. getContext ("2d"); var img = new Image (); img. src = path; // The path here is the image address.

Part 2,Color Processing

// Return an array 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;} // process the six-digit color value 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 ;}}})();

Part 3,Give initial parameters

To avoid unnecessary operations, we use a tag array to record locations that have been determined.

// Parameter var bg = colorRgb ("# fff"); // The ignored background color var width = 220; var height = 220; var imgD; // reserved Pixel Information var colors = ["# effecbff", "# EF2767", "# F17900", "#399690", "#5aa6f7", "# fd417e ", "# ffc000", "#59b6a6"]; // a serial number of the random colors array var ranNum = (function () {var len = colors. length; return function () {return Math. floor (Math. random () * len) ;}}) (); // mark the array var book = []; for (var I = 0; I 

Part 4,Obtains pixel information, traverses each pixel, and finally throws it back to the canvas.

If it is marked, it will be skipped. If it is not marked, it will be a random color, and the depth will be searched and dyed first.

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

Key code

We use a direction array to simplify the operation. We agree that the direction of the attempt is clockwise, starting from the right.

// Direction array var next = [[0, 1], // right [1, 0], // bottom [0,-1], // left [-1, 0] // top]; // deep priority search function dfs (x, y, color) {changeColor (x, y, color); for (var k = 0; k <= 3; k ++) {// The next coordinate var tx = x + next [k] [0]; var ty = y + next [k] [1]; // determine if (tx <0 | tx> = height | ty <0 | ty> = width) {continue ;} if (book [tx] [ty] = 0 & checkColor (tx, ty, width, bg) {// judge the position book [tx] [ty] = 1; dfs (tx, ty, color) ;}} return ;}

The last pitfall I encountered was stack overflow when the length and width were greater than 220, but there was no problem if it was smaller than this value. The specific cause is unclear, the guess may be that there is a problem, resulting in an endless loop.

All code here

// Return an array 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;} // process the six-digit color value 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 ;}}})(); // verify that the pixel at this position is not truefunction 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];} // returns the serial number of the corresponding pixel. function calc (width, I, j) {if (j <0) {j = 0;} return 4 * (I * width + j);} // direction array var next = [[0, 1], // right [1, 0], // bottom [0,-1], // left [-1, 0] // top]; // deep priority search function dfs (x, y, color) {changeColor (x, y, color); for (var k = 0; k <= 3; k ++) {// The next coordinate var tx = x + next [k] [0]; var ty = y + next [k] [1]; // determine if (tx <0 | tx> = height | ty <0 | ty> = width) {continue ;} if (book [tx] [ty] = 0 & checkColor (tx, ty, width, bg) {// judge the position book [tx] [ty] = 1; dfs (tx, ty, color) ;}} return ;} /***** the encapsulated function ***** // *** parameter *****/var bg = colorRgb ("# fff "); // The ignored background color var width = 220; var height = 220; var imgD; // reserved for the pixel information array var colors = ["# effecbff", "# EF2767 ", "# F17900", "#399690", "#5aa6f7", "# fd0000e", "# ffc000", "#59b6a6"]; // dye the array // a serial number of the random colors array var ranNum = (function () {var len = colors. length; return function () {return Math. floor (Math. random () * len) ;}}) (); // mark the array var book = []; for (var I = 0; I 

Summary

Although it looks a little long, most functions are actually processing pixel information. To achieve this, you need to have a certain understanding of Deep-first search. Each pixel performs deep-first search, and the colored ones are naturally marked, so when a new unlabeled pixel appears, it naturally means a new color block. For details, pay attention to the correspondence between imgD. data and the pixel serial number. But note that because the pixels are small, the unconnected color blocks may also be connected and dyed in the same color.

I forgot to show the figure. Here I put a few screenshots and took qq screenshots. I accidentally cut the outer border. Well, let's take a look.

The above describes how to change a solid-color QR code to a color QR code (JavaScript). For more information, see other related articles in the first PHP community!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.