H5解决IOS拍照横屏问题,含后端上传

  • Post author:
  • Post category:其他


IOS这个照片横屏问题相信困扰了不少程序猿,作者当时也是寻找各种解决办法,前端处理试过,后端处理也试过,base64也用过,无奈没有更好的方法,今天这个问题可以说是完美解决了,废话不多说 直接撸代码

这是html部分

<div class="test">
        <img src="" width="200" height="200" class="img">
        <img src="" width="200" height="200" class="img2">
        <input type="file" name="img" class="imgs" οnchange="imgdata(event)">
        <button type="button" class="sub">提交</button>
    </div>

这是js部分


    //input:file change事件
    function imgdata(obj) {
        var e4e =  getObjectURL(obj.target.files[0]);
        $(".img2").attr('src',e4e);
        var readerFiles = obj.target.files[0];
        console.log(readerFiles);
        photoCompress(readerFiles,{quality: 0.8},
            function(base64Codes) {
                $(".img").attr('src', base64Codes);
            }
        )
    }




    //获取上传图片并处理成正常的图片
    function photoCompress(file,w,objDiv) {
        var ready = new FileReader();
        /*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
        ready.readAsDataURL(file);
        ready.onload = function() {
            var re = this.result;
            canvasDataURL(re,w, objDiv)
        }
    }


    //获取上传图片的Orientation并旋转
    function canvasDataURL(path,w, callback) {
        var img = new Image();
        var canvas = document.createElement("canvas");
        img.onload = function() {
            EXIF.getData(this, function() {
                Orientation = EXIF.getTag(this, 'Orientation');
                //如果方向角不为1,都需要进行旋转
                if (Orientation != "" && Orientation != 1 && Orientation) {
                    switch (Orientation) {
                        case 6: //需要顺时针(向左)90度旋转
                            console.log(66);


                            rotateImg(this, 'left', canvas,w, callback);
                            break;
                        case 8: //需要逆时针(向右)90度旋转  
                            rotateImg(this, 'right', canvas,w, callback);
                            break;
                        case 3: //需要180度旋转  
                            rotateImg(this, 'right', canvas,w, callback); //转两次  
                            rotateImg(this, 'right', canvas,w, callback);
                            break;
                    }
                } else {
                    callback(path);
                }
            });
        }
        img.src = path;
    }


    //根据Orientation旋转图片,生成base64的文件
    function rotateImg(img, direction, canvas, w,callback3) {
        //最小与最大旋转方向,图片旋转4次后回到原方向    
        var min_step = 0;
        var max_step = 3;
        if (img == null) return;
        //img的高度和宽度不能在img元素隐藏后获取,否则会出错    
        var height = img.height;
        var width = img.width;
        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;
        }
        dat = canvas.toDataURL("image/jpeg", w.quality);


        callback3(dat)
    };


    //将base64图片转换成文件形式 后台用$_FILES可以直接获取到
    function convertBase64UrlToBlob(urlData) {
        var arr = urlData.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]),
            n = bstr.length,
            u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {
            type: mime
        });
    }

上传部分

$('.sub').unbind('click').on('click',function(){
            // alert(3);
            console.log(Date.parse(new Date()));
            file = convertBase64UrlToBlob($(".img").attr('src'));
            var base64img = $(".img").attr('src');
            var formData = new FormData();
            // formData.append("image2", base64img, "file64_" + Date.parse(new Date()) + ".jpg");
            formData.append("image", file, "file_" + Date.parse(new Date()) + ".jpg");
            $.ajax({
                url: '{:url("Index/upfile")}',
                type: 'POST',
                dataType: 'JSON',
                data: formData,
                // data: {'image2':base64img},
                // 告诉jQuery不要去处理发送的数据
                processData: false,
                // 告诉jQuery不要去设置Content-Type请求头
                contentType: false,
            })
            .done(function(e) {
                console.log(Date.parse(new Date()));
                console.log(e);
            })
            .fail(function() {
                console.log("error");
            })
            .always(function() {
                console.log("complete");
            });
            
        })

后台部分

public function upfile()
    {
        // $file = request()->file('image');
        $file = input('file.image');
        $file2 = input('image2');
        if($file2){
            // $file = input('sharepic'); //base64de 
            // if (!$file) return $this->_A(false, '图片不存在');

            $str = $file2; //获取上传文件字符串 
            $str = str_replace(' ', '+', $str); //替换空字符串为+
            $str = str_replace('\n', '', $str);  //置空换行符
            $str = str_replace('\t', '', $str);
            $str = str_replace('\r', '', $str);
            $str = explode(',', $str);
            $str = stripslashes($str[1]);  //过虑转义符        
            $img = base64_decode($str); //解码  

            
            $path = ROOT_PATH . 'public' . DS . 'uploads' . DS  . date('Ymd');
            
            @mkdir($path, 0755, true);
            $filename = '/uploads/'.date('Ymd').'/'.time().rand(100000,999999).'.png';

            if(file_put_contents('.'.$filename, $img)){
             return json(['status' => 1, 'msg' => 'ok', 'path' => $filename]);
            }else{
             $this->_A(false,'操作失败,请稍后再试');
            }

        }
        if ($file) {
            $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
            if ($info) {
                // 成功上传后 获取上传信息
                $path = 'uploads' . DS . $info->getSaveName();
                // $model = db('img');
                // $model->insert(['user_id' => $this->user_id, 'img' => $path, 'create_time' => time()]);
                $path = DS . $path;
                // $image = \think\Image::open('.'.$path);
                // $image->thumb(500,500)->save($path);
                return json(['status' => 1, 'msg' => 'ok', 'path' => $path]);
            } else {
                // 上传失败获取错误信息
                // $file->getError();
                return json(['status' => 0, 'msg' => '图片上传失败']);
            }
        } else {
            return json(['status' => 0, 'msg' => '请选择上传文件']);
        }
    }

经测试 这种方式比上传base64图片快3倍,并减少后台服务器压力,

需要引用的js:jquery-3.2.1.min.js   exif.js

后台语言PHP 框架thinkphp5

用到的js

点击打开链接



版权声明:本文为yaofare原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。