微信小程序掃描識別圖片 --微信小程序 IOS下camera組件takePhoto時 有快門聲音


需求:掃描識別實物,根據實物展示出對應的效果,實際就是一個camera然后弄了點動畫偽裝成掃描,然后截取圖片,傳給后端,后端進行識別。因為是快一年前的項目了 ,有些地方記不太清楚了。

開始是用camera組件takePhoto每500毫秒獲取一次圖片然后發送請求識別圖片發現在 IOS下會有快門聲音

 

      this.cameraCtx.takePhoto({
        quality: 'high',
        success: (res) => {
          wx.uploadFile({
            url: "https://****",
            method: "post",
            filePath: res.tempImagePath,
            name: 'file',
            header: {
              "content-type": "multipart/form-data"
            },
            success: (res) => {
            //.....
            }
          });
        },
        fail: () => {
        }
      });

 

快門聲音是iOS系統的限制,除非用戶靜音,目前沒辦法關閉,於是又換成camera組件onCameraFrame(獲取 Camera 實時幀數據)通過UPNG.js將實時幀數據轉成base64,然后在

通過wx.getFileSystemManager().writeFile()將base64轉成臨時圖片發送給后端進行圖片識別。 快門聲是沒有了,但是轉出來的臨時圖片不夠清晰,影響到識別的准確率,而且好像UPNG.js方法在真機上有些慢具體記不太清了。
 
          
  import upng from '../../utils/UPNG.js'
this.cameraCtx.onCameraFrame((frame) => {
   this.transformArrayBufferToBase64(frame);
});
 //轉化base64編碼格式
  transformArrayBufferToBase64: function (frame) {
    let base64x = upng.encode([frame.data], frame.width, frame.height, 0)
    let base64 = "data:image/png;base64," + wx.arrayBufferToBase64(base64x)
    const fsm = wx.getFileSystemManager();
    const FILE_BASE_NAME = 'tmp_base64src';
    const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
    if (!format) {
      console.log('format')
      console.log(base64)
      return (new Error('ERROR_BASE64SRC_PARSE'));
    }
    const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
    const buffer = base64x;
    const _this = this
    fsm.writeFile({
      filePath,
      data: buffer,
      encoding: 'binary',
      success() {
        wx.uploadFile({
          url: "http://192.168.0.117:9000/searchVideo",
          method: "post",
          filePath: filePath,
          name: 'file',
          header: {
            "content-type": "multipart/form-data"
          },
          success: (res) => {
          },
          fail() {
          }
        });
      },
      fail() {
        return (new Error('ERROR_BASE64SRC_WRITE'));
      }
    })
  },
 

