問題:ios豎屏拍攝的圖片上傳后會旋轉(zhuǎn)90度弄贿。
解決方案:
1.使用upload的beforeUpload方法獲取到要上傳的文件,beforeUpload方法可以返回一個Promise孝冒,可以通過resolve file文件將處理之后的文件進行上傳侵贵。
2.使用exif-js庫獲取圖片的Orientation信息,如果Orientation為6笆制,那么這張圖片便是ios豎著拍的照片氮墨,需要處理,否則直接將原文件上傳即可栗弟。
3.如果圖片文件需要處理污筷,則將文件先轉(zhuǎn)換為Image對象嗎,這里用到FileReader乍赫,看代碼中如何使用瓣蛀。
4.然后將Image對象畫到canvas畫布上,并將畫布進行旋轉(zhuǎn)處理雷厂。
5.將旋轉(zhuǎn)之后的canvas使用toDataURL得到base64數(shù)據(jù)惋增。
6.將base64數(shù)據(jù)再轉(zhuǎn)化為File文件,上傳改鲫。
===================================================================================
1.首先安裝exif-js庫
npm install exif-js --save
2.下面是處理的時候需要使用的工具方法诈皿,文件名為fileUtil.js
import EXIF from 'exif-js'
export default {
getOrientation: (file) => {
return new Promise((resolve) => {
EXIF.getData(file, function () {
const orient = EXIF.getTag(this, 'Orientation')
resolve(orient)
})
})
},
dataURLtoFile: (dataurl, filename) => {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type: mime});
},
rotateImage: (image, width, height) => {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
ctx.save()
canvas.width = height
canvas.height = width
ctx.rotate(90 * Math.PI / 180)
ctx.drawImage(image, 0, -height)
ctx.restore()
return canvas.toDataURL("image/jpeg")
}
}
3.vue模板中使用
<template>
<el-upload
:action='actionURL'
:show-file-list="false"
:on-change="handleChange"
:before-upload="beforeAvatarUpload">
<span class="font-color">上傳照片</span>
<div class="upload-tips">注:只能上傳JPG/JPEG/PNG/GMP文件林束,且不超過2MB</div>
</el-upload>
</template>
<script>
import fileUtil from '../../assets/utils/fileUtil'
export default {
methods : {
beforeAvatarUpload(file) {
const type = file.type.split('/')[1]
const arr = ['jpg','jpeg','png','gmp']
let isJPG = true
arr.find(item => {
if (item == type) {
return isJPG = true
} else {
return isJPG = false
}
});
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上傳頭像圖片只能是 JPG/JPEG/PNG/GMP 格式!');
return isJPG;
} else if (!isLt2M) {
this.$message.error('上傳頭像圖片大小不能超過 2MB!');
return isLt2M;
} else {
return new Promise((resolve,reject) => {
fileUtil.getOrientation(file).then((orient) => {
if (orient && orient === 6) {
let reader = new FileReader()
let img = new Image()
reader.onload = (e) => {
img.src = e.target.result
img.onload = function () {
const data = fileUtil.rotateImage(img, img.width, img.height)
const newFile = fileUtil.dataURLtoFile(data, file.name)
resolve(newFile)
}
}
reader.readAsDataURL(file)
} else {
resolve(file)
}
})
})
}
}
}
}
</script>