又更新了下材蹬,難搞,蘋果手機(jī)有些版本會(huì)旋轉(zhuǎn)有些版本不會(huì)吝镣,所以還要區(qū)別下堤器,目前只知道最新版的不會(huì)旋轉(zhuǎn),就單獨(dú)處理下末贾,目前沒有打包成蘋果app闸溃,所以在蘋果包上有沒有問題還不確定
卡了將近兩天才解決完,真是頭大未舟,根據(jù)網(wǎng)上的方法也是卡了好久圈暗,所以又特地整理了下
h5是通過拿到旋轉(zhuǎn)的值掂为,重新用canvas畫圖裕膀,所以在頁面需要加入canvas 元素,其中用v-if的原因勇哗,是重復(fù)上傳的話之前畫的不會(huì)清空掉昼扛,所以用v-if來清空。還有canvas要設(shè)置height: 100vh;width: 100vw; 才可以把上傳的圖片完整的畫出來。然后在外一層加上overflow: hidden;就行抄谐,下面的代碼片段是自己封裝的組件中的片段渺鹦,因?yàn)橛行┬枰獌?yōu)化的就不貼出來完整的代碼
<view class="h-upload-img-content">
<view class="h-upload-img-content-input" @click="onChangeUpload" v-if="!imgSrc">
<text class="cross"></text>
<!--canvas 用來解決圖片旋轉(zhuǎn)的-->
<canvas canvas-id="uploadCanvas" class="upload-canvas" v-if="isCanvas"></canvas>
</view>
<view class="h-upload-img-content-img" v-if="imgSrc">
<view class="h-upload-img-content-icon" @click.stop="onDelImg()"><h-icon path="icon/close" width="40" height="40" /></view>
<h-lazy-img :src="imgSrc" mode="widthFix" preview></h-lazy-img>
</view>
</view>
import compressImage from '@/libs/imageUtil.js';
...
// 選擇上傳文件
onChangeUpload() {
if (this.limt && this.limt <= this.imgList) return uni.showToast({ title: `只能上傳${this.limt}個(gè)文件`, icon: 'none' });
uni.chooseImage({
count: this.limt || 1,
success: res => {
if (res && res.tempFiles.length && res.tempFiles[0].size > 5 * 1024 * 1024) {
return uni.showToast({ title: '上傳圖片大小不能超過5M!', icon: 'none' });
}
this.compressImageHandler(res.tempFiles[0]);
}
});
},
// 解決有些圖片會(huì)旋轉(zhuǎn)的問題
async compressImageHandler(file) {
uni.showLoading({title: '上傳中...'});
this.isCanvas = true; //用來清空畫布
const tempPath = await compressImage(file.path);
this.uploadFile({ file: tempPath });
this.isCanvas = false;
},
// 上傳文件
async uploadFile(file) {
try {
let res = await this.$api.uploadFile(file);
uni.showToast({ title: res.msg, icon: 'none' });
this.imgSrc = res.url;
this.$emit('change', this.imgSrc);
} catch (e) {
uni.showToast({ title: e.msg, icon: 'none' });
}
},
注意:h5因?yàn)橐玫叫D(zhuǎn)的值,所以引用exif.js文件蛹含,這個(gè)直接在github就可以搜到毅厚,但因?yàn)閕mg中complete這個(gè)值我拿不到,所以把js文件的974行一段條件注釋掉了浦箱。
image.png
解決旋轉(zhuǎn)問題的js - imageUtil.js
/**
* imageUtil.js
*解決圖片旋轉(zhuǎn)的問題
* **/
import EXIF from './exif.js'
async function compressImage(path) {
let imageInfo = await getImageInfo(path)
let systemInfo = await getSystemInfo()
return new Promise(function(resolve, reject) {
// #ifdef APP-PLUS || APP-NVUE
appCompressImage(path, imageInfo).then(res => {
resolve(res)
}).catch(e => {
reject(e)
})
// #endif
// #ifdef H5
let orientation = 1;
let img = document.createElement("img");
img.src = path;
img.onload = function() {
EXIF.getData(img, function() {
orientation = EXIF.getTag(this, 'Orientation');
canvasImg(path, orientation, imageInfo, systemInfo).then(res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
}
img.onerror = function() {
reject(path)
}
// #endif
})
}
// app處理旋轉(zhuǎn)圖片
function appCompressImage(src, imageInfo) {
return new Promise(function(resolve, reject) {
let orientation = imageInfo.orientation;
let rotate = 0;
let quality = 80;
if (plus.os.name == "iOS") {
rotate = 0;
quality = 25;
} else {
switch (orientation) {
case 'up': //exif:1 不旋轉(zhuǎn)
rotate = 0;
break;
case 'down': //exif:3 旋轉(zhuǎn)180度
rotate = 180;
break;
case 'right': //exif:6 旋轉(zhuǎn)90度
rotate = 90;
break;
case 'left': //exif:8 旋轉(zhuǎn)270度
rotate = 270;
break;
default:
rotate = 0;
break;
}
}
plus.zip.compressImage({
src: src,
dst: "_doc/uniapp_temp" + '/compressed/' + Math.round(new Date()) + '.png',
format: 'png',
quality: quality,
width: 'auto',
height: 'auto',
rotate: rotate,
},
function(event) {
resolve(event.target)
},
function(error) {
reject(src);
});
})
}
// 畫圖片
function canvasImg(path, or, imageInfo, systemInfo) {
return new Promise(function(resolve, reject) {
let canvasId = 'uploadCanvas'
const ctx = uni.createCanvasContext(canvasId)
let scale = imageInfo.width / imageInfo.height
// 圖片參數(shù) start
let maxdestWidth = 1100 // 2000;
let destWidth = imageInfo.width;
let destHeight = imageInfo.height;
let destCompressWidth = imageInfo.width;
let destCompressHeight = imageInfo.height;
// 壓縮圖片 最大不超過5M 1200
// 當(dāng)寬大于高的時(shí)候
if (imageInfo.width > imageInfo.height) {
if (imageInfo.width > maxdestWidth) {
destCompressWidth = maxdestWidth;
destCompressHeight = Math.floor(destCompressWidth / scale);
} else {
destCompressWidth = imageInfo.width * 8 / 10;
destCompressHeight = Math.floor(destCompressWidth / scale);
}
}
// 當(dāng)高大于寬
else {
if (imageInfo.height > maxdestWidth) {
destCompressHeight = maxdestWidth;
destCompressWidth = Math.floor(destCompressHeight * scale);
} else {
destCompressHeight = imageInfo.height * 0.8;
destCompressWidth = Math.floor(destCompressHeight * scale);
}
}
destWidth = destCompressHeight
destHeight = destCompressWidth
// 圖片參數(shù) end
// 畫布參數(shù) start
let maxWidth = 300;
let canvasW = imageInfo.width;
let canvasH = imageInfo.height;
let width = imageInfo.width;
let height = imageInfo.height;
// canvas畫布不能超過最大寬
if (canvasW > maxWidth) {
canvasW = maxWidth;
canvasH = Math.floor(canvasW / scale);
}
width = canvasW
height = canvasH
// 畫布參數(shù) end
// console.log('--or---', or)
//單獨(dú)處理蘋果最新版本
if (systemInfo.model == 'iPhone' && systemInfo.system.indexOf('13.4.1') > -1) {
ctx.drawImage(path, 0, 0, canvasW, canvasH)
destWidth = destCompressWidth
destHeight = destCompressHeight
} else {
if (or == 6) { //逆時(shí)針旋轉(zhuǎn)了90
ctx.translate(width, 0)
ctx.rotate(Math.PI / 2)
ctx.drawImage(path, 0, 0, canvasH, canvasW)
} else if (or == 3) { //逆時(shí)針旋轉(zhuǎn)了180
ctx.translate(width, height)
ctx.rotate(Math.PI)
ctx.drawImage(path, 0, 0, canvasH, canvasW)
} else if (or == 8) { //順時(shí)針旋轉(zhuǎn)90
ctx.translate(0, height)
ctx.rotate(-Math.PI / 2)
ctx.drawImage(path, 0, 0, canvasH, canvasW)
} else {
ctx.drawImage(path, 0, 0, canvasW, canvasH)
// return resolve(path);
destWidth = destCompressWidth
destHeight = destCompressHeight
}
}
// console.log('圖片原始長寬', imageInfo, maxWidth, canvasW, canvasH, width, height, destWidth, destHeight);
ctx.draw(true, setTimeout(() => {
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: width, //畫布寬度
height: height,
destWidth: destWidth,
destHeight: destHeight,
fileType: 'png',
canvasId: canvasId,
success: (res) => {
resolve(res.tempFilePath)
},
fail: (err) => {
resolve(path);
}
})
}, 200))
})
}
// 獲取圖片信息
function getImageInfo(path) {
return new Promise(function(resolve, reject) {
// #ifdef APP-PLUS
plus.io.getImageInfo({
src: path,
success: function(image) {
// console.log('orientation=' + image.orientation);
resolve(image)
},
fail: function(err) {
console.log("getImageInfoErr: " + JSON.stringify(err));
reject(err)
}
});
// #endif
// #ifdef H5 || MP-WEIXIN
uni.getImageInfo({
src: path,
success: function(image) {
// console.log('orientation=' + image.orientation);
resolve(image)
},
fail: function(err) {
console.log("getImageInfoErr: " + JSON.stringify(err));
reject(err)
}
});
// #endif
});
}
// 獲取系統(tǒng)信息
function getSystemInfo(path) {
return new Promise(function(resolve, reject) {
uni.getSystemInfo({
success(res) {
resolve(res)
},
fail(err) {
console.log("getSystemInfoErr: " + JSON.stringify(err));
reject(err)
}
});
});
}
export default compressImage
還有要注意的點(diǎn)吸耿,在ios中上傳的方法設(shè)置這個(gè)才上傳成功
cai
題外話,原本沒處理的圖片地址是一個(gè)url酷窥,我以為還要把canvas之后的base64的格式轉(zhuǎn)化成url才可以上傳咽安,然而其實(shí)可以直接base64上傳,當(dāng)時(shí)一時(shí)沒轉(zhuǎn)過彎蓬推,那叫一個(gè)尷尬呀妆棒。。沸伏。