React开发使用蚂蚁组件ImagePicker图片翻转问题

项目是react使用的是antd-mobile和es6开发,iOS中上传图片被旋转了90度,这里解决后记录下

1、exif获取图片信息并旋转

首先使用exif对图片进行了翻转,上传的图片好了.

import * as exif from "exif-js";
 selectFileImage(files: { file: any; orientation: number; url: string; info: WebUploader.File }[], type: string, index: number) {
        let fileArr = [] as any;
        let _this = this;
        // let file = fileObj.files[0];
        files &&
            files.map((item, index) => {
                let file = item.file,
                    Orientation = null;
                if (file) {
                    exif.getData(file, function() {
                        exif.getAllTags(this);
                        Orientation = exif.getTag(this, "Orientation");
                        // console.log(Orientation, this);
                        // alert(Orientation);
                    });

                    let reader = new FileReader();
                    reader.readAsDataURL(file);

                    reader.onload = function(e) {
                        let image = new Image();
                        image.src = e.target!.result;
                        image.onload = function() {
                            let expectWidth = this.naturalWidth;
                            let expectHeight = this.naturalHeight;

                            if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
                                expectWidth = 800;
                                expectHeight = (expectWidth * this.naturalHeight) / this.naturalWidth;
                            } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
                                expectHeight = 1200;
                                expectWidth = (expectHeight * this.naturalWidth) / this.naturalHeight;
                            }
                            let canvas = document.createElement("canvas");
                            let ctx = canvas.getContext("2d");
                            canvas.width = expectWidth;
                            canvas.height = expectHeight;
                            ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
                            let base64 = null;
                            // 修复ios
                            let u = navigator.userAgent;
                            if (u.match(/iphone/i)) {
                                if (Orientation !== "") {
                                    // alert('旋转处理');
                                    switch (Orientation as any) {
                                        case 6: // 需要顺时针(向左)90度旋转
                                            // alert('需要顺时针(向左)90度旋转');
                                            // _this.rotateImg(this, "left", canvas);
                                            break;
                                        case 8: // 需要逆时针(向右)90度旋转
                                            // alert('需要顺时针(向右)90度旋转');
                                            _this.rotateImg(this, "right", canvas);
                                            break;
                                        case 3: // 需要180度旋转
                                            // alert('需要180度旋转');
                                            _this.rotateImg(this, "right", canvas); // 转两次
                                            _this.rotateImg(this, "right", canvas);
                                            break;
                                        default:
                                            break;
                                    }
                                    /*var mpImg = new MegaPixImage(image);
                                    mpImg.render(canvas, {
                                        maxWidth: 800,
                                        maxHeight: 1200,
                                        quality: 0.8,
                                        orientation: 8
                                    });*/
                                    base64 = canvas.toDataURL("image/jpeg", 0.8);
                                    let imageFile = _this.dataURLtoFile(base64, new Date().getTime());
                                    item.file = imageFile;
                                    fileArr.push(item);
                                    // console.log(fileArr, files)
                                    if (index === files.length - 1) {
                                        // alert("start")
                                        _this.myOnChange(fileArr, type, index);
                                    }
                                }
                            } else if (u.indexOf("Android") > -1 || u.indexOf("Adr") > -1) {
                                alert(Orientation);
                                // android可以直接不变
                                if (Orientation !== "") {
                                    // alert('旋转处理');
                                    switch (Orientation as any) {
                                        case 6: // 需要顺时针(向左)90度旋转
                                            // alert('需要顺时针(向左)90度旋转');
                                            _this.rotateImg(this, "left", canvas);
                                            break;
                                        case 8: // 需要逆时针(向右)90度旋转
                                            // alert('需要顺时针(向右)90度旋转');
                                            _this.rotateImg(this, "right", canvas);
                                            break;
                                        case 3: // 需要180度旋转
                                            // alert('需要180度旋转');
                                            _this.rotateImg(this, "right", canvas); // 转两次
                                            _this.rotateImg(this, "right", canvas);
                                            break;
                                        default:
                                            break;
                                    }
                                    /*var mpImg = new MegaPixImage(image);
                                    mpImg.render(canvas, {
                                        maxWidth: 800,
                                        maxHeight: 1200,
                                        quality: 0.8,
                                        orientation: 8
                                    });*/
                                    base64 = canvas.toDataURL("image/jpeg", 0.8);
                                    let imageFile = _this.dataURLtoFile(base64, new Date().getTime());
                                    item.file = imageFile;
                                    fileArr.push(item);
                                    // console.log(fileArr, files)
                                    if (index === files.length - 1) {
                                        // alert("start")
                                        _this.myOnChange(fileArr, type, index);
                                    }
                                }
                            }
                        };
                    };
                } else {
                    fileArr.push(item);
                }
            });
    }
    dataURLtoFile(dataurl: string, filename: string) {
        const arr = dataurl.split(","),
            mime = arr![0]!.match(/:(.*?);/)![1],
            bstr = atob(arr[1]);

        let n = bstr.length;
        const u8arr = new Uint8Array(n);

        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, { type: mime });
    }
    // 对图片旋转处理 added by lzk
    rotateImg(img, direction, canvas) {
        // alert(img);
        // 最小与最大旋转方向,图片旋转4次后回到原方向
        let min_step = 0;
        let max_step = 3;
        // var img = document.getElementById(pid);
        if (img == null) return;
        // img的高度和宽度不能在img元素隐藏后获取,否则会出错
        let height = img.height;
        let width = img.width;
        // var step = img.getAttribute('step');
        let step = 2;
        if (step == null) {
            step = min_step;
        }
        if (direction === "right") {
            step++;
            // 旋转到原位置,即超过最大值
            step > max_step && (step = min_step);
        } else {
            step--;
            step < min_step && (step = max_step);
        }
        // 旋转角度以弧度值为参数
        let degree = (step * 90 * Math.PI) / 180;
        let ctx = canvas.getContext("2d");
        switch (step as any) {
            case 0:
                canvas.width = width;
                canvas.height = height;
                ctx.drawImage(img, 0, 0);
                break;
            case 1:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, 0, -height);
                break;
            case 2:
                canvas.width = width;
                canvas.height = height;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, -height);
                break;
            case 3:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, 0);
                break;
            default:
                break;
        }
    }

    onChange(files: { file: any; orientation: number; url: string; info: WebUploader.File }[], type: string, index: number) {
        const { fileNumLimit } = this.props;
        if (files.length > fileNumLimit) {
            Toast.fail("文件数量超过限制!", 3);
            return;
        }
        if (this.props.fileSuccess) {
            // 有回调就执行,企业认证表单提交会调用
            this.props.fileSuccess(files);
        }
        console.log("onChange", files, type)
        if (type === "add") {
            this.selectFileImage(files, type, index);
        } else if (type === "remove") {
            const { files: old } = this.state,
                file = old[index],
                { info = file } = file as any;
            this.attachProvider.delFile(info.file || info, this.uploader);
            this.setState({ files } as any);
        }
    }
    myOnChange(files: { file: any; orientation: number; url: string; info: WebUploader.File }[], type: string, index: number) {
        if (this.props.single) {
            const file = files.last();
            this.uploader.once("fileQueued", (info: WebUploader.File) => (((file.info = info), ((info as any).src = file)), this.setState({ files: [file] } as any)));
            this.uploader.addFile(file.file);
        } else {
            files.map((file, index) => {
                files
                alert(file.orientation)
                if (index >= this.state.files.length) {
                    setTimeout(() => {
                        this.uploader.once("fileQueued", (info: WebUploader.File) => (((file.info = info), ((info as any).src = file)), this.setState({ files: files } as any)));
                        this.uploader.addFile(file.file);
                    });
                }
            });
        }
    }
2、新的问题

后面出现了新的问题,上传后没问题但是蚂蚁组件ImagePicker的预览图里还是翻转的,排查蚂蚁组件的file如下,发现这里面有个orientation还记录着旋转信息
1
手动给这个值附上假的旋转信息,这样蚂蚁组件ImagePicker就不会自己翻转了

files && files.length && files.map((file, index) => {
    file.orientation = 1
});

1
2

3、其他发现,采用服务端进行翻转

详细处理方法如下

苹果手机iOS9.0以后图片就会自动正过来但是图片exif方向还是标记了旋转90度。
后面因为性能问题图片处理放在服务端处理分成iOS和安卓两种
1、iOS如果方向值是6,不用进行图片翻转,但是抹除图片exif中翻转信息为1
2、安卓如果方向值是6,按规定进行翻转并重置exif中翻转信息为1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值