最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue 圖片壓縮并上傳至服務(wù)器功能

 更新時間:2020年01月15日 11:35:04   作者:solocoder  
這篇文章主要介紹了Vue 圖片壓縮并上傳至服務(wù)器功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

本文主要講解基于 Vue + Vant ,實現(xiàn)移動端圖片選擇,并用 Canvas 壓縮圖片,最后上傳至服務(wù)器。還會封裝一個工具類,方便直接調(diào)用。

一、工具類封裝

廢話不多說先上代碼,封裝一個 CompressImageUtils 工具類:

**
 * 圖片壓縮工具類
 * 最大高度和最大寬度都為 500,如果超出大小將等比例縮放。
 *
 * 注意可能出現(xiàn)壓縮后比原圖更大的情況,在調(diào)用的地方自己判斷大小并決定上傳壓縮前或壓縮后的圖到服務(wù)器。
 */
// 將base64轉(zhuǎn)換為blob
export function convertBase64UrlToBlob(urlData) {
 let arr = urlData.split(',')
 let mime = arr[0].match(/:(.*?);/)[1]
 let bstr = atob(arr[1])
 let n = bstr.length
 let u8arr = new Uint8Array(n)
 while (n--) {
  u8arr[n] = bstr.charCodeAt(n)
 }
 return new Blob([u8arr], {type: mime})
}

// 壓縮圖片
export function compressImage(path) {
 //最大高度
 const maxHeight = 500;
 //最大寬度
 const maxWidth = 500;
 return new Promise((resolve, reject) => {
  let img = new Image();
  img.src = path;
  img.onload = function () {
   const originHeight = img.height;
   const originWidth = img.width;
   let compressedWidth = img.height;
   let compressedHeight = img.width;
   if ((originWidth > maxWidth) && (originHeight > maxHeight)) {
    // 更寬更高,
    if ((originHeight / originWidth) > (maxHeight / maxWidth)) {
     // 更加嚴重的高窄型,確定最大高,壓縮寬度
     compressedHeight = maxHeight
     compressedWidth = maxHeight * (originWidth / originHeight)
    } else {
     //更加嚴重的矮寬型, 確定最大寬,壓縮高度
     compressedWidth = maxWidth
     compressedHeight = maxWidth * (originHeight / originWidth)
    }
   } else if (originWidth > maxWidth && originHeight <= maxHeight) {
    // 更寬,但比較矮,以maxWidth作為基準(zhǔn)
    compressedWidth = maxWidth
    compressedHeight = maxWidth * (originHeight / originWidth)
   } else if (originWidth <= maxWidth && originHeight > maxHeight) {
    // 比較窄,但很高,取maxHight為基準(zhǔn)
    compressedHeight = maxHeight
    compressedWidth = maxHeight * (originWidth / originHeight)
   } else {
    // 符合寬高限制,不做壓縮
   }
   // 生成canvas
   let canvas = document.createElement('canvas');
   let context = canvas.getContext('2d');
   canvas.height = compressedHeight;
   canvas.width = compressedWidth;
   context.clearRect(0, 0, compressedWidth, compressedHeight);
   context.drawImage(img, 0, 0, compressedWidth, compressedHeight);
   let base64 = canvas.toDataURL('image/*', 0.8);
   let blob = convertBase64UrlToBlob(base64);
   // 回調(diào)函數(shù)返回blob的值。也可根據(jù)自己的需求返回base64的值
   resolve(blob)
  }
 })
}

定義的最大寬度和最大高度均為 500,如果圖片的寬高至少有一個超出了 500,都會被 **等比例 **壓縮,不用擔(dān)心變形??梢愿鶕?jù)自己項目需要改變 maxWidth 和  maxHeight 。

這里直接把壓縮的最大高度和最大寬度寫死為 500 了,沒有在調(diào)用時傳。因為一個項目壓縮的邏輯和大小一般都一致的,沒必要在每次調(diào)用的時候傳。當(dāng)然如果想寫的靈活一點,可以在 compressImage 方法里再把 maxWidth 、 maxHeight 和壓縮質(zhì)量傳上。

compressImage 方法返回的是 blob 值,根據(jù)服務(wù)端接口需要可以改為返回 base64,只需將 resolve(blob) 改為 resolve(base64) 即可。

注意一點,對于有些寬高沒到 500,且分辨率很小的圖片,壓縮之后可能比之前還大。猜測可能是 canvas 生成的圖片分辨率要比原來高一些,所以最終的圖片比壓縮前更大。可以在調(diào)用的地方加個判斷,如果壓縮完的大小比原圖小,就上傳壓縮后的圖片;如果如果壓縮完的大小比原圖大,就上傳原圖。

二、如何使用

將 CompressImageUtils 引入到目標(biāo)文件,然后調(diào)用  compressImage 方法,即可在回調(diào)里獲得壓縮后的結(jié)果。注意  compressImage 方法返回的是 Promise。

省略其他無關(guān)代碼,只保留跟壓縮圖片和上傳相關(guān)的:

<template>
 <div>
  <van-uploader v-model="fileList" :after-read="afterRead" />
 </div>
