Javascriptでバーコードを読む
問題
Javascriptで画面上のバーコード画像からデータを読めますか?
答え
canvasに流し込んでビットマップを解析~の流れのようです。
思ったより簡単そうに見える実装で、白黒がきれいに判断できて、きれいに横を向いているときはうまくいくかなと思います。
細かい突っ込みですが、画像のサイズをオリジナルのサイズから拡大、縮小して白黒が若干ぼやけると(?)読めなくなったりするようです。
/* * Copyright (c) 2010 Tobias Schneider * This script is freely distributable under the terms of the MIT license. */ (function(){ var UPC_SET = { "3211": '0', "2221": '1', "2122": '2', "1411": '3', "1132": '4', "1231": '5', "1114": '6', "1312": '7', "1213": '8', "3112": '9' }; getBarcodeFromImage = function(imgOrId){ var doc = document, img = "object" == typeof imgOrId ? imgOrId : doc.getElementById(imgOrId), canvas = doc.createElement("canvas"), ctx = canvas.getContext("2d"), width = img.width, height = img.height, spoints = [1, 9, 2, 8, 3, 7, 4, 6, 5], numLines = spoints.length, slineStep = height / (numLines + 1); canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0); while(numLines--){ console.log(spoints[numLines]); var pxLine = ctx.getImageData(0, slineStep * spoints[numLines], width, 2).data, sum = [], min = 0, max = 0; for(var row = 0; row < 2; row++){ for(var col = 0; col < width; col++){ var i = ((row * width) + col) * 4, g = ((pxLine[i] * 3) + (pxLine[i + 1] * 4) + (pxLine[i + 2] * 2)) / 9, s = sum[col]; pxLine[i] = pxLine[i + 1] = pxLine[i + 2] = g; sum[col] = g + (undefined == s ? 0 : s); } } for(var i = 0; i < width; i++){ var s = sum[i] = sum[i] / 2; if(s < min){ min = s; } if(s > max){ max = s; } } var pivot = min + ((max - min) / 2), bmp = []; for(var col = 0; col < width; col++){ var matches = 0; for(var row = 0; row < 2; row++){ if(pxLine[((row * width) + col) * 4] > pivot){ matches++; } } bmp.push(matches > 1); } var curr = bmp[0], count = 1, lines = []; for(var col = 0; col < width; col++){ if(bmp[col] == curr){ count++; } else{ lines.push(count); count = 1; curr = bmp[col]; } } var code = '', bar = ~~((lines[1] + lines[2] + lines[3]) / 3), u = UPC_SET; for(var i = 1, l = lines.length; i < l; i++){ if(code.length < 6){ var group = lines.slice(i * 4, (i * 4) + 4); } else{ var group = lines.slice((i * 4 ) + 5, (i * 4) + 9); } var digits = [ Math.round(group[0] / bar), Math.round(group[1] / bar), Math.round(group[2] / bar), Math.round(group[3] / bar) ]; code += u[digits.join('')] || u[digits.reverse().join('')] || 'X'; if(12 == code.length){ return code; break; } } if(-1 == code.indexOf('X')){ return code || false; } } return false; } })();
回転していても、若干ぼやけていても、きちんと読めるようにするには。。。 どうしましょう。
コメント