您的位置 首页 > 数码极客

“如何识别相册二维码“识别相册二维码是老是闪退!

背景

最近有接触到针对二维码进行识别的功能,然后对图片进行位置纠正、二维码扫描,并将数据进行整理。以下是通过nodejs做的,相对简单一些,没有太过严格,识别率也不是很高大约80%左右。

思路

  1. 对FTP的目录进行监听,上传图片后,对图片进行处理。
  2. 二维码的位置,在图片的右上角和右下角,因此可以通过切图进行位置的确定,然后对图片进行旋转。
  3. 将图片切图后,对每一片进行二维码扫描,并获得二维码的内容
  4. 将获得的数据通过接口传递到API中,同时上传压缩后的图片

分步进行

一、FTP目录监听 监听这里我用的是chokidar,代码如下:

var chokidar = require('chokidar'); var config = require('./data'); var Util = require('./Util');//工具类,下面放代码 U('服务器启动,开始对目标目录进行监听:'+con); var watcherIns = null; watcherIns = c(con,{ persistent : true }); wa('add',function(filePath){ //获得图片,再查找da 的内容,配置文件在da中 U('监测到有文件添加进入,文件路径为:'+filePath); var newName = U(filePath);//获得名称 U('随机获得文件的新名字:'+newName) exeFileOpt(newName,filePath); }); function loopExe (){ var fileName = U(); if(fileName){ U('处理错误信息:['+fileName+']'); exeFileOpt(fileName); } setTimeout(function(){ loopExe(); },10000);//每5s执行一次,超过三次放弃 } loopExe();//执行 function exeFileOpt ( newName,filePath ){ if(filePath){ var createTime= U(filePath); U('['+newName+']获得文件创建时间:'+createTime); U[newName].time = createTime; } //3.对图片进行分割:4部分,r/b/l/t--右上角、右下角、左下角、左上角; a([ function(callback){ U(newName,callback); }, function(fileName,callback){ U(fileName,callback); }, function(fileName,callback){ U(fileName,callback); }, function(fileName,callback){ U(fileName,callback); }, function(fileName,callback){ U(fileName,callback); } ],function(err,result){ if(err){ con(err); U('['+newName+']执行过程报错'); U(); U(newName); }else{ U('['+newName+']执行完毕'); U(); U(newName); } }); }

二、对图片进行切图,然后扫描二维码。其中,对于图片的处理,使用的是imagemagick,二维码识别使用的是qrcode-reader. 由于我这里使用的是windows系统,所以安装imagemagick比较简单,直接安装就可以了,放个imagemagick 官网地址。 这里面有一个小坑,安装程序的时候,一定要选中install legacy utilitie. convert),我安装的版本是7.

对于二维码识别,是基于zxing的nodejs版本,识别率不是很高,但是勉强可以,我是先把图片处理了一下,尽量提高识别率。 工具类代码:

