html图片加载原理,关于html加载照片方向问题的研究

目录

问题描述

了解手机拍摄方向

关于照片的EXIF信息

html如何加载图片

遇到这种问题我们如何解决?

解决思路

exif.js的使用

1. 先引用js文件

2. 使用方法获得对应img图片的exif信息

3. 根据Orientation的值不为6,判断需要进行旋转,使用css进行相应的

旋转exif.js原理思路

一些专有名词?

ArrayBuffer?

DataView?

问题描述

这个问题之所以不常发现,是因为我们很少加载手机拍摄的图片,更少加载图片被人为旋转过的图片。

在我们加载图片的时候,浏览器有时候加载带有旋转信息的图像文件的时候方向有旋转的偏差,下面就是深度剖析一下这个问题和解决方案。

了解手机拍摄方向

一张图带你了解手机拍摄方向和在手机系统中呈现的样式。

97d517ba9145

手机拍摄方向.png

这些照片拍出来,不管呈现是不是正的,EXIF里面的旋转信息都为1,表示正方向。

可以看出来,

如果是垂直方向拍出来的,会根据横向纵向进行方向的调整。

如果是水平方向拍出来的,因为无法判断手机的方向,所以拍的总是按照横短竖长为正方向。

关于照片的EXIF信息

Exif就是用来记录拍摄图像时的各种信息:

图像信息(厂商,分辨率等)

相机拍摄记录(ISO,白平衡,饱和度,锐度等)

缩略图(缩略图宽度,高度等)

gps(拍摄时的经度,纬度,高度)等

将这些信息按照JPEG文件标准放在图像文件二进制流的头部。

html如何加载图片

那么一个图片如何加载的呢?上面的图片使用了

+backgroundImage和+src两种方式渲染。

97d517ba9145

浏览器正常加载图片.png

可以看出来,渲染的效果和手机刚拍摄的展示的效果是一样的。

那么我们现在,点击图片右键将图片进行旋转。再看效果。

97d517ba9145

向右旋转.png

第一张照片顺时针旋转一次

第二张照片顺时针旋转两次

第三张照片顺时针旋转一次

第四张照片逆时针旋转一次

97d517ba9145

旋转之后的图片方向.png

这个时候,发现加载的方向依旧和没有旋转过是一样的。 (为了避免是没刷新啥的,我还修改了一下样式)

97d517ba9145

旋转之后没有任何变化.png

然后我们再将图片使用图片工具打开,进行旋转保存,查看效果。

97d517ba9145

使用照片编辑器编辑图片.png

97d517ba9145

使用画板编辑图片.png

然后在浏览器展示看,发现浏览器加载的图片进行了旋转

97d517ba9145

旋转之后没有任何变化.png

可以看出来,在html进行加载的时候,根据不同的渲染方式,会有不一样的展示。原因是什么呢?

使用电脑右键的旋转或者手机直接旋转

只是更改了图像附加的EXIF的一些旋转信息,本身图片的元数据并没有进行改变。

使用图画工具或者照片编辑器进行旋转保存

会直接更改图片的元数据,并将当前的EXIF旋转信息置为正方向。

浏览器会根据图片本身的元数据进行渲染。会忽略EXIF里面的旋转信息Orientation,永远展示的是Orientation为1的方向。

遇到这种问题我们如何解决?

解决思路

只要我们可以获取到图片本身的信息,就可以对其方向进行判断了。 但是本身文件并没有给我们暴露那些接口获取信息,使用原生方法比较复杂。 还好的是有一个插件exif.js 解决了这个问题。

exif.js的使用

1. 先引用js文件

2. 使用方法获得对应img图片的exif信息

EXIF.getData(document.getElementById('img'), function(){

EXIF.getAllTags(this); //获取所有信息,以对象形式返回

EXIF.getTag(this, 'Orientation') //获取图像的Orientation指定属性值

EXIF.pretty(this); //获取所有信息,以字符串形式返回

});

3. 根据Orientation的值不为6,判断需要进行旋转,使用css进行相应的旋转

根据值的不同做不同的旋转

97d517ba9145

exif-orientation说明.png

参数

0行(未旋转上)

0列(未旋转左)

旋转(方法很多)

1

2

水平翻转

3

180°

4

垂直翻转

5

顺时针90°+水平翻转

6

顺时针90°

7

顺时针90°+垂直翻转

8

逆时针90°

exif.js原理思路

首先定义了一套16进制数据对应的种类标记,已经种类对应的值的含义

97d517ba9145

EXIF tags.png

根据图片的加载途径不同,殊途同归的转化成ArrayBuffer对象,并创建一个DataView对象进行操作。

97d517ba9145

exif流程图.png

根据一套规则去解析ArrayBuffer对象

先判断其是不是jpeg图片文件(照片只存储jpg格式,不存储png格式,所以不需要进行png文件的考虑)

二进制文件通过文件头识别文件类型

jpeg的头文件标识是(0xFF, 0xD8),这是JPEG协议规定的

用16进制转化为10进制为(255,216),如果是jpeg文件我们就进行下一步解析。

97d517ba9145

二进制文件类型.png

然后找到对应的Exif字母标记,找到开始读取信息

匹配上面的键值对,进行配对输出。

97d517ba9145

最终输出exif对象.png

一些专有名词?

ArrayBuffer?

97d517ba9145

arrayBuffer.png

ArrayBuffer 对象 用来表示通用的、固定长度的原始二进制数据缓冲区。

根据不同的类型进行区分

Uint8Array是无符号八进制数组

Int8Array是有符号八进制数组

Int16Array是有符号16进制数组。

其中ArrayBuffer对象不能直接操作,原型链上也没有暴露的方法,所有只能通过类型数组对象或DataView对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

DataView?

97d517ba9145

dataView.png

DataView对象用于呈现指定的缓存区数据,可以认为是一个二进制解释器,下面的不同的方法,就是根据不同的位数去取数据进行解析。

var buffer = new ArrayBuffer(16);

var dv = new DataView(buffer);

dv.setInt16(0, 42);

dv.getInt16(0); //42

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值