因為圖片不夠清晰,於是又找到wx.canvasPutImageData畫到canvas上然后用wx.canvasToTempFilePath返回個圖片。(這么做好像是安卓手機上返回的圖片大小有問題,影響到識別的准確率,具體記不太清楚了,反正是安卓有點問題

<canvas  id="tempCanvas" height="{{Height*2}}" width="{{Width*2}}" canvas-id="tempCanvas" style="width:{{Width}}px; height:{{Height}}px"></canvas>
this.cameraCtx.onCameraFrame((frame) => {
this.setData({
            Height: frame.height,
            Width: frame.width
          })
          var data = new Uint8Array(frame.data);
          var clamped = new Uint8ClampedArray(data);
          this.temframe = {};
          this.temframe.width = frame.width;
          this.temframe.height = frame.height;
          this.temframe.data = clamped;
          this.transformArrayBuffer();
});
transformArrayBuffer: function () {
var tf = this.temframe; var _this = this; console.log(tf) wx.canvasPutImageData({ canvasId: 'tempCanvas', x: 0, y: 0, width: tf.width, height: tf.height, data: tf.data, success: function (res) { console.log('繪制成功', res) _this.scaning = true; wx.canvasToTempFilePath({ x: 0, y: 0, width: tf.width, height: tf.height, canvasId: 'tempCanvas', fileType: 'jpg', destWidth: tf.width, destHeight: tf.height, // 精度修改 quality: 1, success(res) { console.log(res.tempFilePath) wx.uploadFile({url: "http://192.168.0.128:9000/searchVideo", method: "post", filePath: res.tempFilePath, name: 'file', header: { "content-type": "multipart/form-data" }, success: (res) => { }, fail(res) { } }) }, fail(res) { console.log('console.log(res);', res); setTimeout(() => { _this._takePhoto(); }, 500); } }); }, fail: function (e) { console.log('res', e); setTimeout(() => { _this._takePhoto(); }, 500); } }); },

最后經過思考決定安卓手機用最開始的takePhoto獲取圖片,ios手機用wx.canvasPutImageData畫到canvas的方法,這樣圖片清晰了,快門聲音也沒有了。

<canvas wx:if="{{system=='ios'}}" id="tempCanvas" height="{{Height*2}}" width="{{Width*2}}" canvas-id="tempCanvas" style="width:{{Width}}px; height:{{Height}}px"></canvas>

 

onLoad: function () {
    this.setData({
      isShow: false
    })
    this.temframe = {};
    this.scanOk = false;
    this.scaning = false;
    this.cameraCtx = wx.createCameraContext();var _this = this
    wx.getSystemInfo({
      success: function (res) {
        _this.setData({
          pixelRatio: res.pixelRatio
        })
        if (res.platform == "devtools") {
          _this.setData({
            system: 'pc'
          }) //PC
        } else if (res.platform == "ios") {
          _this.setData({
            system: 'ios'
          }) //IOS
        } else if (res.platform == "android") {
          _this.setData({
            system: 'android'
          }) 
        }
      }
    })
    setTimeout(this._takePhoto, 500);
    this.donghua()
  },

_takePhoto: function () {
    if (this.scanOk || this.scaning) {
      return false;
    }
    // ios和android區分獲取圖片方式
    if (this.data.system == 'ios') {
      this.setData({
        isReuqest: false
      });
      this.listener = this.cameraCtx.onCameraFrame((frame) => {
        if (!this.data.isReuqest) {
          this.setData({
            Height: frame.height,
            Width: frame.width
          })
          var data = new Uint8Array(frame.data);
          var clamped = new Uint8ClampedArray(data);
          console.log(frame.width, frame.height, clamped)
          this.temframe = {};
          this.temframe.width = frame.width;
          this.temframe.height = frame.height;
          this.temframe.data = clamped;
          this.transformArrayBuffer();
        }
      });
      this.listener.start()
    } else {
      const _this = this
      this.cameraCtx.takePhoto({
        quality: 'high',
        success: (res) => {
          const context = wx.createCameraContext();
          this.scaning = true;
          wx.uploadFile({
            url: "http://192.168.0.128:9000/searchVideo",
            method: "post",
            filePath: res.tempImagePath,
            name: 'file',
            header: {
              "content-type": "multipart/form-data"
            },
            success: (res) => {
              this.scaning = false;
            }
          });
        },
        fail: () => {
          setTimeout(() => {
            this._takePhoto();
          }, 500);
        }
      });
    }
  },

   

transformArrayBuffer: function () {
    this.setData({
      isReuqest: true
    });
    var tf = this.temframe;
    var _this = this;
    wx.canvasPutImageData({
      canvasId: 'tempCanvas',
      x: 0,
      y: 0,
      width: tf.width,
      height: tf.height,
      data: tf.data,
      success: function (res) {
        console.log('繪制成功', res)
        _this.scaning = true;
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: tf.width,
          height: tf.height,
          canvasId: 'tempCanvas',
          fileType: 'jpg',
          destWidth: tf.width,
          destHeight: tf.height,
          // 精度修改
          quality: 1,
          success(res) {
            console.log(res.tempFilePath)
            wx.uploadFile({
              url: "http://192.168.0.128:9000/searchVideo",
              method: "post",
              filePath: res.tempFilePath,
              name: 'file',
              header: {
                "content-type": "multipart/form-data"
              },
              success: (res) => {
                
              },
              fail(res) {
                console.log('fail識別失敗')
              }
            })
          },
          fail(res) {
            setTimeout(() => {
              _this._takePhoto();
            }, 500);
          }
        });

      },
      fail: function (e) {
        console.log('res', e);
        setTimeout(() => {
          _this._takePhoto();
        }, 500);
      }
    });

  },
 
          
 
         

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM