小程序van-uploader图片上传前压缩

van-uploader图片上传前压缩至指定大小

<template>
  <van-field name="uploader" :label="equipFileTitle" class="uploader">
    <div slot="input">
      <van-uploader
        :file-list="fileList"
        :deletable="true"
        max-count="2"
        @afterRead="afterRead"
        @delete="deleteImg"
      />
    </div>
  </van-field>
</template>

在bind:after-read事件中进行图片压缩,当然在bind:before-read事件中操作也是可以的,我使用的是mpvue架构对应的事件为@afterRead @beforeRead,需要注意的是在使用@beforeRead时要开启useBeforeRead,bind:before-read对应的为use-before-read。

新建一个js文件用来压缩图片imageCompress.js

var offCanvas, ctx;
const fs = wx.getFileSystemManager()
const dirPath = `${wx.env.USER_DATA_PATH}/compress-img`

var filePath = null
var imgWidth = 0
var imgHeight = 0
var imgSize = 0

const self = {
    int() {
        if (!offCanvas) {
            offCanvas = wx.createOffscreenCanvas({
                type: '2d',
                width: 300,
                height: 300
            })
        }
        if (!ctx) ctx = offCanvas.getContext('2d')
    },

    async set(src, maxsize = 1024) {
        self.int();
        filePath = src
        let i = 0
        let istrue = false
        do {
            i++
            await new Promise((resolve) => {
                fs.getFileInfo({
                    filePath: filePath,
                    async success(res) {
                        // console.info(res)
                        imgSize = res.size
                        if (res.size > maxsize * 1024) {
                            await self.compress(filePath)
                        } else {
                            await self.compress(filePath, true)
                            istrue = true
                        }
                        resolve()
                    }
                })
            });
        } while (!istrue && i < 50);

        return {
            filePath: filePath,
            width: imgWidth,
            height: imgHeight,
            size: imgSize,
        };
    },

    async compress(src, onlyGetWH = false) {
        let imageItem = offCanvas.createImage() // 图片对象

        imageItem.src = src // 设置图片src
        imageItem.onerror = err => {
            console.log('err', err)
            wx.showModal({
                title: '提示',
                content: '照片加载失败',
                confirmText: '关闭',
                showCancel: false,
            })
        }

        // 如果图片已经存在于浏览器缓存
        if (imageItem.width > 0) {

            if (onlyGetWH) {
                imgWidth = imageItem.width;
                imgHeight = imageItem.height;
            } else {
                self._imgLoaded(imageItem)
            }

        } else {
            await new Promise((resolve) => {
                imageItem.onload = () => {

                    if (onlyGetWH) {
                        imgWidth = imageItem.width;
                        imgHeight = imageItem.height;
                    } else {
                        self._imgLoaded(imageItem)
                    }

                    resolve()
                }
            });
        }
    },

    async _imgLoaded(img) {
        let yinzi = 0.95
        if (img.width > 2048 || img.height > 2048) yinzi = img.height > img.width ? (2048 / img.height) : (2048 / img.width)

        imgWidth = img.width * yinzi;
        imgHeight = img.height * yinzi;

        offCanvas.width = imgWidth
        offCanvas.height = imgHeight
        ctx.clearRect(0, 0, imgWidth, imgHeight);
        ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, offCanvas.width, offCanvas.height)

        fs.mkdir({
            dirPath: dirPath,
            recursive: false,
            // fail(res) {
            //   console.error(res)
            // }
        })

        const tempPath = `${dirPath}/${new Date().getTime()}.jpg`
        const dataURL = offCanvas.toDataURL('image/jpeg', 0.92).replace('data:image/jpeg;base64,', '')
        try {
            fs.writeFileSync(tempPath, dataURL, 'base64')
            filePath = tempPath
        } catch (e) {
            console.error(e)
        }
    },
    clearTempImg() {
        try {
            // 适当的时候删除临时文件
            wx.getFileSystemManager().rmdir({
                dirPath: dirPath,
                recursive: true,
                // fail(res) {
                //   console.error(res)
                // }
            })
        } catch (error) {
            console.info(error)
        }
    },
}

export default {
    set: self.set,
    clearTempImg: self.clearTempImg
}

在文件中引入

import mpImageCompress from "../fileUpload/common/imageCompress";

方法中使用

afterRead(file) {
console.log("压缩前图片大小", file.mp.detail.file.size / 1024 + "kb");
      const tempFiles = [
        {
          fileType: file.mp.detail.file.type,
          size: file.mp.detail.file.size,
          tempFilePath: file.mp.detail.file.url,
        },
      ];
      const that = this;
      const imgRes = mpImageCompress.set(tempFiles[0].tempFilePath, 500); // 500为要压缩的大小 压缩后为500kb左右 有些许误差
      console.log(imgRes);
      imgRes.then(
        (value) => {
          console.log(value); //OK
          console.log("压缩后图片大小", value.size / 1024 + "kb");
        },
        (reason) => {
          console.warn(reason);
        }
      );
    },

在这里插入图片描述
需要注意的是 压缩完返回的为图片路径地址
在这里插入图片描述

同时我用的mpvue框架 afterRead(file) 文件流信息有所不同 为file.mp.detail 一般情况下为file.detail 具体情况还请自行测试。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值