前言
当你通过网页上的输入标签在手机上拍照上传图片时,有些手机会出现图片旋转90度D的问题,包括iPhone和个别三星手机。这个问题只有在这些手机垂直拍摄,水平拍摄的照片正常显示时才会出现。因此,这个问题可以通过获取手机的摄像头角度来旋转照片来解决。
方向
不是所有的图片都有这个参数,但是手机拍摄的图片有这个参数。
当旋转角度的参数值为0 1顺时针90 6逆时针90 8 180 3时,显示正常,那么在水平拍显示正常的手机上,垂直拍的参数为6,即Orientation=1。
要获取Orientation参数,可以通过exif.js库进行操作。Exif.js功能多,体积大,压缩前是30k,对手机页面的加载影响很大。而且我只需要获取Orientation信息,所以我在这里剪切了exif.js库的一些代码,将代码减少到了几KB。
Exif.js获取方向:
EXIF.getData(file,function(){ var Orientation=EXIF . gettag(this,' Orientation ');});文件是由输入文件表单上传的文件。上传的文件可以通过fileReader.readAsDataURL(文件)预览图片。如果这方面不清楚,可以查看:HTML5高级系列:文件上传下载
循环
旋转需要画布的rotate()方法。
ctx.rotate(角度);rotate方法的参数是旋转的弧度。角度需要转换成弧度:度*数学。PI/180
默认情况下,旋转的中心点位于画布的起点,即(0,0)。旋转的原理如下:
旋转后,如果drawImage()是从(0,0)点开始执行的,则绘制的位置是在左侧图片中旋转90度的位置,而不是在可见区域中。旋转之后,坐标轴也会旋转。如果要在可视区域显示,需要将(0,0)点向Y轴相反方向移动Y个单位,此时的起点为(0,-y)。
同样可以得到旋转-90度后的起点为(-x,0),旋转180度后的起点为(-x,-y)。
压缩
手机拍摄的照片太大,base64编码的照片会比原照片大,上传时需要压缩。现在手机的像素很高,拍出来的照片宽度和高度都是几千像素,所以用画布渲染照片的速度会比较慢。
因此,第一步是限制上传照片的宽度和高度,并判断宽度或高度是否超过哪个范围,然后按等比压缩宽度和高度。
var比率=宽度/高度;if(IMgwidth IMgheight IMgwidth xx){ IMgwidth=xx;imgHeight=math . ceil(xx/ratio);} else if(imgWidth imgHeight imgHeight YY){ imgWidth=math . ceil(YY * ratio);imgHeight=yy}第二步是通过canvas.toDataURL()压缩照片质量。
canvas . todaytaul(' image/JPEG ',1);toDataURL()方法返回包含图片演示的数据URI。使用两个参数,第一个参数是图像格式,默认是image/png。第二个参数是压缩质量。当指定的图像格式为image/jpeg或image/webp时,图像质量可以从0到1选择。
摘要
综上所述,示例代码包括简化的exif.js库地址:file-demo
主要核心代码如下:
输入类型=' file ' id=' files ' img src=' http : blank。gif ' id=' preview '脚本src=' http 3360 small-EXIF。js '/script脚本var ipt=document。getelementbyid(' files '),img=document。getelementbyid(' preview '),Orientation=nullipt。onchange=function(){ var file=ipt。文件[0],阅读器=新文件阅读器(),图像=新图像();if(file){ EXIF.getData(file,function(){ Orientation=EXIF。gettag(这是“方向”);});读者。onload=function(ev){ image。src=ev。目标。结果;图像。onload=function(){ var imgWidth=this。宽度,imgHeight=this.height//控制上传图片的宽高if(imgWidth imgHeight imgWidth 750){ imgWidth=750;imgHeight=数学。天花板(750 *这个。身高/这个。宽度);} else if(IMgwidth IMgheight IMgheight 1334){ IMgwidth=math。天花板(1334 *这个。宽度/这个。高度);imgHeight=1334 } var canvas=document。创建元素(“画布”),CTX=画布。get context(' 2d ');canvas . width=IMgwidthcanvas . height=IMGheight如果(方向方向!=1){开关(方向){外壳6: //旋转90度canvas . width=IMGheightcanvas . height=IMgwidth旋转(数学/2);//(0,-imgHeight)从旋转原理图那里获得的起始点ctx.drawImage(this,0,-imgHeight,imgWidth,imgHeight);打破;第3: //旋转180度旋转(数学. PI);ctx.drawImage(this,-imgWidth,-imgHeight,imgWidth,imgHeight);打破;第8: //旋转-90度canvas . width=IMGheightcanvas . height=IMgwidth旋转(3 *数学/2);ctx.drawImage(this,-imgWidth,0,imgWidth,imgHeight);打破;} }else{ ctx.drawImage(this,0,0,imgWidth,imgHeight);} img。src=画布。todaytaul(' image/JPEG ',0.8);} } reader.readAsDataURL(文件);} }/脚本