目錄
前言
對(duì)上傳圖片進(jìn)行格式大小限制
壓縮上傳圖片
前言
上篇文章中研究了如何使用雙token機(jī)制,在此篇中就暴露了一些問(wèn)題:當(dāng)accesstoken過(guò)期后,直到拿到最終想要得到的數(shù)據(jù),期間需要經(jīng)歷三次請(qǐng)求——第一次請(qǐng)求,拿到accesstoken過(guò)期的消息——第二次攜帶refreshtoken發(fā)起請(qǐng)求,刷新了accesstoken——第三次攜帶新的accesstoken發(fā)起請(qǐng)求,拿到數(shù)據(jù)。在這個(gè)過(guò)程中會(huì)出現(xiàn)如下報(bào)錯(cuò):
?無(wú)法加載響應(yīng)數(shù)據(jù):No data found for resource with given identifier.
在測(cè)試了一系列的請(qǐng)求之后,發(fā)現(xiàn)問(wèn)題可能是該次請(qǐng)求攜帶的請(qǐng)求信息過(guò)大。因?yàn)槲覀兂霈F(xiàn)問(wèn)題的請(qǐng)求是前端上傳圖片到服務(wù)端獲取圖片鏈接。此時(shí),前端能想到的優(yōu)化方案是限制用戶上傳圖片的大小和格式,并且對(duì)上傳圖片進(jìn)行壓縮。
對(duì)上傳圖片進(jìn)行格式大小限制
// 上傳圖片大小及格式限制
export function restrictionPic(file) {
// 定義上傳圖片大小需小于2MB
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
ElMessage.error("上傳頭像圖片大小不能超過(guò) 2MB!");
return isLt2M;
}
// 定義上傳圖片格式,
const types = ["image/jpg", "image/png"];
const isType = types.includes(file.type);
if (!isType) {
ElMessage.error("上傳頭像圖片格式不正確!");
return isType;
}
}
壓縮上傳圖片
用到的api:
FileReader:FileReader
?對(duì)象允許 Web 應(yīng)用程序異步讀取存儲(chǔ)在用戶計(jì)算機(jī)上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容,使用?File?或?Blob?對(duì)象指定要讀取的文件或數(shù)據(jù)。
//讀取文件的方法
const fileToDataURL = (file) => {
return new Promise((resolve) => {
const reader = new FileReader()
reader.onloadend = (e) => resolve(e.target.result)
reader.readAsDataURL(file)
})
}
Image():Image()
函數(shù)將會(huì)創(chuàng)建一個(gè)新的HTMLImageElement實(shí)例,它的功能等價(jià)于??????document.createElement('img')。
//文件轉(zhuǎn)成圖片流
const dataURLToImage = (dataURL) => {
return new Promise((resolve) => {
const img = new Image()
img.onload = () => resolve(img)
img.src = dataURL
})
}
?????canvas:canvas是一個(gè)可以使用腳本 (通常為JavaScript) 來(lái)繪制圖形的?HTML元素。例如,它可以用于繪制圖表、制作圖片構(gòu)圖或者制作簡(jiǎn)單的動(dòng)畫。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-738943.html
// 壓縮圖片函數(shù),接收一個(gè)文件和壓縮質(zhì)量參數(shù)
export function compressPic(file, quality) {
var qualitys = 0.52
// 根據(jù)文件大小設(shè)置不同的默認(rèn)壓縮質(zhì)量
if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
qualitys = 0.85
}
if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
qualitys = 0.92
}
if (quality) qualitys = quality
// 如果上傳的是多個(gè)文件,遞歸處理每個(gè)文件
if (file[0]) {
return Promise.all(Array.from(file).map(e => this.compressPic(e, qualitys)))
} else {
return new Promise((resolve) => {
// 如果圖片大小小于300KB,直接返回原始圖片數(shù)據(jù)
if ((file.size / 1024).toFixed(2) < 300) {
resolve({
file: file
})
} else {
// 創(chuàng)建FileReader對(duì)象,異步讀取存儲(chǔ)在客戶端上的文件內(nèi)容
const reader = new FileReader()
// 讀取操作完成時(shí)觸發(fā)該事件,使用格式(必須將接收到的數(shù)據(jù)從onload發(fā)送到其他函數(shù)):reader.onload = e => {}
reader.onload = ({
target: {
result: src
}
}) => {
//創(chuàng)建img元素
const image = new Image()
// 圖片加載完成后異步執(zhí)行,當(dāng)image的src發(fā)生改變,瀏覽器就會(huì)跑去加載這個(gè)src里的資源,這個(gè)操作是異步的。
image.onload = async () => {
// 創(chuàng)建一個(gè)新的畫布元素和上下文,用于繪制壓縮后的圖片
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
// 計(jì)算目標(biāo)圖片的寬度和高度,以適應(yīng)最大寬度和高度的要求
var targetWidth = image.width
var targetHeight = image.height
var maxWidth = 800
var maxHeight = 800
// 縮放圖片尺寸以適應(yīng)最大寬度和高度
if (targetWidth > maxWidth || targetHeight > maxHeight) {
const scaleFactor = Math.min(maxWidth / targetWidth, maxHeight / targetHeight);
targetWidth *= scaleFactor;
targetHeight *= scaleFactor;
}
// 設(shè)置畫布的尺寸
canvas.width = targetWidth
canvas.height = targetHeight
// 清空畫布并在畫布上繪制壓縮后的圖片
context.clearRect(0, 0, targetWidth, targetHeight)
context.drawImage(image, 0, 0, targetWidth, targetHeight)
// 將壓縮后的圖片數(shù)據(jù)轉(zhuǎn)換為 data URI??梢允褂?type 參數(shù)其類型,默認(rèn)為 PNG 格式。qualitys越小,文件體積越小
const canvasURL = canvas.toDataURL(file.type, qualitys)
// 解碼 data URI,獲取圖片的二進(jìn)制數(shù)據(jù)。atob:是ascii to binary,用于將ascii碼解析成binary數(shù)據(jù),即Base64的解碼過(guò)程。
const buffer = atob(canvasURL.split(',')[1])
let length = buffer.length
//創(chuàng)建一個(gè) Uint8Array 類型的向量,用于存儲(chǔ)圖片的二進(jìn)制數(shù)據(jù)
const bufferArray = new Uint8Array(new ArrayBuffer(length))
while (length--) {
bufferArray[length] = buffer.charCodeAt(length)
}
// 創(chuàng)建一個(gè)壓縮后的文件對(duì)象
const miniFile = new File([bufferArray], file.name, {
type: file.type
})
// 解析壓縮后的文件對(duì)象
resolve({
file: miniFile,
origin: file,
beforeSrc: src,
afterSrc: canvasURL,
beforeKB: Number((file.size / 1024).toFixed(2)),
afterKB: Number((miniFile.size / 1024).toFixed(2))
})
}
// 設(shè)置圖片的 src,觸發(fā)圖片加載
image.src = src
}
// 讀取文件內(nèi)容,并在讀取完成后觸發(fā) onload 事件
reader.readAsDataURL(file)
}
})
}
}
參考文章:前端圖片最優(yōu)化壓縮方案文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-738943.html
到了這里,關(guān)于【vue3】前端上傳圖片的格式大小限制和壓縮的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!