단색 QR 코드를 컬러 QR 코드로 변환하는 방법(JavaScript)
이 글에서는 주로 자바스크립트 단색 QR 코드를 컬러 QR 코드로 변환하는 솔루션을 자세히 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.
이 글에서는 주로 방법에 대해 소개합니다. 단색 QR 코드를 컬러로 변환합니다.
얼마 전 회사 사업에서 고객이 배경에 생성된 단색 QR 코드를 좋아하지 않는다는 요구가 있었습니다. 그들은 단색 QR 코드를 원하지 않았습니다. 코드. 그러다가 이 작업이 나에게 맡겨졌다. 이미지 처리이기 때문에 캔버스에 의존하는 것이 주된 아이디어였고, 캔버스는 픽셀 작업을 수행할 수 있기 때문에 몇 가지 시도를 했으나 몇 가지 함정에 부딪혔다.
전제 지식
drawImage 메소드는 캔버스에 그림을 그릴 수 있으며, getImageData는 메소드는 직사각형 영역의 모든 픽셀 정보를 얻을 수 있습니다. 반환 값의 데이터 속성은 모든 픽셀의 정보를 저장하는 1차원 배열입니다. 각각 r, g, b 및 투명도입니다. 1차원 배열의 픽셀 순서는 왼쪽에서 오른쪽, 위에서 아래입니다. 마지막은 변경된 픽셀 정보 배열을 캔버스로 다시 보내는 putImageData 메서드입니다.
몇 가지 작은 함정
첫 번째 함정은 캔버스가 속성을 사용하여 너비와 높이를 제공한다는 것입니다. CSS를 사용하지 마세요.
두 번째 함정 함정, 이미지 처리가 로컬에서는 불가능한 서버 환경이 필요한 것 같습니다.. 보안상의 문제로 인해 결국 로컬 서버를 설정하여 캔버스 오류를 해결했습니다.
세 번째 함정은 아직까지 원인을 찾지 못한 경우입니다.
색상 변경 아이디어
주요 아이디어는 "아하!"에서 나옵니다. 연산! 깊이 우선 탐색과 너비 우선 탐색 장에서는 장의 마지막 부분인 '보물섬 모험'에서 서로 다른 지역의 순차적인 번호 매기기를 구현합니다. 숫자를 색칠이라고 생각하지만 실제로는 동일합니다.
구체적인 구현
사실 컬러QR코드는 픽셀 하나하나의 색상이 랜덤하게 나오는 그런 QR코드가 아닙니다. QR코드를 자세히 보면 검은 부분이 하나하나씩 흰색 부분에 분포되어 있는 것을 알 수 있는데, 마치 바다에 분포되어 있는 섬처럼 검은 부분을 하나하나 염색해야 하는 것입니다. . 검은색 블록의 핵심은 검은색 픽셀이다.
앞서 언급했듯이 픽셀 작업을 수행할 수 있기 때문에 캔버스를 사용하므로 실제로 픽셀을 염색하는 작업입니다. 분명히 배경색을 염색하고 싶지 않으므로 배경색을 판단해야 합니다. 이전에는 배경색이 검은 색 블록을 나누는 바다와 같다고도 했는데, 이는 픽셀을 읽고 염색한 후 배경색이 결정되면 끊임없이 픽셀의 색상을 판단한다는 의미입니다. 경계가 올바른 방향으로 색칠되는 것을 멈출 수 있지만 실제로는 각 픽셀의 오른쪽이 배경색인 경우 다른 방향의 가능성도 시도해야 합니다. 깊이 우선 탐색은 재귀를 통해 현재 픽셀의 다음 위치의 색상이 배경색인지 지속적으로 확인하고, 다시 돌아와서 배경색이 아닌 경우 다른 방향을 시도한 다음 염색합니다. 염색된 픽셀의 네 방향을 확인합니다.
몇 가지 언급할 사항이 있습니다. 배경색인지 확인하려면 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; } }
네 번째 부분인 픽셀 정보를 얻고, 각 픽셀을 순회한 후 마지막으로 캔버스에 다시 던집니다.
표시된 경우 건너뛰고, 그렇지 않은 경우 무작위로 색상을 지정합니다. , 깊이 우선 검색 및 염색
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 스크린샷을 찍다가 실수로 바깥쪽 테두리가 잘렸네요.
위 내용은 단색 QR 코드를 컬러 QR 코드로 변환하는 방법(JavaScript)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











