【微信小程序】图片选择、转码、压缩、预览、上传,file与base64

0 前言

微信小程序中,上传图片,如标题,涉及图片选择、图片转码、图片压缩、图片预览、图片上传等


1 图片选择

需要使用微信提供的wx.chooseMedia

chooseImage() {
    
    
    var that = this
    wx.chooseMedia({
    
    
      count: 1,
      mediaType: ['image'],
      //图片尺寸原图和压缩图
      // sizeType: ['original', 'compressed'],
      //从相册选图和使用相机
      sourceType: ['album', 'camera'],
      camera: 'back',
      success(res) {
    
    
        // tempFilePath可以作为img标签的src属性显示图片
        const tempFilePaths = res.tempFiles[0].tempFilePath

        // 图片压缩
        var compressFilePath = that.get_img(tempFilePaths)

        that.setData({
    
    
          photo: compressFilePath
        })


      }
    })
  },

2 图片压缩

在wxml中放置一个canvas,使用canvas来实现图片的压缩

<!--wxml-->
<canvas   
  style="width: { 
        { 
        cwidth}}px;height: { 
        { 
        cheight}}px;" 
  canvas-id="myCanvas" 
  class="canvas-compress">
</canvas>
  

让canvas在画面外

/*wxss*/
.canvas-compress {
    
    
	position: absolute;
	top: -1000px;
	background-color: #bbbbbb;
}

进行图片的压缩

//js
get_img(url) {
    
    
    let that = this
    console.log("选择图片返回的路径", url)
    that.setData({
    
    
      uploadShow: false,
      loadingShow: true
    })
    wx.getImageInfo({
    
    
      src: url,
      success(res) {
    
    
        console.log(res)
        console.log("路径", res.path)
        console.log('获得原始图片大小', res.width, res.height)
        var originWidth, originHeight;
        originHeight = res.height;
        originWidth = res.width;
        // 最大尺寸限制   //压缩比例
        var maxWidth = originWidth >= originHeight ? 800 : 1600,
          maxHeight = originWidth >= originHeight ? 1600 : 800;
        // 目标尺寸
        var targetWidth = originWidth,
          targetHeight = originHeight;
        //等比例压缩,如果宽度大于高度,则宽度优先,否则高度优先
        if (originWidth > maxWidth || originHeight > maxHeight) {
    
    
          if (originWidth / originHeight > maxWidth / maxHeight) {
    
    
            // 要求宽度*(原生图片比例)=新图片尺寸
            targetWidth = maxWidth;
            targetHeight = Math.round(maxWidth * (originHeight / originWidth));
          } else {
    
    
            targetHeight = maxHeight;
            targetWidth = Math.round(maxHeight * (originWidth / originHeight));
          }
        }
        console.log("压缩后的图片大小", targetWidth, targetHeight)

        var ctx = wx.createCanvasContext('myCanvas');
        ctx.clearRect(0, 0, targetWidth, targetHeight);
        ctx.drawImage(res.path, 0, 0, targetWidth, targetHeight);
        ctx.draw();
        //更新canvas大小
        that.setData({
    
    
          cwidth: targetWidth,
          cheight: targetHeight
        });
        setTimeout(function () {
    
    
          wx.canvasToTempFilePath({
    
    
            canvasId: 'myCanvas',
            success: (res) => {
    
    
              console.log("压缩后的临时路径:", res.tempFilePath)
              // file格式转base64格式
              return that.imgBase64(res.tempFilePath)                    
            },
            fail: (err) => {
    
    
              console.error(err)
            }
          }, that)
        }, 400); //延迟400毫秒为了等canvas画上
      }
    })
  },

注意,此处调用的微信的canvas相关的方法,有些是落后的,但是要改造的话涉及的变动量比较大,所以就没有修改了


3 图片转码

将base64图片转为File文件类型

//js
imgBase64(img_url) {
    
    
    let res = wx.getFileSystemManager().readFileSync(img_url, 'base64')

    this.setData({
    
    
      photo: res
    })

    this.setData({
    
    
      loadingShow: false,
      successShow: true
    })
    return res
  },

将base64图片转为File文件类型(如果你需要的话)

// 将base64图片转为File文件类型
  base64ToFile(base64data, cb) {
    
    
    const fsm = wx.getFileSystemManager();
    const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
    const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
    if (!format) {
    
    
      return (new Error('ERROR_BASE64SRC_PARSE'));
    }
    const filePath = `${
      
      wx.env.USER_DATA_PATH}/${
      
      FILE_BASE_NAME}.${
      
      format}`;
    const buffer = wx.base64ToArrayBuffer(bodyData);
    fsm.writeFile({
    
    
      filePath,
      data: buffer,
      encoding: 'binary',
      success() {
    
    
        console.log('文件地址')
        console.log(filePath)
        cb(filePath);

        wx.uploadFile({
    
    
          filePath: filePath,
          name: FILE_BASE_NAME,
          url: 'url',
        })


      },
      fail() {
    
    
        return (new Error('ERROR_BASE64SRC_WRITE'));
      }
    })
  },


4 图片上传

直接base64字符串上传即可


5 其他补充

图片上传、加载、完成的相关xwml代码

<van-cell>
   <!-- 图片上传 -->
   <view class="photo-upload-wrap"  
     wx:if="{
     
     {uploadShow}}">    
      <van-icon 
          name="photograph" 
          class="photo-icon" 
          bind:tap="chooseImage"/>
   </view>

   <!-- 图片加载 -->
   <view class="photo-loading-wrap" 
     wx:if="{
     
     {loadingShow}}">
      <van-loading 
          type="spinner" 
          lass="shade" 
          color="#1989fa">
      </van-loading>
    </view>

    <!-- 图片完成 -->
    <view class="photo-success-wrap" 
      wx:if="{
     
     {successShow}}">
      <van-image
          width="620rpx"
          height="400rpx"
          fit="contain"
          src="data:image/png;base64,{
     
     {photo}}"
          bind:tap="onClickShow"
       />

       <van-icon 
          bind:tap="deletePhoto"
          class="photo-cancel-icon" 
          name="clear" />
    </view>
          
</van-cell>

<!-- 图片预览 -->
<van-overlay show="{
     
     { showPhotoOverlay }}" 
    bind:click="onClickHide">
    <view class="over-wrapper">
      <van-image
        fit="contain"
        src="data:image/png;base64,{
     
     {photo}}"
      />
    </view>
</van-overlay>


6 参考

微信小程序文件上传file
小程序baes64转普通格式
微信小程序 图片和base64相互转换
微信小程序(组件)----上传单张图片以及获取图片【wx.chooseMedia wx.uploadFile】

猜你喜欢

转载自blog.csdn.net/RogerQianpeng/article/details/128822169