/*** 1.处理图片操作 2.处理二维码 3.处理位置 ***/ var gm = require('gm');//图片操作 var magick = gm.subClass({imageMagick : true});//实体 // var magick =require('gm').subClass({ imageMagick : true }); // var gm = require('gm'); var fs = require('fs');//文件操作 var QrCode = require('qrcode-reader');//二维码读取 var Jimp = require('jimp');//bitmap var moment = require('moment');//moment var path = require('path'); var async = require('async'); var config = require('./data'); var superagent = require('superagent'); var Util = { cache : {},//存放每一个图片的具体信息 error : {},//存放错误的具体信息 delay : {}//存放延迟处理的文件夹集合 }; /** * 错误机制 * 1. 将错误的图片放在内存中 * 2. 定时去处理错误的信息(比如五分钟处理一次?或者一分钟检查一次) * 3. 将成功后的文件消灭掉,并更新 **/ //添加错误信息 U = function( fileName ){ var info = U[fileName]; if(info){ //判断error中是否存在 i[fileName]){ in = in + 1; U[fileName] = info; if(in > 3){ U(fileName); } }else{ in = 1; U[fileName] = info; } } }; //删除错误信息 U = function( fileName ){ var info = U[fileName]; if(info){ U[fileName] = null; delete U[fileName]; } }; //获得第一个错误信息 U = function(){ var first = null; for(var key in U){ if(key && U[key]){ first =key; break; } } return first; }; //成功+1 U = function(){ var data = require('./analysis'); var all = da || 0; all ++ ; var now = moment(new Date()).format('YYYY-MM-DD'); var today = data[now] || 0; today ++ ; da = all; data[now] = today; ('.;,JSON.stringify(data)); }; //失败+1 U = function(){ var data = require('./analysis'); var all = da || 0; all ++ ; var error = da || 0; error ++ ; da = all; da = error; ('.;,JSON.stringify(data)); } //日志处理 U = function(str){ var now = moment(new Date()).format('YYYY-MM-DD HH:mm:ss'); //1.打印 str = typeof str === 'string' ? str : (); var info = now +'\t'+str+'\n'; // con(info); //2.写入文件 var nowDate = moment(new Date()).format('YYYY-MM-DD'); var logPath = (__dirname,'logs',nowDate+'.log'); i(logPath)){ (logPath,info,function(err){ if(err){ con(err); } }); }else{ (logPath,info,function(err){ if(err){ con(err); } }); } }; //对时间进行格式化 U = function(time){ return moment(time).format('YYYY-MM-DD HH:mm:ss'); }; //获得文件的创建时间 U = function(filePath){ var stats = (filePath); return U); }; //获得随机ID U = function(filePath){ var guid = (+new Date()).toString( 32 ),i = 0; for ( ; i < 5; i++ ) { guid += Ma( Ma() * 65535 ).toString( 32 ); } while(U[guid]){ guid = U(); } if(filePath){ U[guid] = { filePath : filePath, extname : (filePath) }; } return guid; }; //创建目录 U = function( dirpath ){ dirpath = (dirpath); try{ if (!(dirpath)) { var pathtmp; dir(/[/\\]/).forEach(function (dirname) { //这里指用/ 或\ 都可以分隔目录 如 linux的/usr/local/services 和windows的 d:\temp\aaaa if (pathtmp) { pathtmp = (pathtmp, dirname); }else { pathtmp = dirname; } if (!(pathtmp)) { if (!(pathtmp, 0777)) { return false; } } }); } return true; }catch(e){ U('文件夹目录创建失败:'+dirpath+'\n'+e.toString()); return false; } } //对图片进行压缩 U = function( fileName ,callback){ var info = U[fileName]; //将图片压缩 var filePath = in; var date = moment(new Date()).format('YYYYMMDD'); var extname = (filePath); //目标路径 var newPath = '/byymoral/'+date+'/'+fileName+'-thumb'+extname; var targetPath = ); magick(filePath).resize).density).write(targetPath,function(err){ if(err){ U()); } in = newPath; U[fileName] = info; callback(null,fileName); }); }; //复制图片 U = function(fileName,callback){ var info = U[fileName]; var filePath = in; //给定时间 var date = moment(new Date()).format('YYYYMMDD'); var extname = (filePath); var newPath = '/byymoral/'+date+'/'+fileName+extname; //如果路径不存在,则创建 U('['+fileName+']移动后新路径为'+newPath); in = newPath; U[fileName] = info; //将图片移动到某位置 var movePath = ); if(U(movePath)){ //复制过去,压缩后 magick(filePath).density).quality).write(movePath,function(err){ if(err){ var data = (filePath); (movePath,data); U()); } U('['+fileName+']复制成功,由'+filePath+'复制到'+newPath); callback(null,fileName); }); } }; //对buffer读取二维码内容 U = function(buffer){ var qr = new QrCode(); qr.callback = function(err2, value) { if (err2) { //没有二维码 U('['+fileName+']'+(['右上角','右下角','左下角','左上角'][pos])+'无二维码'); rs.has = false; rs.msg = '图片没有二维码'; cb(null,rs); }else{ rs.has = true; U('['+fileName+']'+(['右上角','右下角','左下角','左上角'][pos])+'二维码内容:'+value.result); rs.result = value.result; //根据宽高计算位置和大小 cb(null,rs); } }; qr.decode); } //识别二维码 U = function(fileName,filePath,pos,cb){ var rs = { has : false, pos : pos }; //读取图片是否有二维码 var buffer = (filePath); (filePath); Jimp.read(buffer).then(function(blockimg){ var qr = new QrCode(); qr.callback = function(err2, value) { if (err2) { //没有二维码 U('['+fileName+']'+(['右上角','右下角','左下角','左上角'][pos])+'无二维码'); rs.has = false; rs.msg = '图片没有二维码'; cb(null,rs); }else{ rs.has = true; U('['+fileName+']'+(['右上角','右下角','左下角','左上角'][pos])+'二维码内容:'+value.result); rs.result = value.result; //根据宽高计算位置和大小 cb(null,rs); } }; qr.decode); }).catch(function(err2){ if(err2){ U()); cb(err2); } }); }; //对图片进行裁切 U = function(fileName,filePath,targetPath,width,height,x,y,pos,callback){ magick(filePath).crop(width,height,x,y) .contrast(0) .resize(1500) // .sharpen(0,10) // .whiteThreshold(50,50,50) .threshold('75%') .write(targetPath,function(err){ if(err){ U()); callback(err); }else{ U('['+fileName+']截取'+(['右上角','右下角','左下角','左上角'][pos])+'图片成功'); U(fileName,targetPath,pos,function(err2,rs){ callback(err2,rs); }); } }) }; //获得旋转度数 U = function( arr ){ //四个角,右上角和右下角有--,可能存在的情况 01 12 23 30,如果是单独的则是0 1 2 3 var target = ['01','12','23','03']; var num = 0; var ts = []; var str = [];//内容 //排序 arr.sort(function(a,b){ return a.pos > b.pos; }); arr.forEach(function( item ){ i){ ); ); num ++ ; } }); // if(num == 1){//只有一个,肯定在右上角 var temp = ts[0]; var rs = { degree : -temp * 90, result : str }; return rs; }else if(num == 2){ var temp = ().join(''); i(temp)>-1){ var rs = { degree : - (temp) * 90, result : temp === '03' ? () : str }; return rs; } } return { degree : 0, result : str }; }; //整理数据,提交到接口 U = function(fileName,callback){ /*** * 整理数据: * 1.图片的创建时间 * 2.图片转移后的路径 * 3.二维码的内容 * 4. ***/ var info = U[fileName]; var degree = in; var result = ['']; i){ result = degree.result; } var data = { createTime : in, content0 : result[0], content1 : re > 1 ? result[1] : '', filePath : in, thumb : in }; U('['+fileName+']调用接口发送数据:'+JSON.stringify(data)); superagent .po) // .send(data) .field('createTime',in) .field('content0',result[0]) .field('content1',re >1 ? result[1] : '') //attach file .attach('file',(config.target,in)) .attach('thumb',(config.target,in)) .end(function(err,res){ if(err){ U('['+fileName+']调用接口失败'+err.toString()); callback(err); }else{ // var txt = res.text; U('['+fileName+']调用接口成功'); //删除源文件 (in); U('['+fileName+']删除源文件成功'+in); callback(null); } }); } //旋转 U = function(fileName,callback){ var info = U[fileName]; if(info && in){ var filePath = in,degree = in.degree; if(degree !== 0){ magick(filePath).rotate('width',degree).write(filePath,function(err){ if(err){ U('['+fileName+']旋转图片角度失败'); callback(err);//即便是失败也要上传 }else{ U('['+fileName+']旋转图片角度'+degree+'° 成功'); callback(null,fileName); } }); }else{ callback(null,fileName); } }else{ callback(null,fileName); } }; //图片分割并识别二维码 U = function( fileName,callback ){ var info = U[fileName]; var filePath = in; //通过gm对文件进行分割成四个分片并保存 setTimeout(function(){ Jimp.read(filePath).then(function(image){ var width = image.bi = image.bi; U('['+fileName+']获得图片宽高:w='+width+'px;h='+height+'px'); var hwidth = width /2 ,hheight = height /2 ; var targetPath = (__dirname,'crop'); var ext = (fileName); var rpath = (targetPath,fileName+'-r'+in); var bpath = (targetPath,fileName+'-b'+in); var lpath = (targetPath,fileName+'-l'+in); var tpath = (targetPath,fileName+'-t'+in); var hasCode = false; //同时进行 a([ function(callback){//右上角,根据宽高比对 var a,b,c,d; if(width >= height){//横向 a = width / 4; b = height /2 ; c = width /4 * 3; d = 0; }else{ a = width /2; b = height /4; c = width /2; d = 0; } U(fileName,filePath,rpath,a,b,c,d,0,callback); }, function(callback){//右下角 var a,b,c,d; if(width >= height){//横向 a = width /4; b = height /2; c = width /4 * 3; d = height /2; }else{ a = width /2; b = height /4; c = width /2; d = height/4*3; } U(fileName,filePath,bpath,a,b,c,d,1,callback); }, function(callback){//左下角 var a,b,c,d; if(width >= height){//横向 a = width /4; b = height /2; c = 0; d = height /2; }else{ a = width /2; b = height /4; c = 0; d = height /4 *3; } U(fileName,filePath,lpath,a,b,c,d,2,callback); }, function(callback){//左上角 var a,b,c,d; if(width >= height){//横向 a = width /4; b = height/2; c = 0; d = 0; }else{ a = width /2; b = height/4; c = 0; d =0; } U(fileName,filePath,tpath,a,b,c,d,3,callback); } ],function(err3,res){ if(err3){ U()); callback(err3); }else{ var degree = U(res);//获得度数 in = degree;//设置度数信息和二维码内容 U[fileName] = info; callback(null,fileName); } }); }).catch(function(err){ if(err){ U()) callback(err); } }); },500); }; module.exports = Util;

核心代码已经在上面了,主要的处理就是:图片切割、二维码识别、图片处理、接口调用。 附上一张页面图:

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“如何识别相册二维码,识别相册二维码是老是闪退,如何识别相册二维码图片,如何识别照片二维码,识别相册二维码捷径”边界阅读