vue3+Taro小程序实现图片上传+图片压缩功能(小白版)

实现效果:

可自定义中间内容及灰色区域背景图、背景色
![加粗样式](https://i-blog.csdnimg.cn/direct/bacb69273f474d6eba8dd1a022a6ffff.png

实现说明:

1、使用原生html+css实现上传区域(因为支付宝小程序不兼容我的项目nut-ui的上传组件),改成别的ui组件也是可以的,反正全程处理的fileList
2、 使用Taro原生方法chooseImage实现图片选择,
3、 依旧是使用Taro实现的图片压缩。

代码部分:

html + css部分:

<view :class="styles.card">
     <view :class="styles.license" @click="handleUploadClick" v-if="fileList?.length == 0">
          <img :class="styles.uploadIcon" src="../../assets/img/icon-upload.png" alt="">
          <text><slot>上传图片</slot></text>
      </view>
      <view :class="styles.previewContent" v-else>
          <img :class="styles.previewImg" :src="fileList[0]?.url" alt="">
          <IconFont :class="styles.delIcon" name="mask-close" color="rgba(0, 0, 0, 0.45)" @click="handleDeleteClick"></IconFont>
      </view>
  </view>
  
.card {
    background:  linear-gradient(to bottom, #E4ECFD 0%, #FFFFFF 40px, #FFFFFF 100%),rgba(255,255,255,0.5);
    border-radius: 18px;
    width: 100%;
    height: 414px;
    margin-bottom: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.license {
    width: 474px;
    height: 300px;
    background-color: rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-weight: 500;
    font-size: 24px;
    color: var(--color-font-light__5);
    line-height: 28px;
}
.uploadIcon {
    width: 52px;
    height: 52px;
    margin-bottom: 6px;
}
.previewContent {
    width: 474px;
    height: 300px;
    border: 1px dashed #CACBD0;
    border-radius: 18px;
    position: relative;
}
.delIcon {
    position: absolute;
    top: -20px;
    right: -20px;
    display: inline-block;
    z-index: 99;
}
.previewImg {
    width: 100%;
    height: 100%;
    border-radius: 18px;
}

js部分



// js部分
// 选择图片 & 图片识别
const handleUploadClick = () => {
    Taro.chooseImage({
        count: 1,
        sourceType: ['album', 'camera'],
        success: async (res) => {
            
            const tempFilePaths = res?.tempFilePaths;
            if (tempFilePaths.length > 0) {
                fileList.value = [{
                    url: tempFilePaths[0],
                    path: tempFilePaths[0]
                }] 
                try {
                    Taro.showLoading({
                        title: '图片处理中...',
                        mask: true, 
                    })
                    // 获取原始图片大小
                    const originalFileInfo = await Taro.getFileInfo({
                        filePath: tempFilePaths[0]
                    }) as { size: number }
                    console.log('原始文件大小:', (originalFileInfo.size / (1024 * 1024)).toFixed(2), 'MB')
                    // 压缩图片 -》我设置的压缩到6M内
                    compressImage(tempFilePaths[0], '', 6 * 1024 * 1024, 100, 5, (base64) =>{
                         // 请求图片上传接口
                        request({
                            url: 'XXXX',
                            body: {
                                "image": base64,
                            },
                            success: function (body) {
                                    title: '图片上传成功',
                                    icon: 'none' 
                                })
                                Taro.hideLoading()
                            },
                        }).finally(() => {
                            Taro.hideLoading()
                        })
                    })
                    
                } catch (err) {
                    Taro.showToast({
                        title: '图片处理失败,请手动输入',
                        icon: 'none'
                    })
                }
            }
        }
    })
}
// 删除icon-》清空图片列表 
const handleDeleteClick = () => {
    fileList.value = []; 
}

压缩图片逻辑封装:

 /**
   *小程序图片压缩到指定大小
   * @param oldFilePath 原图地址
   * @param filePath 压缩后的图片地址
   * @param limitSize 图片大小kb
   * @param quality 图片质量
   * @param step 图片质量每次降低多少
   * @param callback 回调
   */
export const compressImage = (
    oldFilePath: string,
    filePath: string,
    limitSize: number = 7 * 1024 * 1024,
    quality: number = 100,
    step: number = 5,
    callback: (base64: string) => void,
  ) => {
    Taro.showLoading({
        title: '图片处理中...',
        mask: true, 
    })
    const path = filePath === '' ? oldFilePath : filePath;
    Taro.getFileSystemManager().getFileInfo({
      filePath: path,
      success: async (res) => {
        console.log(`图片压缩size:${res.size / 1024 / 1024}m`, `quality:${quality}`, limitSize/ 1024 / 1024);
        if (res.size > limitSize) {
          Taro.compressImage({
            src: oldFilePath,
            quality: quality - step,
            success(result) {
              compressImage(
                oldFilePath,
                result.tempFilePath,
                limitSize,
                quality - step,
                step,
                callback,
              );
            },
          });
        } else {
          console.log(
            `压缩成功!size:${res.size / 1024 / 1024}m`,
            `quality:${quality}`,
            `path:${filePath}`,
          );
          Taro.getFileSystemManager().readFile({
            filePath: path,
            encoding: 'base64',
            success: (res) => {
                callback(res.data as string);
            },
            fail: (err) => {
                callback(err.errMsg);
            }
        });
        }
      },
      fail(res) {
        Taro.showToast({
            title: '图片解析失败,请重试',
            icon: 'none' 
        })
        Taro.hideLoading();
        callback(res.errMsg);
      },
    });
  };

end~
希望记录的问题能够帮助到你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值