【uni-app】H5以及真機(jī)(android& ios解決上傳圖片旋轉(zhuǎn)90度的問題)

又更新了下材蹬,難搞,蘋果手機(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è)尷尬呀妆棒。。沸伏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末糕珊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子毅糟,更是在濱河造成了極大的恐慌放接,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件留特,死亡現(xiàn)場離奇詭異纠脾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蜕青,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門苟蹈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人右核,你說我怎么就攤上這事慧脱。” “怎么了贺喝?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵菱鸥,是天一觀的道長。 經(jīng)常有香客問我躏鱼,道長氮采,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任染苛,我火速辦了婚禮鹊漠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己躯概,他們只是感情好登钥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著娶靡,像睡著了一般牧牢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姿锭,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天结执,我揣著相機(jī)與錄音,去河邊找鬼艾凯。 笑死献幔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的趾诗。 我是一名探鬼主播蜡感,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恃泪!你這毒婦竟也來了郑兴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤贝乎,失蹤者是張志新(化名)和其女友劉穎情连,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體览效,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡却舀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锤灿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挽拔。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖但校,靈堂內(nèi)的尸體忽然破棺而出螃诅,到底是詐尸還是另有隱情,我是刑警寧澤状囱,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布术裸,位于F島的核電站,受9級(jí)特大地震影響亭枷,放射性物質(zhì)發(fā)生泄漏袭艺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一奶栖、第九天 我趴在偏房一處隱蔽的房頂上張望匹表。 院中可真熱鬧,春花似錦宣鄙、人聲如沸袍镀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苇羡。三九已至,卻和暖如春鼻弧,著一層夾襖步出監(jiān)牢的瞬間设江,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工攘轩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叉存,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓度帮,卻偏偏與公主長得像歼捏,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笨篷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355