關(guān)于vue中圖片壓縮上傳以及旋轉(zhuǎn)圖片

大體的思路是

利用FileReader,讀取blob對象,或者是file對象,將圖片轉(zhuǎn)化為data uri的形式。

使用canvas,在頁面上新建一個畫布,利用canvas提供的API,將圖片畫入這個畫布當(dāng)中。

利用canvas.toDataURL(),進(jìn)行圖片的壓縮,得到圖片的data uri的值

上傳文件。

我將以上步驟封裝成一個方法:

compress(file, quality, callback) {

? ? ? ? ? if (!window.FileReader || !window.Blob) {

? ? ? ? ? ? ? return errorHandler('您的瀏覽器不支持圖片壓縮')();

? ? ? ? ? }

? ? ? ? ? var reader = new FileReader();

? ? ? ? ? var mimeType = file.type || 'image/jpeg';

? ? ? ? ? reader.onload = createImage;

? ? ? ? ? reader.onerror = errorHandler('圖片讀取失敗!');

? ? ? ? ? reader.readAsDataURL(file);

? ? ? ? ? function createImage() {

? ? ? ? ? ? ? var dataURL = this.result;

? ? ? ? ? ? ? var image = new Image();

? ? ? ? ? ? ? image.onload = compressImage;

? ? ? ? ? ? ? image.onerror = errorHandler('圖片加載失敗');

? ? ? ? ? ? ? image.src = dataURL;

? ? ? ? ? }

? ? ? ? ? function compressImage() {

? ? ? ? ? ? ? var canvas = document.createElement('canvas');

? ? ? ? ? ? ? var ctx;

? ? ? ? ? ? ? var dataURI;

? ? ? ? ? ? ? var result;

? ? ? ? ? ? ? canvas.width = this.naturalWidth;

? ? ? ? ? ? ? canvas.height = this.naturalHeight;

? ? ? ? ? ? ? ctx = canvas.getContext('2d');

? ? ? ? ? ? ? ctx.drawImage(this, 0, 0);

? ? ? ? ? ? ? dataURI = canvas.toDataURL(mimeType, quality);

? ? ? ? ? ? ? result = dataURIToBlob(dataURI);

? ? ? ? ? ? ? callback(null, result);

? ? ? ? ? }

? ? ? ? ? function dataURIToBlob(dataURI) {

? ? ? ? ? ? ? var type = dataURI.match(/data:([^;]+)/)[1];

? ? ? ? ? ? ? var base64 = dataURI.replace(/^[^,]+,/, '');

? ? ? ? ? ? ? var byteString = atob(base64);

? ? ? ? ? ? ? var ia = new Uint8Array(byteString.length);

? ? ? ? ? ? ? for (var i = 0; i < byteString.length; i++) {

? ? ? ? ? ? ? ? ? ia[i] = byteString.charCodeAt(i);

? ? ? ? ? ? ? }

? ? ? ? ? ? ? // var blob = getBlob([ia]);

? ? ? ? ? ? ? return new Blob([ia], {type: type});

? ? ? ? ? }

? ? ? ? ? function errorHandler(message) {

? ? ? ? ? ? ? return function () {

? ? ? ? ? ? ? ? ? var error = new Error('Compression Error:', message);

? ? ? ? ? ? ? ? ? callback(error, null);

? ? ? ? ? ? ? };

? ? ? ? ? }

? ? ? },

然后在在onchange事件中調(diào)用上面方法:

