二維碼是近年來出現的比較流行的移動端編碼方式,有了它,我們在手機上訪問網站、查看信息、添加好友等再不用手支輸入了,我這裏說的二維碼指的是QR Code碼,不是小程序碼或一維碼。最近公司的小程序項目中也上了掃碼功能,用於查看一合格證或產品信息,當然這個好說,因爲小程序有可用的開放掃碼api可用,so,這個功能很快的實現了:
wx.scanCode({
scanType: 'qrCode',
success: (res) => {
//根據掃碼的結果跳轉至目標頁面進行展示,內容不便貼出。
}
})
一個功能的出現,隨之而來的就是boss挑剔的眼光,我們都知道,微信如今的掃碼是全屏的,不能設計樣式的,boss就問,這個界面太醜了,能不能優化一下,讓樣式調整一下,能不能?你說這個問題我說能不能,說不能的馬上就是一句質疑:爲毛別的都這麼好看咱的就不行,改!沒辦法,改吧,於是,從官方文檔中查找答案,結論是scancode這個調起的界面沒法改,不過可以使用camera。於是改良版的也面世了:
wxml:
<camera class='scan-camera' mode="scanCode" binderror="cameraError" bindscancode='scancode' frame-size='large'>
<view class="cover-corner cover-left-top"></view>
<view class="cover-corner cover-right-top"></view>
<view class="cover-corner cover-left-bottom"></view>
<view class="cover-corner cover-right-bottom"></view>
</camera>
wxss:
.scan-camera {
width:480rpx;
height: 480rpx;
border-radius: 6rpx;
margin: 30rpx;
margin-top: 20rpx;
position: relative;
}
.cover-corner {
width: 150rpx;
height: 150rpx;
position: absolute;
}
.cover-left-top {
left: 0;
top: 0;
border-top: 2px solid #04e461;
border-left: 2px solid #04e461;
}
.cover-right-top {
right: 0;
top: 0;
border-top: 2px solid #04e461;
border-right: 2px solid #04e461;
}
.toView{
color:#fff;
float:right;
margin-right:10px;
padding:2px 16px;
background-color:#25b97e;
font-size: 24rpx;
border-radius: 24rpx;
}
.cover-left-bottom {
left: 0;
bottom: 0;
border-bottom: 2px solid #04e461;
border-left: 2px solid #04e461;
}
.cover-right-bottom {
right: 0;
bottom: 0;
border-bottom: 2px solid #04e461;
border-right: 2px solid #04e461;
}
.scan-animation {
position: absolute;
top: 10rpx;
left: 10rpx;
width: 460rpx;
height: 6rpx;
background-color: #04e461;
border-radius: 50%;
background: -webkit-linear-gradient(to right, rgba(4,228,97,0) 0, rgba(4,228,97,1) 50%, rgba(4,228,97,0) 100%);
}
js
scancode(e){
// 此處爲掃碼結果
}
ok,一頓操作之後,頁面是出來了,掃碼效果也不錯,再加上頁面背景圖片,看起來確實是美觀了不少。然而,boss的眼中是不能揉時沙子的,問:如何從相冊中選擇圖片進行掃碼,以前就有的,現在怎麼沒了?怎麼沒了這件事兒明顯不是一個疑問句,那就繼續改。從網上搜了一下,還真有相關的js----jsQR和qrcode兩者都可以實現二維碼解析,於是,一頓操作+複製之後,又添加了新的功能,從選擇相冊中選擇圖片實現解碼的功能實現了:
wx.chooseImage({
count: 1,
success(res){
wx.getImageInfo({
src: res.tempFilePaths[0],
success(info){
self.setData({
width:info.width,
height:info.height,
});
setTimeout(() => {
let ctx = wx.createCanvasContext('canvas');
ctx.drawImage(res.tempFilePaths[0],0,0,info.width,info.height)
ctx.draw();
setTimeout(() => {
wx.canvasGetImageData({
canvasId: 'canvas',
height:320,
width: 640,
x: 0,
y: 0,
success: (result) => {
let r = jsQR(result.data,result.width,result.height,{
inversionAttempts: "dontInvert",
});
if(!r){
wx.showToast({
title: '請選擇清晰的二維碼圖片',
icon:"none"
})
}else{
let e = {detail:{}};
e.detail.result = r.data;
// 處於解析後的二維碼內容
}
console.log(r)
},
fail: (res) => {},
complete: (res) => {},
}, this)
}, 20);
}, 500);
}
})
}
})
馬上選擇一張圖片,完美,好了,這下可以交差了,該有的功能都有了。這個功能終於可以放下了,不用再折騰了。
理想與現實總是存在着不一致的樣子,比如這個功能,沒有想像中的清閒,有的是更大的麻煩:jsQR這個是可以實現識別二維碼的功能,但是,它有一個大大的缺點,就是它的識別精度太低了,如果一個圖片中的二維碼能夠佔據頁面一半以上的話,它能很快的識別,而反之,則直接說找不到二維碼,這下可好,boss怎麼可能會同意,試了試qrcodejs也會面臨這個尷尬的問題,沒辦法 ,找方案吧,網上一看,說是如果在掃碼前使用opencv對圖片進行處理,定位並截取到二維碼,再對二維碼進行解析,emmmm這個方法不錯,剛好可以網上也有說把oepncv打包成js文件,前端也可以使用,於是滿懷開心的進行操作,然而當我得到js文件時,傻眼了,連同js文件帶它的一個data文件,大小7M多,可是小程序有規定——小程序的所有的包的大小不大於8M每個分包不大於2M,這。。。我爲了實現一個掃碼,把其他功能都砍了?
終極方案,既然前端無法處理這個問題,那就讓後臺來解決吧,於是告訴後臺大佬們,他們最後是在後臺使用ZXing + openCV來實現這個功能,我向後臺傳一張圖片,然後後臺處理該圖片,並獲取二維碼中的參數。當然效果不如微信的快,但是夠用,想想光是這個二維碼解析的問題,我都做了什麼鬼操作,當時是多麼希望微信官方能開放這個二維碼解析的接口或scancode這個接口實現可設計,
最後,說明一下,寫這篇文件是在告訴我,如果再遇到這種需求,直接交給後臺處理圖片或從阿里中找現成的接口,不必走彎路。