美文网首页
web中图片被自动旋转了,怎么解决

web中图片被自动旋转了,怎么解决

作者: 摩登开发者Oliver | 来源:发表于2020-04-15 16:27 被阅读0次

    先看个案例:


    web站上图片被旋转90度
    打开图片连接可以查看到原图是横向的
    很多人会遇到这样的问题,一张背景图片或者img标签图片没有任何角度相关的样式,图片却被旋转了90度或者180度,然后疯狂查看代码依然找不到原因,其实这是部分图片由于拍摄时候保存了exif信息。

    什么是EXIF
    简单来说,Exif 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,它就好像是傻瓜相机的日期打印功能一样,只不过 Exif信息所记录的资讯更为详尽和完备。Exif 所记录的元数据信息非常丰富,主要包含了以下几类信息:

    • 拍摄日期
    • 摄器材(机身、镜头、闪光灯等
    • 拍摄参数(快门速度、光圈F值、ISO速度、焦距、测光模式等
    • 图像处理参数(锐化、对比度、饱和度、白平衡等)
    • 图像描述及版权信息
    • GPS定位数据
    • 缩略图
      这里面就包含了图片的角度信息,就是说你用手机拍照时是不是倒着拍还是侧着拍,这些都是有记录的。

    有几种方式去解决这个问题

    一、后端可以利用php的exif扩展中的函数exif_read_data()去做,具体操作可以只行百度,不做详细描写。

    二、js

    // 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64
    // 步骤一
    // base64转ArrayBuffer对象
      function base64ToArrayBuffer(base64) {
        base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
        var binary = atob(base64);
        var len = binary.length;
        var buffer = new ArrayBuffer(len);
        var view = new Uint8Array(buffer);
        for (var i = 0; i < len; i++) {
          view[i] = binary.charCodeAt(i);
        }
        return buffer;
      }
    // 步骤二,Unicode码转字符串
    // ArrayBuffer对象 Unicode码转字符串
      function getStringFromCharCode(dataView, start, length) {
        var str = '';
        var i;
        for (i = start, length += start; i < length; i++) {
          str += fromCharCode(dataView.getUint8(i));
        }
        return str;
      }
     
    // 步骤三,获取jpg图片的exif的角度(在ios体现最明显)
      function getOrientation(arrayBuffer) {
        var dataView = new DataView(arrayBuffer);
        var length = dataView.byteLength;
        var orientation;
        var exifIDCode;
        var tiffOffset;
        var firstIFDOffset;
        var littleEndian;
        var endianness;
        var app1Start;
        var ifdStart;
        var offset;
        var i;
        // Only handle JPEG image (start by 0xFFD8)
        if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
          offset = 2;
          while (offset < length) {
            if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
              app1Start = offset;
              break;
            }
            offset++;
          }
        }
        if (app1Start) {
          exifIDCode = app1Start + 4;
          tiffOffset = app1Start + 10;
          if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
            endianness = dataView.getUint16(tiffOffset);
            littleEndian = endianness === 0x4949;
     
            if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
              if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
                firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
     
                if (firstIFDOffset >= 0x00000008) {
                  ifdStart = tiffOffset + firstIFDOffset;
                }
              }
            }
          }
        }
        if (ifdStart) {
          length = dataView.getUint16(ifdStart, littleEndian);
     
          for (i = 0; i < length; i++) {
            offset = ifdStart + i * 12 + 2;
            if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
     
              // 8 is the offset of the current tag's value
              offset += 8;
     
              // Get the original orientation value
              orientation = dataView.getUint16(offset, littleEndian);
     
              // Override the orientation with its default value for Safari (#120)
              if (IS_SAFARI_OR_UIWEBVIEW) {
                dataView.setUint16(offset, 1, littleEndian);
              }
              break;
            }
          }
        }
        return orientation;
      }
    

    方法getStringFromCharCode(arrayBuffer)返回的orientation就是图片的方向也就是旋转的值,再对应下面的表,对图片进行处理

    orientation值表

    大家可以先判断图片Exif的orientation值再根据上表对应的旋转值,在canvas上对图片进行反方向旋转消除影响

    三、Photoshop另存图片

    如果图片是单独的一张或者是固定的又或者不是后台返回的,可以通过photoshop重新保存,保存的时候去掉exif信息

    四、vue中安装exif插件就可以获取Orientation参数然后做调整就可以了

    这里有我自己项目上传照片时的处理代码:

    import EXIF from 'exif-js'
    
    selectPhoto(e) {
                this.uploadImgClass = '';
                if (e.target.files[0].type.indexOf('image/') != 0) {
                    this.showTopTip('error', this.language.unify_errorFormatImgTip);
                    return false;
                }
                this.dialogData = {};
                let tthis = this,
                    reader = new FileReader();
                EXIF.getData(e.target.files[0], function() {
                    let Orientation = EXIF.getTag(this, 'Orientation');
                    if (Unit.inArray(Orientation, [3, 6, 8]) != -1) {
                        tthis.uploadImgClass = 'img rotate' + Orientation;
                    } else {
                        tthis.uploadImgClass = 'img';
                    }
                });
                if (e.target.files[0]) {
                    this.file = e.target.files[0];
                    e.target.value = ''; //clear file
                    reader.readAsDataURL(this.file);
                    reader.onload = function(e) {
                        tthis.uploadImg = this.result;
                        // tthis.text = tthis.language.unify_upload;
                        tthis.btn = true;
                        //get width&height
                        let img = new Image();
                        img.src = tthis.uploadImg;
                        img.onload = function() {
                            tthis.width = img.naturalWidth;
                            tthis.height = img.naturalHeight;
                        };
    
                    }
                }
            },
    

    我是定义了类名根据Orientation的值做了相应旋转

    这里的exif插件不只是可以用来获取信息还可以用来做摄像头实时拍照等功能,总的说来是很方便的

    文章部分内容引用https://www.mk2048.com/blog/blog.php?id=hbabci10jhaa

    相关文章

      网友评论

          本文标题:web中图片被自动旋转了,怎么解决

          本文链接:https://www.haomeiwen.com/subject/wbgcvhtx.html