美文网首页
小程序拍照压缩上传全攻略

小程序拍照压缩上传全攻略

作者: 回调的幸福时光 | 来源:发表于2019-04-29 20:35 被阅读0次

前言

以小程序 【识花君】为例子,分析下在小程序中如何实现拍照压缩上传。

识花君

一、camera 和 cover-view、cover-image 组件

首先分析如何实现类似的设计:

  1. 引用 camera 组件,并且通过样式设置宽高为全屏。(拓展:可以在样式中设置宽高,或者定位来调整相机组件在页面中的大小以及位置。)
  2. 以 cover-view 为父容器设置定位,以嵌套的 cover-image 引用图片

说明:

  • 为什么不直接对 cover-image,而要使用 在外面嵌套一层 cover-view ?
    答:因为对 cover-image 设置定位样式后,在真机上无效。基础库 1.9.90 起最外层 cover-view 支持 position: fixed 。
  • cover-image 使用本地图片路径会存在问题
    答:图标路径,支持临时路径、网络地址(1.6.0起支持)、云文件ID(2.2.3起支持)。暂不支持base64格式。

二、从相册选取

点击相册图标时,触发事件调用 wx.chooseImage(Object object) 即可。

三、拍照

  • 图片 api :wx.chooseImage(Object object)
  • 相机 api :CameraContext.takePhoto(Object object)

四、压缩

现在的智能手机拍出的照片,很容易达到 5M 左右,上传时不仅占用带宽,且速度慢。

小程序提供了 3 种方式可压缩图片:

  1. 选择照片时指定图片的尺寸或者拍照时指定成像质量
    经过测试,如果对压缩要求比较高,这种方法是不行的,因为压缩效果不显著。
  2. wx.compressImage(Object object)
    局限性:仅对 jpg 有效。实际业务中包含 pngjpg 等多种格式。
  3. 通过 canvas 来曲线救国

原理:将一张大尺寸的图片通过 canvas 的提供的 drawImage() 方法绘制到小尺寸的画布上,再通过 canvasToTempFilePath 将画布内容生成图片,就完成了大尺寸到小尺寸的转换,完成了压缩。

步骤

  • wx.getSystemInfoSync() 获取设备像素比
  • wx.chooseImg() 或者 CameraContext.takePhoto 获取图片
  • wx.getImageInfo() 获取图片信息,并检测图片是否超过指定尺寸
  • drawImage() 绘制图片到画布
  • draw()
  • wx.canvasToTempFilePath() 将画布内容生成图片

说明:为什么需要设备像素比??

看下不处理设备像素比时,普通屏和二倍屏的对比,只关注 width 即可

pixelRatio = 1 pixelRatio = 2

在高倍屏上面,1px 对应的物理像素会比普通屏幕更多,这就导致通过 drawImage() 方法绘制时,虽然在 css
层面设置的宽高是一致的,比如(w: 300px),如果普通屏(pixelRatio: 1) 1px = 1 个物理像素,那么在二倍屏 (pixelRatio: 2) 上面 1 px = 4 个物理像素(宽是2, 高是2),所以实际上是将图片的宽绘制为 300 * 2 个物理像素,这时使用
canvasToTempFilePath() 生成图片的宽度是 600, 而不是期望的 300

设备像素比对 px 和物理像素的关系图

主要代码
模板 部分 (以下为 mpvue 中的语法)

<canvas class="canvas-hidden" :style="{width: cWidth + 'px', height: cHeight + 'px'}" canvas-id="CanvasId"/>

js 部分

pixelRatio 通过 wx.getSystemInfoSync() 获取。

// 将图片绘制到画布上
drawImage(file) {
   const ctx = wx.createCanvasContext('CanvasId');
   wx.getImageInfo({
      src: file,
      success: (res) => {
        if (res.width > 300 || res.height > 300) { // 判断图片是否超过300像素
          this.cWidth = 300 / this.pixelRatio;
          this.cHeight = 300 / this.pixelRatio / scale;
          // 画出压缩图片
          ctx.drawImage(file, 0, 0, this.cWidth, this.cHeight);
          ctx.draw();
          setTimeout(() => {
            this.canvasToImg();
          }, 3000);
        } else {
          this.upload(file);
        }
      }
    });
  },
// 将画布内容转成图片
canvasToImg() {
   wx.canvasToTempFilePath({
      canvasId: 'CanvasId',
      success: (res) => {
        // 上传图片
     this.upload(res.tempFilePath);
     }
   });
 },

五、兼容性

  1. 小米 android 9.0 版本无法渲染出 https 协议的图片。
    解决方案:前端强制转换成 http 。
  2. CanvasContext.draw(boolean reserve, function callback)
    callback 在某些机型上面无效。(当前基础库 2.6.5)
    解决方案:draw 之后强制 setTimeout 3s ,然后再去执行 wx.canvasToTempFilePath(Object object, Object this)

2019/5/13 更改
解决方案:通过wx.getSystemInfoSync()获取当前设备信息,其中的 platform 字段代表当前系统类型

  • ios
CanvasContext.draw(false, () => {
  wx.canvasToTempFilePath(Object object, Object this)
})
  • android
    draw 之后强制 setTimeout 3s ,然后再去执行 wx.canvasToTempFilePath(Object object, Object this)

3: 对 canvas 应用样式 visibility 无效
解决方案: 通过 left: -9999; 或者 tranlateX() 改变位置,移至不可见区域。

相关文章

  • 小程序拍照压缩上传全攻略

    前言 以小程序 【识花君】为例子,分析下在小程序中如何实现拍照压缩上传。 一、camera 和 cover-vie...

  • Vue上传图片压缩的问题

    上传图片太大,需要前台进行图片压缩上传图片大于100* 1024 的用canvas 来压缩来解决然后IOS拍照上传...

  • 小程序, 图片压缩上传

    问题: 图片上传后保存的图片跟原图不一致,还要待研究 //选择图片 chooseImg(e) { let t...

  • vue 图片压缩

    vue 图片压缩 上传图片大于100* 1024 的用canvas 来压缩来解决 然后IOS拍照上传会有图片旋转的...

  • vue 图片压缩

    vue 图片压缩 上传图片大于100* 1024 的用canvas来压缩来解决 然后IOS拍照上传会有图片旋转的问...

  • html base64图片压缩

    个人用于微信小程序中html的图片压缩展示与上传 export function dealImage(base64...

  • Lrz.js 压缩与 new File() 在 iOS上的兼容问

    问题 H5 拍照上传,前端使用 lrz.js 压缩图片后上传到阿里云 OSS,上传需要直接传 File。这里遇到两...

  • 2018-12-04 留影

    英语书写按老师要求拍照上传至打卡小程序。第一天,按时完成作业!✌

  • uniapp小程序图片前端压缩上传

    1,前言 这次项目中做了一个图片上传,要求是大于2MB的就压缩成2MB一下的再上传,我这边利用了uniapp的文件...

  • vue前端图片压缩,js图片压缩技术

    vue前端图片压缩,js图片压缩技术 公司项目有拍照上传图片,现在一般手机拍照都会有4M,5M样子,四五兆的图片上...

网友评论

      本文标题:小程序拍照压缩上传全攻略

      本文链接:https://www.haomeiwen.com/subject/cscunqtx.html