now007
now007
  • 发布:2019-11-20 14:53
  • 更新:2022-01-24 13:25
  • 阅读:8865

uniapp h5上传图片对图片进行压缩旋转处理

分类:uni-app

csdn博客地址:uniapp h5上传图片对图片进行旋转处理

场景:uniapp开发的h5项目,需要内嵌在app中运行,在项目首页有一块是自定义上传日历背景图,并且需要进行裁剪。
最开始直接使用的插件市场的插件,但是由于webview的原因,该项目内嵌app后在ios上出现了无法解决的bug。故弃用了插件,并且由于需求调整目前只进行图片的上传旋转处理。(下面着重旋转的处理)

思路:

1、参考vue的处理方法,需要exif.js 获取到图片meta信息中的旋转角度,故首先需要引入exif.js,(本人直接从bootcdn上搜索下载的exif.min.js )(使用import引入本地文件的方式尝试了下没有成功,放弃了。由于项目本身需要存在了引入第三方的js方法所以exifjs是通过动态添加js的方式全局引入的)

2、通过uni.chooseImage 获取到图片的临时路径,并且将blob临时路径转化为 file文件用于exif获取图片的旋转值

3、根据获取到旋转值(有:1 3 6 8),如下:

                        //如果方向角不为1,都需要进行旋转  
                        switch (Orientation) {  
                            case 6: //需要顺时针(向右)90度旋转  
                                console.log('(向右)90度旋转');  
                                break;  
                            case 8: //需要逆时针(向左)90度旋转  
                                console.log('向左)90度旋转');  
                                break;  

                            case 3: //需要180度旋转 转两次  
                                console.log('需要180度旋转');  
                                break;  
                            default:  
                                break;  
                        }  

4、根据网上搜索的处理图片旋转方法或者从往期vue的上传图博客中提到的,对图片进行旋转处理,最终拿到base64的图片信息然后对图片进行上传。(1.直接上传base64 ;2.将base64转化为blob文件后再传后台)

具体代码如下:

1、
choiceImg(){
var that = this;
let maxWidth = 500; //压缩图片最大宽度
let Orientation = 1;
uni.chooseImage({
count: 1, // 能够选择的图片数量
sizeType: ['original', 'compressed'], // original: 原图, compressed: 压缩图, 默认二者都有
sourceType: ['album'], // album: 从相册选择 camera: 相机拍照
success: res => {
let imgArr = res.tempFilePaths; // 所选择图片的临时路径数组
//BlobUrl转blob数据

                uni.showToast({  
                    icon: "none",  
                    title: "图片处理中..."  
                })  
                //blob数据转file  
                this.objectURLToBlob(imgArr[0], function(blob) {  
                    let files = new window.File([blob], 'file.name', { type: 'file.type' });  
                    console.log('获取图片文件', files);  
                    EXIF.getData(files, async function() {  
                        let or = EXIF.getTag(this, 'Orientation'); //这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8  
                        console.log(or);  
                        Orientation = or;  
                        var img = null;  
                        var canvas = null;  
                        await that.comprossImage(imgArr[0], maxWidth, function(e) {  
                            img = e.img;  
                            canvas = e.canvas;  
                        });  
                        let baseStr = '';  
                        //如果方向角不为1,都需要进行旋转  
                        switch (Orientation) {  
                            case 6: //需要顺时针(向右)90度旋转  
                                console.log('(向右)90度旋转');  
                                baseStr = that.rotateImg(img, 'right', canvas);  
                                break;  
                            case 8: //需要逆时针(向左)90度旋转  
                                console.log('向左)90度旋转');  
                                baseStr = rotateImg(img, 'left', canvas);  
                                break;  

                            case 3: //需要180度旋转 转两次  
                                console.log('需要180度旋转');  
                                baseStr = that.rotateImg(img, 'right', canvas, 2);  
                                break;  
                            default:  
                                baseStr = that.rotateImg(img, '', canvas);  
                                break;  
                        }  
                    });  
                });  
            }  
        });  

}
2、1中使用到的将blob转化为file方法 和图片的压缩方法
objectURLToBlob(url, callback) {
var http = new XMLHttpRequest();
http.open('GET', url, true);
http.responseType = 'blob';
http.onload = function(e) {
if (this.status == 200 || this.status === 0) {
callback(this.response);
}
};
http.send();
},
async comprossImage(imgSrc, maxWidth, func) {
if (!imgSrc) return 0;
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: imgSrc,
success(res) {
let img = new Image();
img.src = res.path;
console.log(img);

                    let canvas = document.createElement('canvas');  

                    let obj = new Object();  
                    obj.img = img;  
                    obj.canvas = canvas;  
                    resolve(func(obj));  
                }  
            });  
        });  
    },  

