日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue 图片压缩并上传至服务器

發布時間:2023/12/14 vue 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue 图片压缩并上传至服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

一、工具類封裝

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

/*** 圖片壓縮工具類* 最大高度和最大寬度都為 500,如果超出大小將等比例縮放。** 注意可能出現壓縮后比原圖更大的情況,在調用的地方自己判斷大小并決定上傳壓縮前或壓縮后的圖到服務器。*/// 將base64轉換為blob export function convertBase64UrlToBlob(urlData) {let arr = urlData.split(',')let mime = arr[0].match(/:(.*?);/)[1]let bstr = atob(arr[1])let n = bstr.lengthlet 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 = maxHeightcompressedWidth = maxHeight * (originWidth / originHeight)} else {//更加嚴重的矮寬型, 確定最大寬,壓縮高度compressedWidth = maxWidthcompressedHeight = maxWidth * (originHeight / originWidth)}} else if (originWidth > maxWidth && originHeight <= maxHeight) {// 更寬,但比較矮,以maxWidth作為基準compressedWidth = maxWidthcompressedHeight = maxWidth * (originHeight / originWidth)} else if (originWidth <= maxWidth && originHeight > maxHeight) {// 比較窄,但很高,取maxHight為基準compressedHeight = maxHeightcompressedWidth = maxHeight * (originWidth / originHeight)} else {// 符合寬高限制,不做壓縮}// 生成canvaslet 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);// 回調函數返回blob的值。也可根據自己的需求返回base64的值resolve(blob)}}) }

定義的最大寬度和最大高度均為 500,如果圖片的寬高至少有一個超出了 500,都會被?**等比例?**壓縮,不用擔心變形。可以根據自己項目需要改變maxWidth?和?maxHeight?。

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

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

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

二、如何使用

將 CompressImageUtils?引入到目標文件,然后調用?compressImage?方法,即可在回調里獲得壓縮后的結果。注意?compressImage 方法返回的是 Promise。
省略其他無關代碼,只保留跟壓縮圖片和上傳相關的:

<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('壓縮后的結果', result); // result即為壓縮后的結果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>

在返回結果中加了層判斷,壓縮后比原來更大,則將原圖上傳;壓縮后比原來小,上傳壓縮后的。解決壓縮后比原圖更大的情況。
this.$api.uploadImage(params)?是調用封裝的 api 方法,如下:

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

三、使用效果

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

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

總結:這個工具類對大圖的壓縮效果很明顯,不管多大的圖,壓縮之后基本不會超過 300k。但對某些小圖可能出現壓縮完反而更大的情況。在調用的地方加層壓縮后和壓縮前大小的比較判斷,會完美解決這個問題。
當然也可以在工具類內部判斷,但個人覺得跟業務邏輯相關的代碼還是不要放在公用的工具類比較好。

總結

以上是生活随笔為你收集整理的Vue 图片压缩并上传至服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。