1. 程式人生 > 其它 >vue3.2中使用Canvas實現在畫布上對本地圖片進行壓縮移動,將最終結果畫布上傳

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

      }
    })

  })
}