IOS照片为何在web中展示出来是旋转90度的,通过js可以实现旋转图像

IOS中的拍照时,相机有4种不同的放置方法,不管你的相机如何放置,拍出来的照片从数据上来说都是一个方向的(横向)。把你的手机逆时针旋转90度(横向拿),这个方向就是相机的原始视角。你从任何其他3个视角拍出的照片的数据其实都是和原始视角一样的,只是在文件中做了个关于视角的标记。在程序需要展示照片时,需要根据这个标志来翻转图像。

假如你是竖向拍的照片,对相机来说,就是等于把头向右侧歪成水平,再拍照。它眼里看到的世界是逆时针转了90度的。要把相机里的图像转成人看到的视角,就要顺时针旋转90度。

一、实现图像转换的步骤:

1. 在js中,可以通过EXIF图像库获取image的旋转角度,

EXIF.getData(image, function () {
var orient = EXIF.getTag(this, ‘Orientation’);

});

2. 把image 顺时针旋转一定度数画到 canvas上

iphone拍照分辨率太大,一般需要缩小图片,在canvas上画image的时候可以按比例缩小画。
iphone新出的手机长宽比太大,长长的图片有时不好看,需要把上方和下方剪去一部分。

          var canvas = document.createElement('canvas');
             var ctx = canvas.getContext("2d");
               var cutHt = (ht - keepHt) / 2;//计算上下切去高度
               canvas.height = keepHt; 
                 ctx.rotate(degree);//顺时针旋转一定角度
               //注意: ctx.rotate(degree);必须在canvas的大小设定好之后再旋转,否则会形成黑屏图片*
                 ctx.translate(-cutHt, 0); 
                 //translate 将整个画面移向左动cutHt
                 ctx.drawImage(image, cutHt / bl, 0, keepHt / bl, height, cutHt, 0, keepHt, -wd);
                 //-wd 是绘制的高度,这里为负数不太好理解。高度为正的情况下,是画在横坐标轴下方的,高度为负时画在上方。宽度为正画在纵坐标轴右侧,为负数时在左侧。
3.然后再把canvas生成图像,这样就完成了格式的转换。

canvas.toBlob(callback, “image/jpeg”, resolution); // get the data from canvas as 70% JPG

二、完整代码


    function resizeImage(blob, max_width, max_height, resolution, callback) {
        window.URL = window.URL || window.webkitURL;
        var blobURL = window.URL.createObjectURL(blob); // and get it's URL

        // helper Image object
        var image = new Image();
        image.src = blobURL;
       
        image.onload = function () {
            // have to wait till it's loaded
            // var resized = resizeMe(image); // send it to canvas
            EXIF.getData(image, function () {
                //EXIF.getAllTags(this);
                var orient = EXIF.getTag(this, 'Orientation');
                var canvas = document.createElement('canvas');
                // resize the canvas and draw the image data into it

                var ctx = canvas.getContext("2d");
                var width = image.width;
                var height = image.height;
                var wd = width, ht = height;
                var degree = 0;
                var step = 0;
                if (navigator.userAgent.match(/iphone/i)) {
                    if (orient !== "" && orient !== 1) {
                        switch (orient) {
                            case 6://需要顺时针(向左)90度旋转   
                                //rotateImg(this, 'left', canvas);
                                step = 1;
                                ht = width;
                                wd = height;
                                break;
                            case 8://需要逆时针(向右)90度旋转   
                                step = 3;
                                ht = width;
                                wd = height;
                                break;
                            case 3://需要180度旋转   
                                // rotateImg(this, 'right', canvas);//左转两次  
                                // rotateImg(this, 'right', canvas);
                                step = 2;
                                break;
                        }
                    }
                }
                degree = step * 90 * Math.PI / 180;
                var wl = max_width / wd, hl = max_height / ht;
                var bl = wl < hl ? wl : hl;
                ht = Math.round(ht * bl); wd = Math.round(wd * bl);
                canvas.width = wd; canvas.height = ht;
                //ctx.rotate(degree);//anti clock
                var maxHtBl = 1.1;
                if (step === 1) { 
                    if (ht / wd > maxHtBl) {
                        var keepHt = wd * maxHtBl;
                        var cutHt = (ht - keepHt) / 2;
                        canvas.height = keepHt;
                        ctx.rotate(degree);//this should be always after setting the height
                        ctx.translate(-cutHt, 0); 
                        ctx.drawImage(image, cutHt / bl, 0, keepHt / bl, height, cutHt, 0, keepHt, -wd);
                    }
                    else {
                        ctx.rotate(degree);
                        ctx.drawImage(image, 0, 0, ht, -wd);
                    }
                        
                }
                else if (step === 2) {
                    ctx.rotate(degree);
                    ctx.drawImage(image, 0, 0, -wd, -ht);
                }
                else if (step === 3) {
                    ctx.rotate(degree);
                    ctx.drawImage(image, 0, 0, -ht, wd);
                }
                else if (step === 0) {
                    if (ht / wd > maxHtBl) {
                        var keepHt = wd * maxHtBl;
                        var cutHt = (ht - keepHt) / 2;
                        canvas.height = keepHt; 
                        //ctx.translate(0,-cutHt);
                        ctx.drawImage(image, 0, cutHt / bl, width, keepHt / bl, 0, 0,wd, keepHt);
                    }
                    else ctx.drawImage(image, 0, 0, wd, ht);
                }
                canvas.toBlob(callback, "image/jpeg", resolution); // get the data from canvas as 70% JPG    
            });
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值