欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

iOS和小米手机拍照上传后,在web端显示旋转

程序员文章站 2022-05-23 19:16:37
( ′◔ ‸◔`)现在的公司啊都流行混合开发,我们公司也不例外,非要把交互非常多的社区模块用内嵌web页展示,好吧好吧,毕竟有的应用也是这么做的,那既然是社区就肯定少不了用户上传图片的操作,在开发阶段没有发现任何问题,也是很奇怪,等到了测试阶段,发现部分机型和IOS机型拍照之后,web页获取路径之后 ......

( ′◔ ‸◔`)现在的公司啊都流行混合开发,我们公司也不例外,非要把交互非常多的社区模块用内嵌web页展示,好吧好吧,毕竟有的应用也是这么做的,那既然是社区就肯定少不了用户上传图片的操作,在开发阶段没有发现任何问题,也是很奇怪,等到了测试阶段,发现部分机型和ios机型拍照之后,web页获取路径之后展示的图片和图片文件全不是正确的方向,旋转了90°、180°的都有,于是去网上查找原因,结果就是……

大于2m的图片!并且是竖拍的图片!在生成照片的时候图片的orientation属性会被重写!!!!所以部分机型和ios 都会出现旋转的问题!

可恶!

当然方法也百度到了,只不过大部分都是只放了代码,并没有讲解,其实理解了也非常简单。

一、安装插件 ︶︿︶

解决这个问题首先是要借助插件的,因为我们前端旋转了图片只是在页面上看上去旋转了,并没有解决根本问题,于是就要用到 exif.js这个工具。

一个强大的读取图片数据的工具,安装也很简单文档里也有,就不多说了,因为我使用的是vue,所以之间npm安装后在需要使用的页面引入:

import exif from "exif-js";

到这里就算完成了插件的全部安装;

二、开工!(^-^)v

首先在选择框的change事件中我们直接调用exif的方法;

let orientation = 0;
exif.getdata(e.target.files[0], function() {
    exif.getalltags(this);
    orientation = exif.gettag(this, 'orientation');
});
//e.target.files[0]为获取的第一个图片文件,如果是多个图片文件可进行遍历

这时候我们就已经获取到图片的orientation属性了,这个属性就是图片的方向属性,不同的值代表不同的方向:

图片正常 1
图片朝右 6
图片朝左 8
图片倒置 3

后来经过测试orientation还会有一个值,就是0,当orientation等于0的时候图片是正常的,但0代表的意思,还没有找到。

那么现在就可以对图片进行处理了let canvas = document.createelement("canvas");

let ctx = canvas.getcontext("2d");
let width = img.width;
let height = img.height;
switch(orientation) {
    case 0:
        //不做任何处理直接画图
        canvas.width = width;
        canvas.height = height;
        ctx.drawimage(img, 0, 0)
        break;
    case 1:
        //不做任何处理直接画图
        canvas.width = width;
        canvas.height = height;
        ctx.drawimage(img, 0, 0)
        break;
    case 6:
        //图片顺时针旋转90°
        canvas.height = width;
        canvas.width = height;
        ctx.rotate(math.pi / 2);
        ctx.translate(0, -height);
        ctx.drawimage(img, 0, 0)
        break;
     case 3:
        //图片旋转180°
        canvas.height = height;
        canvas.width = width;
        ctx.rotate(math.pi);
        ctx.translate(-width, -height);
        ctx.drawimage(img, 0, 0)
        break;
     case 8:
        //图片逆时针旋转90°
        canvas.height = width;
        canvas.width = height;
        ctx.rotate(-math.pi / 2);
        ctx.translate(-height, 0);
        ctx.drawimage(img, 0, 0)
        break;
     case undefined:
        //不作任何处理直接画图
        canvas.width = width;
        canvas.height = height;
        ctx.drawimage(img, 0, 0)
        break;    
}      
let ndata=canvas.todataurl("image/jpeg", 1);

这里图片的处理就是把图片原原本本的在canvas上画一遍,然后把它转成正确的方向就可以了,那么缩略图就可以直接展示ndata就可以了。

但是这里还只是一张图片,我们不可能给后台传图片base64码过去,必须是图片文件才可以,那么这里就要用到base64的转码。

首先是base64转码函数的封装:

    // base64转成bolb对象
      datauritoblob(base64data) {
        let bytestring;
        if(base64data.split(",")[0].indexof("base64") >= 0)
          bytestring = atob(base64data.split(",")[1]);
        else bytestring = unescape(base64data.split(",")[1]);
        let mimestring = base64data
          .split(",")[0]
          .split(":")[1]
          .split(";")[0];
        let ia = new uint8array(bytestring.length);
        for(let i = 0; i < bytestring.length; i++) {
          ia[i] = bytestring.charcodeat(i);
        }
        return new blob([ia], {
          type: mimestring
        });
      },

然后将上面我们转换好的ndata通过base64转换成图片文件就可以了。

//调用转换函数将base64码转换成图片文件
let blob = this.datauritoblob(ndata);
//将新文件名与原图片文件保持一致
blob.name = e.target.files[0].name;
//将新文件放到我们需要传给后台的文件数组里
this.files.push(blob);

 

三、结束o(゚д゚)っ

以上就是对图片旋转做的处理,很简单,我们就可以理解为图片的重绘。当然上面的方法只是单个图片的转换,如果用户同时上传了多个图片,那么就在对应的地方添加遍历循环就可以了。

如果有不足的地方希望大家补充,有不对的地方也请大家批评指正。

如果还不太明白也可以通过我的联系方式进行讨论。