【uni-app】H5以及真机(android& ios解决上传图片旋转90度的问题)

2 篇文章 0 订阅

h5是通过拿到旋转的值,重新用canvas画图,所以在页面需要加入canvas 元素,其中用v-if的原因,是重复上传的话之前画的不会清空掉,所以用v-if来清空。还有canvas要设置height: 100vh;width: 100vw; 才可以把上传的图片完整的画出来。然后在外一层加上overflow: hidden;就行,下面的代码片段是自己封装的组件中的片段

 

    <view class="h-upload-img-content">
            <view class="h-upload-img-content-input" @click="onChangeUpload" v-if="!imgSrc">
                <text class="cross"></text>
                <!--canvas 用来解决图片旋转的-->
                <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}个文件`, 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]);
                }
            });
        },

        // 解决有些图片会旋转的问题
        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因为要拿到旋转的值,所以引用exif.js文件,这个直接在github就可以搜到,但因为img中complete这个值我拿不到,所以把js文件的974行一段条件注释掉了。

image.png

解决旋转问题的js - imageUtil.js

 


/**
 *  imageUtil.js
 *解决图片旋转的问题 
 * **/

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处理旋转图片
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 不旋转
                    rotate = 0;
                    break;
                case 'down': //exif:3 旋转180度
                    rotate = 180;
                    break;
                case 'right': //exif:6 旋转90度
                    rotate = 90;
                    break;
                case 'left': //exif:8 旋转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

        // 图片参数 start
        let maxdestWidth = 1100 // 2000;
        let destWidth = imageInfo.width;
        let destHeight = imageInfo.height;

        let destCompressWidth = imageInfo.width;
        let destCompressHeight = imageInfo.height;

        // 压缩图片 最大不超过5M  1200
        // 当宽大于高的时候
        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);
            }
        }
        // 当高大于宽
        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
        // 图片参数 end


        // 画布参数 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
        // 画布参数 end

        // console.log('--or---', or)
               //单独处理苹果最新版本
        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) { //逆时针旋转了90
                ctx.translate(width, 0)
                ctx.rotate(Math.PI / 2)
                ctx.drawImage(path, 0, 0, canvasH, canvasW)
            } else if (or == 3) { //逆时针旋转了180
                ctx.translate(width, height)
                ctx.rotate(Math.PI)
                ctx.drawImage(path, 0, 0, canvasH, canvasW)
            } else if (or == 8) { //顺时针旋转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
    });
}

// 获取系统信息
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

还有要注意的点,在ios中上传的方法设置这个才上传成功

cai

题外话,原本没处理的图片地址是一个url,我以为还要把canvas之后的base64的格式转化成url才可以上传,然而其实可以直接base64上传,当时一时没转过弯,那叫一个尴尬呀。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值