</template>
<script>
 import {compressImage} from '../../utils/CompressImageUtils'
 export default {
  components: {},
  methods: {
   //讀取完圖片后
   afterRead(file) {
    console.log('afterRead------', file);
    this._compressAndUploadFile(file);
   },
   //壓縮圖片上傳
   _compressAndUploadFile(file) {
    compressImage(file.content).then(result => {
     console.log('壓縮后的結(jié)果', result); // result即為壓縮后的結(jié)果
     console.log('壓縮前大小', file.file.size);
     console.log('壓縮后大小', result.size);
     if (result.size > file.file.size){
      console.log('上傳原圖');
      //壓縮后比原來更大,則將原圖上傳
      this._uploadFile(file.file, file.file.name);
     } else {
      //壓縮后比原來小,上傳壓縮后的
      console.log('上傳壓縮圖');
      this._uploadFile(result, file.file.name)
     }
    })
   },
   //上傳圖片
   _uploadFile(file, filename) {
    let params = new FormData();
    params.append("file", file, filename);
    this.$api.uploadImage(params).then(res => {
     console.log('uploadImage', res);
   //上傳成功,寫自己的邏輯
    }).catch(err => {
     console.log('err', err);
    });
   }, 
  }
 }
</script>

在返回結(jié)果中加了層判斷,壓縮后比原來更大,則將原圖上傳;壓縮后比原來小,上傳壓縮后的。解決壓縮后比原圖更大的情況。

this.$api.uploadImage(params) 是調(diào)用封裝的 api 方法,如下:

//上傳圖片
 uploadImage(params){
  return axios.post(`${base}/api/v1/file`, params, {
   headers: {'content-type': 'multipart/form-data'}
  })
 },

三、使用效果

先上傳一個非常大的,尺寸為 6016 × 4016,16.8M 的大圖,看輸出日志,壓縮后大小僅為 260k 左右。此時判斷壓縮后比壓縮前小,上傳壓縮圖到服務(wù)器。

 

再看個尺寸 300 × 300,12k 的小圖,壓縮前大小是 11252,壓縮后大小是 93656,大了很多。此時判斷壓縮后比壓縮前更大,上傳的是原圖。

 

總結(jié):這個工具類對大圖的壓縮效果很明顯,不管多大的圖,壓縮之后基本不會超過 300k。但對某些小圖可能出現(xiàn)壓縮完反而更大的情況。在調(diào)用的地方加層壓縮后和壓縮前大小的比較判斷,會完美解決這個問題。

當(dāng)然也可以在工具類內(nèi)部判斷,但個人覺得跟業(yè)務(wù)邏輯相關(guān)的代碼還是不要放在公用的工具類比較好。

總結(jié)

以上所述是小編給大家介紹的Vue 圖片壓縮并上傳至服務(wù)器功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

相關(guān)文章

  • 如何用命令窗口的方式創(chuàng)建Vue項目

    如何用命令窗口的方式創(chuàng)建Vue項目

    這篇文章主要介紹了如何用命令窗口的方式創(chuàng)建Vue項目過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Vue.js中集成Socket.IO實現(xiàn)實時聊天功能

    Vue.js中集成Socket.IO實現(xiàn)實時聊天功能

    隨著 Web 技術(shù)的發(fā)展,實時通信成為現(xiàn)代 Web 應(yīng)用的重要組成部分,Socket.IO 是一個流行的庫,支持及時、雙向與基于事件的通信,適用于各種平臺和設(shè)備,本文將介紹如何在 Vue.js 項目中集成 Socket.IO,實現(xiàn)一個簡單的實時聊天應(yīng)用,需要的朋友可以參考下
    2024-12-12
  • vue實現(xiàn)動態(tài)數(shù)據(jù)綁定

    vue實現(xiàn)動態(tài)數(shù)據(jù)綁定

    本篇文章主要介紹了vue實現(xiàn)動態(tài)數(shù)據(jù)綁定,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • vue項目proxyTable配置小結(jié)

    vue項目proxyTable配置小結(jié)

    本文主要介紹了vue項目proxyTable配置小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue自定義正在加載動畫的例子

    vue自定義正在加載動畫的例子

    今天小編就為大家分享一篇vue自定義正在加載動畫的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue+element ui實現(xiàn)錨點定位

    vue+element ui實現(xiàn)錨點定位

    這篇文章主要為大家詳細介紹了vue+element ui實現(xiàn)錨點定位,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • vue中點擊下載圖片的實現(xiàn)方法

    vue中點擊下載圖片的實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于vue中點擊下載圖片的實現(xiàn)方法,在Vue的模板中,我們可以將下載屬性綁定至或元素上,用來實現(xiàn)點擊下載,需要的朋友可以參考下
    2023-08-08
  • Vue組件為什么data必須是一個函數(shù)

    Vue組件為什么data必須是一個函數(shù)

    這篇文章主要介紹了Vue組件為什么data必須是一個函數(shù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 詳解Vue中生命周期鉤子函數(shù)的使用示例

    詳解Vue中生命周期鉤子函數(shù)的使用示例

    這篇文章主要為大家詳細介紹了Vue中常見的生命周期鉤子函數(shù)的使用,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • vue3使用pdf.js來預(yù)覽文件的操作步驟(本地文件測試)

    vue3使用pdf.js來預(yù)覽文件的操作步驟(本地文件測試)

    這篇文章主要介紹了vue3使用pdf.js來預(yù)覽文件的操作步驟(本地文件測試),文中通過代碼示例和圖文結(jié)合的方式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05

最新評論

山阳县| 天长市| 门源| 凤山县| 静乐县| 丰台区| 皮山县| 太白县| 东源县| 乌兰察布市| 济源市| 阿拉善左旗| 扶绥县| 汤阴县| 和静县| 武川县| 濉溪县| 玉山县| 祁连县| 邵武市| 青阳县| 临沂市| 志丹县| 巴东县| 韶关市| 浦东新区| 赤壁市| 闽侯县| 吉安市| 甘谷县| 林芝县| 西乡县| 罗源县| 泰来县| 嘉峪关市| 陵川县| 罗平县| 西充县| 德安县| 定州市| 浮梁县|