• ios手机竖屏拍照图片旋转90°问题解决方法


    手机拍照会给图片添加一个Orientaion信息(即拍照方向),如下:

    用ios手机拍照,系统会给图片加上一个方向的属性, ios相机默认的拍照方向是后摄Home键在右为正,前摄Home键在左为正。

    1代表正常的拍摄角度,ios横屏下拍摄、安卓机无论横屏竖屏拍摄,Orientaion的值都为1;但是ios竖屏拍摄,Orientaion的值为6,即竖着拍出的照片被添加了一个顺时

    针旋转90°的拍照方向,显示的时候其实就是横着拍的照片顺时针旋转90°而成。当我们对拍出来的照片进行处理后,这个拍摄方向Orientaion信息就会丢失,显示的效果

    自然回到横屏状态,看起来像是逆时针旋转了90°。

    实际上iOS手机竖着拍出的照片与横着拍出的照片其本质上是一样的,只不过竖着拍出的照片被添加了一个顺时针旋转90°的拍照方向,所以显示的时候,就是横着拍的照

    片顺时针旋转90°而成的,照片旋转bug的原因、其实就是当我们在前端对图片进行像素处理或者drawInRect等操作之后,照片

    的Orientaion信息,即为拍照方向信息被删除了,所以iOS手机竖着拍的照片又回到了横着的状态,看起来也就是逆时针旋转了90°!

    html

    <!doctype html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <meta name="viewport"

              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <title>前端解决ios手机竖拍上传图片旋转90° 完美适配:Android/ios/Windows</title>

        <script src="js/jquery-1.11.3.min.js"></script>

        <script src="js/exif.js"></script>

        <script src="js/uploadImage.js"></script>

        <script src="js/tech.js"></script>

    </head>

    <body>

    <div class="featfile">

        <div class="featimage featupfile phoneclick" id="imgcontainer">

            <img src="" class="fileimg" id="fileimg">

            <!--canvas 为后文引用-->

            <canvas id="Drawborder"></canvas>

        </div>

        <!--   multiple="multiple" 是为了input能直接支持 Formdata 上传图片到后台 后文有述 -->

        <input type=file name="image" multiple="multiple" class="imgfilebtn" accept="image/jpeg,image/png,image/gif,image/jpg" onchange="selectFileImage(this)">

    </div>

    </body>

    </html>

    js

    function selectFileImage(fileObj) {

        var file = fileObj.files['0'];

        var Orientation = null;

        $('.loading_bg').fadeIn();

        if (file) {

            console.log("正在上传,请稍后...");

            var rFilter = /^(image/jpeg|image/png)$/i; // 检查图片格式

            if (!rFilter.test(file.type)) {

                //showMyTips("请选择jpeg、png格式的图片", false);

                return;

            }

            // var URL = URL || webkitURL;

            //获取照片方向角属性,用户旋转控制

            EXIF.getData(file, function() {

                // alert(EXIF.pretty(this));

                EXIF.getAllTags(this);

                //alert(EXIF.getTag(this, 'Orientation'));

                Orientation = EXIF.getTag(this, 'Orientation');

                //return;

            });

            var oReader = new FileReader();

            oReader.onload = function(e) {

                //var blob = URL.createObjectURL(file);

                //_compress(blob, file, basePath);

                var image = new Image();

                image.src = e.target.result;

                image.onload = function() {

                    var expectWidth = this.naturalWidth;

                    var 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;

                    }

                    var canvas = document.createElement("canvas");

                    var ctx = canvas.getContext("2d");

                    canvas.width = expectWidth;

                    canvas.height = expectHeight;

                    ctx.drawImage(this, 0, 0, expectWidth, expectHeight);

                    var u = navigator.userAgent;

                    //修复ios

                    if (u.match(/iphone/i)) {

                        console.log('iphone');

                        //如果方向角不为1,都需要进行旋转 added by lzk

                        if(Orientation != "" && Orientation != 1){

                            console.log('旋转处理');

                            switch(Orientation){

                                case 6://需要顺时针(向左)90度旋转

                                    console.log('需要顺时针(向左)90度旋转');

                                    rotateImg(this,'left',canvas);

                                    break;

                                case 8://需要逆时针(向右)90度旋转

                                    console.log('需要逆时针(向右)90度旋转');

                                    rotateImg(this,'right',canvas);

                                    break;

                                case 3://需要180度旋转

                                    console.log('需要180度旋转');

                                    rotateImg(this,'right',canvas);//转两次

                                    rotateImg(this,'right',canvas);

                                    break;

                            }

                        }

                        //base64 在外定义为全局变量

                        //下面base64为得到旋转后的base64图片

                        base64 = canvas.toDataURL("image/jpeg", 0.8);

                        var type = 'jpeg';

                        var fixtype = function (type) {

                            type = type.toLocaleLowerCase().replace(/jpg/i, 'jpeg');

                            var r = type.match(/png|jpeg|bmp|gif/)[0];

                            return 'image/' + r;

                        };

                        base64 = base64.replace(fixtype(type), 'image/jpeg');

                        // saveFile(base64, '111')  此处是如果想要保存当前图片到本地的话;

                        //这里是把已经旋转过的图片路径赋值到img中

                        $(".fileimg").attr("src", base64);

                    }

                    else if (u.indexOf('Android') > -1 || u.indexOf('Adr') > -1) {// android可以直接不变

                        $(".fileimg").attr("src", e.target.result);

                        //如果安卓收到ios拍摄的照片,可以按PC端方式判断

                    }

                    else{

                        //修复PC端上上传ios拍出来的图片

                        if(Orientation != "" && Orientation != 1){

                            //alert('旋转处理');

                            switch(Orientation){

                                case 6://需要顺时针(向左)90度旋转

                                    console.log('需要顺时针(向左)90度旋转');

                                    rotateImg(this,'left',canvas);

                                    break;

                                case 8://需要逆时针(向右)90度旋转

                                    console.log('需要逆时针(向右)90度旋转');

                                    rotateImg(this,'right',canvas);

                                    break;

                                case 3://需要180度旋转

                                    console.log('需要180度旋转');

                                    rotateImg(this,'right',canvas);//转两次

                                    rotateImg(this,'right',canvas);

                                    break;

                            }

                        }

                        base64 = canvas.toDataURL("image/jpeg", 0.8);

                        var type = 'jpeg';

                        var fixtype = function (type) {

                            type = type.toLocaleLowerCase().replace(/jpg/i, 'jpeg');

                            var r = type.match(/png|jpeg|bmp|gif/)[0];

                            return 'image/' + r;

                        };

                        base64 = base64.replace(fixtype(type), 'image/jpeg');

                        // saveFile(base64, '111');

                        $(".fileimg").attr("src", base64);

                    }

                };

            };

            oReader.readAsDataURL(file);

        }

    }

    //将图片保存到本地

    var saveFile = function (data, filename) {

        var link = document.createElement('a');

        link.href = data;

        link.download = filename;

        var event = document.createEvent('MouseEvents');

        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

        link.dispatchEvent(event);

    }

    //对图片旋转处理 added by lzk

    function rotateImg(img, direction,canvas) {

        //alert(img);

        //最小与最大旋转方向,图片旋转4次后回到原方向

        var min_step = 0;

        var max_step = 3;

        //var img = document.getElementById(pid);

        if (img == null)return;

        //img的高度和宽度不能在img元素隐藏后获取,否则会出错

        var height = img.height;

        var width = img.width;

        //var step = img.getAttribute('step');

        var 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);

        }

        //旋转角度以弧度值为参数

        var degree = step * 90 * Math.PI / 180;

        var ctx = canvas.getContext('2d');

        switch (step) {

            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;

        }

    }

    下面讲述一下如何用ajax传输base64图片,不需要表单,直接使用input就可以完成

    上文html中有述, 在input中添加multiple="multiple"属性即可

    //此函数是为了转化base64的值,用于传给后台

    function convertBase64Url(urlData){

         //获取canvas中的图片信息

             //window.atob方法将其中的base64格式的图片转换成二进制字符串;若将转换后的值直接赋值给Blob会报错,需Uint8Array转换:最后创建Blob对象;

             var _data = window.atob(data.split(",")[1]);

             //如果不用ArrayBuffer,发送给服务器的图片格式是[object Uint8Array],上传失败...

             var buffer = new ArrayBuffer(_data.length);

             var _buffer = new Uint8Array(buffer);

             for(var i = 0; i < _data.length; i++) {

                       _buffer[i] = _data.charCodeAt(i);

             }

             var blob;

    var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;;

             if(Builder) {

                       var builder = new Builder();

                       builder.append(_buffer);

                       blob = builder.getBlob('image/jpeg');

             } else {

                       blob = new window.Blob([_buffer], {

                                type: 'image/jpeg'

                       });

             }

             return blob;}

    //到这里就能实现与后台的交互了

    var base64 = null;

    $('.button').click(function(){

        var formDate = new FormData();

        formDate.append('image', convertBase64Url(base64));

        $.ajax({

                    beforeSend: function (xhr) {

                    },

                    type: 'POST',

                    url: url,

                    data: formDate,

                    contentType: false,

                    processData: false,

                    success: function(data){

                       //成功回调

                    },

                    error: function (data) {

                       //失败返回

                    }

                })

    })

  • 相关阅读:
    dotnet 6 使用 HttpWebRequest 进行 POST 文件将占用大量内存
    递增运算符重载
    左移运算符重载
    流程与标准
    Erp系统常用递归,查类目树,查上级,查下级
    判断一个点是否在指定的直角三角形内
    [LeetCode]2281. Sum of Total Strength of Wizards 计算公式推导详解(JavaScript版)
    Airtest+Poco常见Exception报错
    nodejs连接mysql数据库,报错Client does not support authentication protocol requested by server的解决方法
    Poco API精讲之元素树冻结freeze()
  • 原文地址:https://www.cnblogs.com/ranyonsue/p/10830688.html
Copyright © 2020-2023  润新知