3、图片的旋转处理
rotateImg(img, direction, canvas, times = 1) {
console.log('开始旋转');
//最小与最大旋转方向,图片旋转4次后回到原方向
var min_step = 0;
var max_step = 3;
if (img == null) return;

        //img的高度和宽度不能在img元素隐藏后获取,否则会出错  
        var height = img.height;  
        var width = img.width;  
        let maxWidth = 500;  
        let canvasWidth = width; //图片原始长宽  
        let canvasHeight = height;  
        let base = canvasWidth / canvasHeight;  
        console.log(maxWidth);  
        if (canvasWidth > maxWidth) {  
            canvasWidth = maxWidth;  
            canvasHeight = Math.floor(canvasWidth / base);  
        }  
        width = canvasWidth;  
        height = canvasHeight;  
        var step = 0;  

        if (step == null) {  
            step = min_step;  
        }  

        if (direction == 'right') {  
            step += times;  
            //旋转到原位置,即超过最大值  
            step > max_step && (step = min_step);  
        } else if (direction == 'left') {  
            step -= times;  
            step < min_step && (step = max_step);  
        } else {  
            //不旋转  
            step = 0;  
        }  

        //旋转角度以弧度值为参数  
        var degree = (step * 90 * Math.PI) / 180;  
        var ctx = canvas.getContext('2d');  
        // console.log(degree)  
        // console.log(step)  
        switch (step) {  
            case 1:  
                console.log('右旋转 90度');  
                canvas.width = height;  
                canvas.height = width;  
                ctx.rotate(degree);  
                ctx.drawImage(img, 0, -height, width, height);  
                break;  
            case 2:  
                //console.log('旋转 180度')  
                canvas.width = width;  
                canvas.height = height;  
                ctx.rotate(degree);  
                ctx.drawImage(img, -width, -height, width, height);  
                break;  
            case 3:  
                console.log('左旋转 90度');  
                canvas.width = height;  
                canvas.height = width;  
                ctx.rotate(degree);  
                ctx.drawImage(img, -width, 0, width, height);  
                break;  
            default:  
                //不旋转  
                canvas.width = width;  
                canvas.height = height;  
                ctx.drawImage(img, 0, 0, width, height);  
                break;  
        }  

        let baseStr = canvas.toDataURL('image/jpeg', 1);  
        // console.log(baseStr)  
        // return baseStr;  
        // replace("data:image/jpeg;base64,", "")  
        // 将base64转化为blob文件进行图片上传,(考虑到转化后再上传耗费时间暂时没有使用,如果需要base64ToPath 方法可百度或者私信我)  
        // base64ToPath(baseStr).then(tempPath => {  
        //  this.uploadBgImg(tempPath)  
        // });  
        // 自定义上传请求  
        this.uploadBaseImg(baseStr);  
    },  
0 关注 分享

要回复文章请先登录注册

healthy

healthy

666!
2022-01-24 13:25
now007

now007 (作者)

回复 2***@qq.com :
重新看了下,undefined说明没有旋转。
2020-11-07 16:55
now007

now007 (作者)

回复 2***@qq.com :
EXIF 有没有引入成功
2020-11-07 16:36
2***@qq.com

2***@qq.com

let or = EXIF.getTag(this, 'Orientation'); //这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8
console.log(or);
这个地方打印的是 undefined
2020-11-03 16:10