vue3.2中使用Canvas实现在画布上对本地图片进行压缩移动,将最终结果画布上传

中文文档地址:文档很多功能都有介绍使用,我主要用到的是getImageData()这个方法,在画布上对对图片进行处理;所有对图片和画布的函数使用方法都可以在文档中找到详细的使用方法和例子,

https://www.canvasapi.cn/

1、使用ref定义引入canvas标签对象;后面可以直接调用myCanvasRef.value.方法(参数,参数)

```
<template>
....
    <canvas  ref="myCanvasRef"   :width="489" :height="34" style="width: 489px;height: 34px;background-color: pink">
    </canvas>
....
</template>
```
//1、找到画布的对象
const  myCanvasRef= ref(null)

1、选择本地的图片;我这里是选择之后直接调用对用的Canvas图片处理方法,直接在页面上展示对应的结果:注意,要在图片已经加载完成之后,再对内存中的图片进行处理,不然异步效果会出现,还没加载完成,处理方法就已经执行完毕了,.onload

              <label class="btn" for="uploads">选择Logo文件</label>
              <input
                  type="file"
                  id="uploads"
                  ref="uploadsFileInstall"
                  style="position: absolute; clip: rect(0 0 0 0)"
                  accept="image/png, image/jpeg, image/gif, image/jpg"
                  @change="selectImg($event)"
              />

setup 中方法;主要把文件读入进内存

const option = reactive({
  img: '',             //裁剪图片的地址
})
// 选择图片
const selectImg = function(e){
  

  if(!e.target.files.length) return
  if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
    alert('图片类型要求:jpeg、jpg、png')
    return false
  }
  let file = e.target.files[0]
  let strArr = file.name.split('.')
  chooseImageType.value = strArr[strArr.length-1]
  let reader = new FileReader()
  reader.onload = (e) => {


    let data
    if (typeof e.target.result === 'object') {
      data = window.URL.createObjectURL(new Blob([e.target.result]))
    } else {
      data = e.target.result
    }
    option.img = data


    //调用Canvas 载入图片
    testCanvas()
  }
  //转化为base64
  reader.readAsDataURL(file)

}

2、Canvas的调用;对图片进行压缩,画布上移动,保存画布

const testCanvas = () => {

  //清空内存中的图片对象
  const ctx = myCanvasRef.value.getContext("2d");
  //如果不是第一次点击:有值:清空Canvas内存中的图片对象:同时把上传的内容置为空
  if( result_base64_src.value){
    ctx.clearRect(0, 0, 489, 34);
    result_base64_src.value=""
  }
  //绘制图像 图片对象,x位置,y位置
  let img=new Image()
  img.src=option.img
  //图片载入数据后再进行绘制
  img.onload=()=>{
    // 第一种情况:当图片的高度height>34px
      //获取图片的高度和宽度:
      //将图片的按照原有的比例进行缩放 为height:34
      let original_img_width=img.width
      let original_img_height=img.height
      //得到缩放后的结果
      let new_img_width=34*original_img_width/original_img_height
      let new_img_height=34
      //计算图片距离距离左边的起点位置:画布为:489 34:
      let x_image=(489-new_img_width)/2
      //画图:
      // 1.2985074626865583 0 486.4029850746269 34     0 0 489 34
      // console.log(x_image,0,new_img_width,34,0,0,489,34)
      ctx.drawImage( img,x_image,0,new_img_width,34)
      result_base64_src.value = myCanvasRef.value.toDataURL();

  }
}

得到Base64的地址结果

3、转换为blob流,使用axios进行上传;myCanvasRef.value.toBlob方法执行成功后的回调方法,支持一个参数,表示当前转换的Blob对象,使用这个二进制流data进行上传

const testCanvasUploadImg=()=>{
  myCanvasRef.value.toBlob(async (data)=> {
    let formData = new FormData();
    formData.append('logoFile',data,`DX.${chooseImageType.value}`)
    formData.append('hospId',hosp.info.hospId)
    //调用axios上传   将请求地址改为自己图片上传的地址
    uploadLoading.value = true
    uploadLogo(formData).then(res =>{
      if (res.code === 200) {
        ElMessage({
          message: "logo上传成功",
          type: 'success',
          showClose: true,
          duration: 1000,
        })
        getHospInfo()
        uploadLoading.value = false
      }else {
        ElMessage({
          message: +res.msg,
          type: 'error',
          showClose: true,
          duration: 1000,
        })
        uploadLoading.value = false

      }
    })

  })
}
posted @ 2022-03-08 17:58  成强  阅读(1337)  评论(0编辑  收藏  举报