onUploadIdcard(e) {

? ? ? ? ? var _this = this

? ? ? ? ? let file = e.target.files[0];

? ? ? ? ? var formData = new FormData();

? ? ? ? ? _this.compress(file, 0.5, function (err, data) {

? ? ? ? ? ? ? if (err) {

? ? ? ? ? ? ? ? ? console.log(err);

? ? ? ? ? ? ? ? ? return;

? ? ? ? ? ? ? }

? ? ? ? ? ? ? formData.append('file', data,'image.png');

? ? ? ? ? ? ? $.ajax({

? ? ? ? ? ? ? ? url: '你的接口',//這里是后臺接口需要換掉

? ? ? ? ? ? ? ? type: 'POST',

? ? ? ? ? ? ? ? dataType: 'json',

? ? ? ? ? ? ? ? cache: false,

? ? ? ? ? ? ? ? data: formData,

? ? ? ? ? ? ? ? processData: false,

? ? ? ? ? ? ? ? contentType: false,

? ? ? ? ? ? ? ? success: (res) => {

? ? ? ? ? ? ? ? ? if (res.code === 200) {

? ? ? ? ? ? ? ? ? }else if(res.code==40107){

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? },error: function(err) {

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? });

? ? ? ? ? });

? ? ? },

搞定

我這里設(shè)置的用 canvas重繪時 圖像寬高不變,只改變質(zhì)量,想改變寬高的可以修改canvas.width和canvas.height,改變質(zhì)量就修改compress方法中的第二個參數(shù)0.5。

另外注意部分安卓機(jī)型不支持blob類型,會導(dǎo)致選擇圖片后無法上傳,自動跳頁;這里不能直接用new Blob();這時在dataURIToBlob方法中要改成兼容性寫法:

function dataURIToBlob(dataURI) {

? ? ? ? ? ? ? var type = dataURI.match(/data:([^;]+)/)[1];

? ? ? ? ? ? ? var base64 = dataURI.replace(/^[^,]+,/, '');

? ? ? ? ? ? ? var byteString = atob(base64);

? ? ? ? ? ? ? var ia = new Uint8Array(byteString.length);

? ? ? ? ? ? ? for (var i = 0; i < byteString.length; i++) {

? ? ? ? ? ? ? ? ? ia[i] = byteString.charCodeAt(i);

? ? ? ? ? ? ? }

? ? ? ? ? ? ? var blob;

? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? blob = new Blob([ia], {type: 'image/jpg'});

? ? ? ? ? ? ? } catch (e) {

? ? ? ? ? ? ? ? window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;

? ? ? ? ? ? ? ? if(e.name === 'TypeError' && window.BlobBuilder){

? ? ? ? ? ? ? ? ? var blobBuilder = new BlobBuilder();

? ? ? ? ? ? ? ? ? blobBuilder.append(ia);

? ? ? ? ? ? ? ? ? blob = blobBuilder.getBlob('image/jpg');

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? }

? ? ? ? ? ? ? return blob

? ? ? ? ? }

OK

還有就是iOS和部分Android機(jī)型拍照后圖片自動旋轉(zhuǎn),原因在另一篇文章中說明了,這里要用到exif.js,

npm install exif-js --save

然后在當(dāng)前頁面

import Exif from 'exif-js'

在封裝的compress方法開頭用exif獲取方向

let Orientation;

//去獲取拍照時的信息,解決拍出來的照片旋轉(zhuǎn)問題?

Exif.getData(file, function(){?

? ? ?Orientation = Exif.getTag(this, 'Orientation');?

});

修改compressImage() 方法,

function compressImage() {

? ? ? ? ? ? ? var canvas = document.createElement('canvas');

? ? ? ? ? ? ? var ctx;

? ? ? ? ? ? ? var dataURI;

? ? ? ? ? ? ? var result;

? ? ? ? ? ? ? var degree = 0,drawWidth,drawHeight,width,height;

? ? ? ? ? ? ? drawWidth = this.naturalWidth;

? ? ? ? ? ? ? drawHeight = this.naturalHeight;

? ? ? ? ? ? ? canvas.width=width=drawWidth;

? ? ? ? ? ? ? canvas.height=height=drawHeight;

? ? ? ? ? ? ? ctx = canvas.getContext('2d');

? ? ? ? ? ? ? //判斷圖片方向,重置canvas大小,確定旋轉(zhuǎn)角度,iphone默認(rèn)的是home鍵在右方的橫屏拍攝方式

? ? ? ? ? ? ? if(Orientation != "" && Orientation != 1){

? ? ? ? ? ? ? ? ? switch(Orientation){

? ? ? ? ? ? ? ? ? ? ? ? //iphone橫屏拍攝,此時home鍵在左側(cè)

? ? ? ? ? ? ? ? ? ? ? case 3:

? ? ? ? ? ? ? ? ? ? ? ? ? ? degree=180;

? ? ? ? ? ? ? ? ? ? ? ? ? ? drawWidth=-width;

? ? ? ? ? ? ? ? ? ? ? ? ? ? drawHeight=-height;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? //iphone豎屏拍攝,此時home鍵在下方(正常拿手機(jī)的方向)

? ? ? ? ? ? ? ? ? ? ? ? case 6:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canvas.width=height;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canvas.height=width;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? degree=90;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drawWidth=width;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drawHeight=-height;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? ? ? //iphone豎屏拍攝,此時home鍵在上方

? ? ? ? ? ? ? ? ? ? ? ? case 8:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canvas.width=height;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canvas.height=width;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? degree=270;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drawWidth=-width;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drawHeight=height;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? }

? ? ? ? ? ? ? //使用canvas旋轉(zhuǎn)校正

? ? ? ? ? ? ? ctx.rotate(degree*Math.PI/180);

? ? ? ? ? ? ? ctx.drawImage(this, 0, 0, drawWidth, drawHeight);

? ? ? ? ? ? ? dataURI = canvas.toDataURL(mimeType, quality);

? ? ? ? ? ? ? result = dataURIToBlob(dataURI);

? ? ? ? ? ? ? callback(null, result);

? ? ? ? ? }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 業(yè)務(wù)有個需求,要做圖片預(yù)覽上傳,過去都是客戶端上傳給后端,后端返回url前端進(jìn)行預(yù)覽,現(xiàn)在其實可以不依賴后端做預(yù)覽...
    諾花生閱讀 4,480評論 1 3
  • 一、作者介紹 納西姆·尼古拉斯·塔勒布( Nassim Nicholas Taleb)暢銷書《黑天鵝》、《隨機(jī)漫步...
    3分鐘即興演講閱讀 779評論 1 0
  • 初到杭州的那些天,一肚子的委屈。這里的天空似乎不太歡迎我這個西北土著,像被長工白吃了飯的財主的臉,陰沉沉的拉著。心...
    愛佛僧閱讀 545評論 7 10
  • 每次總是以為感冒很快就要好了,結(jié)果情況更糟糕。昨晚上已經(jīng)沒有什么感冒的跡象的,沒有想到今早上起床后,嚴(yán)重咳嗽,胸口...
    羅xuexue閱讀 358評論 0 0

友情鏈接更多精彩內(nèi)容