背景

最近要做一个h5的页面,主要功能就是调用相机拍照或者是相册选图并且把照片压缩转base64之后上传到后台服务器,然后服务器返回识别结果。

前端的主要功能点有:

  1. H5如何调用相机
  2. 图片如何压缩
  3. 图片转base64

H5调用相机/相册

调用相机最简单的方法就是使用input file[camera]属性:

<       input               type       =       "file"               capture       =       camera               accept       =       "image/*"       >//相机      
       <       input               type       =       "file"               accept       =       "image/*"       >//相册

这个种方法兼容性还是有问题的,在iphone手机上可以正常打开相机,但是在安卓手机上点击之后是相机、图库、文件管理器等混合选择项。在网上搜了很多都没有什么好的解决办法,只能继续往下写了。。。

图片压缩

图片压缩就要用到FileReader<canvas>了。

FileReader对象允许Web应用程序异步读取存储在计算机上的文件的内容,使用File或Blob对象指定要读取的文件或数据。

<canvas>是一个可以使用脚本在其中绘制图形的HTML元素,可以绘制图形和简单的动画。

图片压缩要压缩图片的分辨率和质量,分辨率压缩我这里是设置了图片的最大边为800,另一边按照图片原有比例缩放,也可以设置图片整体的缩放比例。

var               MAX_WH=800;      
       var               image=       new               Image();      
       image.onload=       function               () {      
              if       (image.height > MAX_WH) {      
              // 宽度等比例缩放 *=      
              image.width *= MAX_WH/ image.height;      
              image.height = MAX_WH;      
              }      
              if       (image.width > MAX_WH) {      
              // 宽度等比例缩放 *=      
              image.height *= MAX_WH/ image.width;      
              image.width = MAX_WH;      
              }      
       }      
       image.src=dataURL;       //dataURL通过FileReader获取

然后就是压缩图片的质量了,这里设置压缩了80%,如果设置太小图片就失真了。动态创建<canvas>标签然后压缩图片:

var               quality=80;      
       var               cvs = document.createElement(       'canvas'       );      
       cvs.width = image.width;      
       cvs.heigh = image.height;      
       var               context=cvs.getContext(       "2d"       );      
       context.drawImage(image, 0, 0,image.width, image.height);      
       dataURL = cvs.toDataURL(       'image/jpeg'       , quality/100);

然后就是上传到服务器并展示服务器的结果啦,然而事情并没有那么顺利。。。ios手机拍照压缩之后图片莫名的旋转了,继续解决问题。

解决IOS图片旋转

首先引用exif.js,通过EXIF.getData和EXIF.getTag获取拍照方向信息。

//file通过input标签获取      
       EXIF.getData(file,       function       (){      
              orientation=EXIF.getTag(file,       'Orientation'       );      
       });

下面给出每个orientation值对应到iphone手机拍照的含义:

orientation

描述

3

iphone横屏拍摄,此时home键在左侧,图片相对于原始位置旋转了180度

6

iphone竖屏拍摄,此时home键在下方(正常拿手机的方向),图片相对于原始位置逆时针旋转可90度

8

iphone竖屏拍摄,此时home键在上方,图片相对于原始位置顺时针旋转了90度

获取图片的方向信息之后,根据获取到的值作相应的旋转操作。

switch               (orientation) {      
              case               6:      
              case               8:      
              cvs.width = height;      
              cvs.height = width;      
              break       ;      
       }      
       var context=cvs.getContext(       "2d"       );      
       switch       (orientation){      
              //iphone横屏拍摄,此时home键在左侧      
              case               3:      
              // 180度向左旋转      
              context.translate(width, height);      
              context.rotate(Math.PI);      
              break       ;      
              //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)      
              case               6:      
              context.rotate(0.5 * Math.PI);      
              context.translate(0, -height);      
              break       ;      
              //iphone竖屏拍摄,此时home键在上方      
              case               8:      
              // 逆时针旋转90度      
              context.rotate(-0.5 * Math.PI);      
              context.translate(-width, 0);      
              break       ;      
       }

然后再上传图片,发现在IOS下图片已经正常了。

下面给出完整代码:

$(       'input[type=file]'       ).change(       function       (e) {      
              var               file =        this       .files[0];      
              var               mime_type=file.type;      
              var               orientation=0;      
              if               (file && /^image\       //i.test(file.type)) {      
              EXIF.getData(file,       function       (){      
              orientation=EXIF.getTag(file,       'Orientation'       );      
              });      
              
              var               reader =        new               FileReader();      
              reader.onloadend =        function               () {      
              var               width,height;      
              var               MAX_WH=800;      
              var               image=       new               Image();      
              image.onload=       function               () {      
              if       (image.height > MAX_WH) {      
              // 宽度等比例缩放 *=      
              image.width *= MAX_WH / image.height;      
              image.height = MAX_WH;      
              }      
              if       (image.width > MAX_WH) {      
              // 宽度等比例缩放 *=      
              image.height *= MAX_WH / image.width;      
              image.width = MAX_WH;      
              }      
              //压缩      
              var               quality=80;      
              var               cvs = document.createElement(       'canvas'       );      
              cvs.width = width = image.width;      
              cvs.height =height = image.height;      
              
              switch               (orientation) {      
              case               6:      
              case               8:      
              cvs.width = height;      
              cvs.height = width;      
              break       ;      
              }      
              
              var               context=cvs.getContext(       "2d"       );      
              
              //解决ios图片旋转问题      
              switch       (orientation){      
              //iphone横屏拍摄,此时home键在左侧      
              case               3:      
              // 180度向左旋转      
              context.translate(width, height);      
              context.rotate(Math.PI);      
              break       ;      
              //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)      
              case               6:      
              context.rotate(0.5 * Math.PI);      
              context.translate(0, -height);      
              break       ;      
              //iphone竖屏拍摄,此时home键在上方      
              case               8:      
              // 逆时针旋转90度      
              context.rotate(-0.5 * Math.PI);      
              context.translate(-width, 0);      
              break       ;      
              }      
              context.drawImage(image, 0, 0,image.width, image.height);      
              dataURL = cvs.toDataURL(       'image/jpeg'       , quality/100);      
              //获取识别结果      
              ...      
              }      
              image.src=dataURL;      
              };      
              reader.readAsDataURL(file);      
              }       else       {      
              alert(       "只能识别图片!"       )      
              }      
       });

以上就是关于html5中如何调用相机拍照并且压缩图片的示例详解的详细内容