因为 手机重力感应 人们在拍照的时候,不同的重力,图片会有旋转

 

ios 没有统一 安卓 统一为 1 base64上传到oss

 

/*
	 * 裁剪图片- -base64 文件流 上传
	 * $base64_data   为以#号分割的字符串
	 */
	public function base64_img($base64_data){
        ini_set('max_execution_time','300');

	    $img_str = '';
	    //判断是否是base64文件流
	    if(strpos($base64_data,'base64') !== false){
	        $img_arr = explode('#',$base64_data);

                foreach ($img_arr as $key => $value){

                    if(strpos($value,'http://') !== false){
                        $img_arr[$key] = $value;
                    }else{
                        //图片类型
                        $type = $this->header_byte(substr($value,5,strpos($value,';')-5));
                        //文件流反转
                        $img_data_str = substr($value,strpos($value,',')+1);
                        //图片资源
                        $img_data = base64_decode($img_data_str);

                        //上传oss  拼接路径
                        $filename = "upload/images/base64/".date("Y/m/d",time());
                        $filename .= "/upload_".time().rand(1111,9999).".".$type;

                        Storage::put($filename, $img_data);
                        //校正  图片
                        if($type == 'jpg'){
                            //本地图片地址
                            $localName ="./upload/images/base64/tmp/wxupload_".time().rand(1111,9999).".jpg";
                            //调用
                            $new_filename = C('file_url').$filename;
                            $res = $this->imgReverse($new_filename,$localName);
                            if($res){
                                //校正成功   重新上传oss图片
                                $filename = "upload/images/base64/".date("Y/m/d",time());
                                $filename .= "/upload_".time().rand(1111,9999).".".$type;

                                Storage::put($filename,file_get_contents($localName));
                            }

                        }

                        $imgurl = C('file_url').$filename;
                        $img_arr[$key] = $imgurl;
                    }
                }
                $img_str = implode('#',$img_arr);

            }else{
                //不是文件流  直接返回
                $img_str = $base64_data;
            }

            return $img_str;

        }


        /*
         * ios 拍照上传  图片反转   矫正
         * @param   string
         */
        public function imgReverse($image,$filename){
           //从 JPEG 或 TIFF 文件中读取 EXIF 头信息   (数码相机元数据)
            $exif = exif_read_data($image);
           //从字符串中的图像流新建一图像
            $data = imagecreatefromstring(file_get_contents($image));
           //图片旋转
            if(!empty($exif['Orientation'])) {
                switch($exif['Orientation']) {
                    case 8:
                        $data = imagerotate($data, 90, 0);
                        break;
                    case 3:
                        $data = imagerotate($data, 180, 0);
                        break;
                    case 6:
                        $data = imagerotate($data, -90, 0);
                        break;
                }
                $dir         =  dirname($filename);
                if(!is_dir($dir)){
                    mkdir($dir,0777,true);
                }
               //校正后的图片  返回资源
                $res = imagejpeg($data,$filename);
                if($res){
                    return true;
                }else{
                    return false;
                }
            }else{
               return false;
            }
        }

没有废话,直接代码,有点猛。。。。。。

 

修订(2019-04-08):因为后端校正图片,必须要获取  Orientation 属性,否则盲目的校正方向,必然会导致冤假错案,正常的图片也被处理为异常图片了。但是,某些图片在前端传给后端的时候,因不是原图,导致不存在该元素了。那么就绕过了校正操作,导致图片未处理。此时,需要前端校正处理。(如果前端OSS自传,更需要前端校正图片了,不要问我为什么)

function selectFileImage(fileObj) {

        //图片方向角 added by lzk
        var Orientation = null;

        file = fileObj;

            // 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 base64 = null;
                    //修复ios
                    if (navigator.userAgent.match(/iphone/i)) {
                        //console.log('iphone');
                        //alert(expectWidth + ',' + expectHeight);
                        //如果方向角不为1,都需要进行旋转 added by lzk
                        if(Orientation != "" && Orientation != 1){
                            //alert('旋转处理');
                            switch(Orientation){
                                case 6://需要顺时针(向左)90度旋转
                                    //alert('需要顺时针(向左)90度旋转');
                                    rotateImg(this,'left',canvas);
                                    break;
                                case 8://需要逆时针(向右)90度旋转
                                    //alert('需要顺时针(向右)90度旋转');
                                    rotateImg(this,'right',canvas);
                                    break;
                                case 3://需要180度旋转
                                    //alert('需要180度旋转');
                                    rotateImg(this,'right',canvas);//转两次
                                    rotateImg(this,'right',canvas);
                                    break;
                            }
                        }

                        base64 = canvas.toDataURL("image/jpeg", 0.8);
                    }else{
                        //alert(Orientation);
                        if(Orientation != "" && Orientation != 1){
                            //alert('旋转处理');
                            switch(Orientation){
                                case 6://需要顺时针(向左)90度旋转
                                   // alert('需要顺时针(向左)90度旋转');
                                    rotateImg(this,'left',canvas);
                                    break;
                                case 8://需要逆时针(向右)90度旋转
                                    //alert('需要顺时针(向右)90度旋转');
                                    rotateImg(this,'right',canvas);
                                    break;
                                case 3://需要180度旋转
                                    //alert('需要180度旋转');
                                    rotateImg(this,'right',canvas);//转两次
                                    rotateImg(this,'right',canvas);
                                    break;
                            }
                        }

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

                        //console.log(base64);
                    }
                    //uploadImage(base64);
                    //$("#myImage").attr("src", base64);
                    //return base64;

                    if(imgArr.length == 0){
                        imgArr[0] = 'http://static.img**.cn/image/microVoting/uploadBtn.png';
                    }
                    if(file.size/1024 > 200) {

                        smallImg(base64, function(newurl) {
                            imgArr.push(newurl);
                            change();
                        })
                    } else {
                        imgArr.push(base64);
                        change();
                    }
                };
            };
            oReader.readAsDataURL(file);
    }

    //对图片旋转处理 added by lzk
    function rotateImg(img, direction,canvas) {
        //alert(img);
        //最小与最大旋转方向,图片旋转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 = 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;
        }
    }