前端圖片壓縮 - H5&Uni-App圖片壓縮

隨意的ID發表於2020-11-30

plus

plus簡介

plus是HTML5+(HTML5 plus)的一個介面

HTML5+是中國HTML5產業聯盟的擴充套件規範,基於HTML5擴充套件了大量呼叫裝置的能力,使得web語言可以想原生語言一樣強大。

使用plus的坑

注意!plus開頭的方法都是屬於HTML5+環境呼叫的方法。plus不能在瀏覽器環境下使用,它必須在手機APP上才能使用,因為它操控的是APP原生功能。

另外! 我們在使用HTML5+方法之前,必須監聽HTML5+環境是否已經載入完畢,載入完成後,才可以使用HTML5+的方法。

document.addEventListener('plusready',function () { 
  // 在這裡呼叫5+ API 
},false); 

這裡拿我的uni-app專案為例

takePhoto() {
	uni.chooseImage({
		count: 1, //預設9
		sizeType: ['compressed'], //可以指定是原圖還是壓縮圖,預設二者都有
		sourceType: ['camera'],
		success: res => {
			uni.previewImage({
				urls: res.tempFilePaths,
			});
			console.log('壓縮前圖片體積', res.tempFiles[0].size);
			let path = res.tempFilePaths[0];
			plus.zip.compressImage({
					src: path,
					dst: path,
					overwrite: true, //是否生成新圖片
					quality: 20, //1-100,1圖片最小,100圖片最大
					width: 'auto',
					height: 'auto'
				},
				(result) => {
					console.log("result: ", result);
					let imgPathUrl = result.target;
					let imgPathSize = result.size;
					console.log('壓縮後的體積', imgPathSize);
				}
			);
		}
	});
},

canvas

canvas的方案要複雜許多,個人是參考眾多大佬的方案才最終解決。
圖片純前端JS壓縮的實現

前端圖片壓縮上傳(壓縮篇):可能是最適合小白的前端圖片壓縮文章了!

自己淺薄的理解就是,先用FileReader把圖片轉成base64格式;
然後新建canvas畫布把圖片繪製到畫布,此處做了個將圖片等比縮小的操作,因為我這邊的後端推薦圖片寬為1024px,所以我也限制了這個數值,順便也能把圖片縮小;
再用canvas.toDataURL將這個畫布轉換成base64格式資訊影像資訊,而且這個方法接受的第二個引數正是圖片質量,所以可以將圖片質量調低到一定值以達到壓縮圖片的目的;
得到了這個壓縮後圖片的base64後,再將base64的資訊轉換成Blob類檔案物件,然後就將其上傳即可;

choosePhoto() {
	uni.chooseImage({
		count: 1, //預設9
		sizeType: ['compressed'], //可以指定是原圖還是壓縮圖,預設二者都有
		sourceType: ['album'], //從相簿選擇
		success: res => {
			this.$refs.popup.close();
			// uni.previewImage({
			// 	urls: res.tempFilePaths,
			// });

			console.log('壓縮前圖片體積', res.tempFiles[0].size);
			let reader = new FileReader();
			reader.readAsDataURL(res.tempFiles[0]);
			let _this = this;
			reader.onload = function() {
				let content = this.result; //圖片的src,base64格式
				let img = new Image();
				img.src = content;
				img.onload = function() { //圖片載入完畢
					_this.compressEvent(img, (dataURL) => {
						_this.uploadImg(dataURL);
					})
				}
			};
		}
	});
},
compressEvent(img, callback) {
	let canvasWidth = img.width //圖片原始寬高
	let canvasHeight = img.height;
	//圖片寬高比
	let base = canvasWidth / canvasHeight;
	//寬度最大設為1024
	if (canvasWidth > 1024) {
		canvasWidth = 1024;
		canvasHeight = Math.floor(canvasWidth / base);
	}
	//繪製影像到畫布
	let canvas = document.createElement('canvas');
	let ctx = canvas.getContext("2d");
	canvas.width = canvasWidth;
	canvas.height = canvasHeight;
	ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
	//將畫布轉為base64,mimeType型別為image/jpeg,圖片質量為0.3
	let dataURL = canvas.toDataURL("image/jpeg", 0.3);
	callback ? callback(dataURL) : null; //呼叫回撥函式
},
dataURItoBlob(dataurl) { //dataurl是base64格式
	var arr = dataurl.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	return new Blob([u8arr], {
		type: mime
	});
},
uploadImg(dataURL) {
	//將base64轉為blob物件
	let blob = this.dataURItoBlob(dataURL);
	console.log("blob size: ", blob.size);
	uni.uploadFile({
		//此處填檔案上傳的介面url
		url: 'http://example.com',
		filePath: dataURL,
		name: 'file',
		file: blob,
		success: (uploadFileRes) => {
			console.log(uploadFileRes);
		}
	});
},

相關文章