【自用笔记】小程序 图片url和base64互转,延伸canvas压缩

领导让图片上传前做校验并进行压缩,给了一个vue的案例,是需要传入base64的,但是小程序是获取到图片地址。虽然最后用了别的方法进行图片压缩,但是既然搜到了转base64,那就记录一下,防止自己忘记。

比如我是在van-uploader的 before-read 中进行的,

以下是图片url转base64的方式:

.wxml中:

<van-uploader file-list="{{ imgList }}" max-count="5" upload-icon="scan" bind:after-read="afterRead" bind:delete="imgDelete" use-before-read="{{ true }}" bind:before-read="beforeRead" />


.js中:

beforeRead(event) {
    const { file, callback } = event.detail;
    this.getImageBase64_readFile(file.tempFilePath).then((res) => {
        callback(res); //res 为 base64流
    })
  },

//图片转base64
async getImageBase64_readFile(tempFilePath) {
    return  await new Promise(resolve => {
      //获取全局唯一的文件管理器 
      wx.getFileSystemManager().readFile({ //读取本地文件内容
        filePath: tempFilePath, // 文件路径
        encoding: 'base64', // 返回格式
        success: ({
          data
        }) => {
            // 这里必须要用'data:image/png;base64,'前缀,
            resolve('data:image/png;base64,' + data);
        }
      });
    });
  },

该代码块是base64转图片url↓:

// base64: 图片的base64文件流,最后用callback返出去

base64ImgtoFile(base64, callback) {
        const fsm = wx.getFileSystemManager();
        const FILE_BASE_NAME = new Date().getTime(); //自定义文件名(这里以时间戳为文件名)
        const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
        if (!format) {
            return (new Error('ERROR_BASE64SRC_PARSE'));
        }
        const imageUrl= `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.png`;
        const buffer = wx.base64ToArrayBuffer(bodyData);
        fsm.writeFile({
        imageUrl,
        data: buffer,
        encoding: 'binary',
        success() {
          callback(imageUrl); //返出图片url
        },
        fail() {
          return (new Error('ERROR_BASE64SRC_WRITE'));
        },
      });
    }

使用时:

base64ImgtoFile(base64, resCurrent => {
     let imageUrl = resCurrent   // resCurrent 是返回的图片地址

    // 这里可以进行自己的业务逻辑

})

在这里延伸一个小程序的图片压缩方法(因为我的业务用到的地方比较多,所以提出来放在了utils里面,随时使用):

// 压缩图片
const compressImg = (imageUrl) => {
    let _this = this;
        return new Promise((resolve, reject) => {
        //获取原图片信息 canvas压缩实现
        wx.getImageInfo({
        src: imageUrl,
        success: function (res) {
        // let canvasRatio = 1.1;
        var quality = 0.8;   //压缩系数0-1之间,越小越模糊(这里是用来压缩图片体积达到压缩效果的,和下面的修改图片大小为两种类型)
        let picWidth = res.width/2 //图片原始长宽
        let picHeight = res.height/2
        // while (picWidth > 600 || picHeight > 600) { // 保证宽高在600以内(通过宽高修改来修改图片大小,如果你要通过改变图片大小来控制图片体积的话,就可以放开这里的代码)
        //     picWidth = Math.trunc(res.width / canvasRatio)
        //     picHeight = Math.trunc(res.height / canvasRatio)
        //     canvasRatio = canvasRatio + 0.1;
        // }
        const query = wx.createSelectorQuery()
        query.select('#picCanvas').fields({
            node: true,
            size: true
        }).exec((res) => {
            try {
            const canvas = res[0].node
            const ctx = canvas.getContext('2d')
            // let dpr = wx.getSystemInfoSync().pixelRatio
            //这里是设置css样式的宽高。
            //属性宽高是css样式宽高的dpr倍,兼容不同机型,避免绘制的内容模糊。
            // _this.setData({
            //     canvasWidth: picWidth / dpr,
            //     canvasHeight: picHeight / dpr
            // })
            canvas.width = picWidth
            canvas.height = picHeight

            const img = canvas.createImage()
            img.src = imageUrl
            img.onload = () => {
                ctx.drawImage(img, 0, 0, picWidth, picHeight); //先画出图片
                var base64 = canvas.toDataURL("image/jpeg",quality ); //压缩语句(压缩体积,不改变宽高大小,quality可以动态改变,这里压缩后返回的是图片base64)
                
                 //这里可以用base64转图片url的方法,转化成图片url然后给resolve出去,也可以直接在resolve
                 resolve(base64)

                //延迟600ms,避免部分机型未绘制出图片内容就执行保存操作,导致最终的图片是块白色画板。
                // setTimeout(() => {
                // wx.canvasToTempFilePath({
                //     fileType: "jpg",
                //     canvas: canvas,
                //     destWidth: picWidth,
                //     destHeight: picHeight,
                //     success: function (res) {
                //     return resolve(res.tempFilePath) //返回压缩后的图片
                //     }
                // }, _this)
                // }, 600)
            }
            } catch (e) {
                //异常后的操作
            }
        })
        }
    })
    })
}

完毕,我是把压缩和转url放在了一个方法里面,如果你们也需要压缩后的图片Url,也可以像我一样,直接放在一起

注意:在使用canvas压缩图片的时候,wxml文件中一定要加上,以下代码,不然无法上传图片以后无法显示


<!-- 在压缩中需要用到,这里通过css控制在界面上不可见 -->
<canvas style="width:{{canvasWidth}}px;height:{{canvasHeight}}px;position:fixed;left:100%;" id="picCanvas" type="2d"></canvas>

参考地址:

base64图片转file的处理_base64转file_酸菜鱼很好吃哦1的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值