1. 소프트웨어를 열고 wps 텍스트 작업 인터페이스로 들어갑니다. 2. 이 인터페이스에서 삽입 옵션을 찾으세요. 3. 삽입 옵션을 클릭하고 편집 도구 영역에서 QR 코드 옵션을 찾으세요. 4. QR 코드 옵션을 클릭하면 QR 코드 대화 상자가 나타납니다. 5. 왼쪽의 텍스트 옵션을 선택하고 텍스트 상자에 정보를 입력하세요. 6. 오른쪽에서는 QR코드의 모양과 색상을 설정할 수 있습니다.

WebSocket 및 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법 소개: 지속적인 기술 개발로 음성 인식 기술은 인공 지능 분야의 중요한 부분이 되었습니다. WebSocket과 JavaScript를 기반으로 한 온라인 음성 인식 시스템은 낮은 대기 시간, 실시간, 크로스 플랫폼이라는 특징을 갖고 있으며 널리 사용되는 솔루션이 되었습니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 음성 인식 시스템을 구현하는 방법을 소개합니다.

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

JavaScript 및 WebSocket을 사용하여 실시간 온라인 주문 시스템을 구현하는 방법 소개: 인터넷의 대중화와 기술의 발전으로 점점 더 많은 레스토랑에서 온라인 주문 서비스를 제공하기 시작했습니다. 실시간 온라인 주문 시스템을 구현하기 위해 JavaScript 및 WebSocket 기술을 사용할 수 있습니다. WebSocket은 TCP 프로토콜을 기반으로 하는 전이중 통신 프로토콜로 클라이언트와 서버 간의 실시간 양방향 통신을 실현할 수 있습니다. 실시간 온라인 주문 시스템에서는 사용자가 요리를 선택하고 주문을 하면

WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법 오늘날의 디지털 시대에는 점점 더 많은 기업과 서비스에서 온라인 예약 기능을 제공해야 합니다. 효율적인 실시간 온라인 예약 시스템을 구현하는 것이 중요합니다. 이 기사에서는 WebSocket과 JavaScript를 사용하여 온라인 예약 시스템을 구현하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. WebSocket이란 무엇입니까? WebSocket은 단일 TCP 연결의 전이중 방식입니다.

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

Enterprise WeChat의 QR 코드를 로드할 수 없으면 어떻게 해야 합니까? Enterprise WeChat의 컴퓨터 버전에 로그인할 때 QR 코드를 로드할 수 없고 표시할 수 없는 경우 어떻게 해야 합니까? 여기서 편집자는 Enterprise의 QR 코드가 발생하는 문제에 대한 해결 방법을 자세히 설명합니다. WeChat을 로드할 수 없습니다. 필요한 사람은 누구나 와서 살펴보세요! 방법 1. 네트워크 이유 1. 네트워크 속도가 느려 로딩이 느려지고 표시가 되지 않을 수 있습니다. 연결을 끊었다가 다시 연결해 보세요. 2. 컴퓨터 자체의 네트워크 문제를 확인하여 네트워크에 연결되어 있는지 확인하세요. 네트워크 장치를 다시 시작할 수 있습니다. 방법 2: 유지 관리 및 업데이트: Enterprise WeChat 버전이 너무 낮아서 QR 코드가 생성되지 않을 수 있습니다. 소프트웨어를 최신 버전으로 업그레이드할 수 있습니다. 방법 3, 방화벽 1
