文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript如何实现获取图片文件真实格式

2023-07-05 05:00

关注

这篇文章主要介绍“JavaScript如何实现获取图片文件真实格式”,在日常操作中,相信很多人在JavaScript如何实现获取图片文件真实格式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaScript如何实现获取图片文件真实格式”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

常见方式判断图片格式

当我们进行前端开发,需要处理图片上传功能,针对图片格式做判断时,常规的方法都是使用文件后缀名来判断,如下代码所示:

input.addEventListener('change', (e) => {  const file = e.target.files[0]  const format = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()}, false)

以上代码,监听上传控件的事件,得到要上传的文件信息,获取文件名称,然后通过获取文件名称截取文件后缀名,以后缀名作为图片文件的格式。

这段代码,大部分人都比较熟悉,也有很多场景下是这样来判断图片格式的,但如果我们强行修改了文件的后缀名,则此方法就失效了。

我们知道gif格式图片的位深度是8,如果我们强制把位深度为32的png格式的图片后缀名改成gif,这个图片文件依然可以正常使用:

JavaScript如何实现获取图片文件真实格式

上图所示,就是将png格式文件后缀名改成了gif,图片系统信息显示格式为gif,但是位深度还是32,图像本质上还是png格式的。

这个时候,单纯的通过后缀名来判断图片的格式,就不再准确了,我们需要另外的方式来获取图片文件的真实格式。而这种方式就需要使用到前端二进制相关的知识,见前文介绍深入理解前端字节二进制知识以及相关API。

修改后缀名的方式

图像数据简单说明

不同格式的图像所存储的数据是不一样的,都有自己特殊的数据结构。

依据各个格式图像不同的数据结构,我们通过类型数组中的图像数据,就能判断出图片的真实格式。

针对不同位图的的数据判断,可以使用下面表格列出的方式:

格式标识的字节数对应的十进制值偏移量
jpg3255 216 2550
png8137 80 78 71 13 10 26 100
gif371, 73, 700
webp487, 69, 66, 808
ico40, 0, 1, 00
bmp266 770

其中,偏移量为0,表示取最前面几个字节的数据;webp的偏移量为8,表示从最前面移动8个字节后,再取4个字节的标识符。

上面的表格,已经列出了当前浏览器支持的位图图像,字节判断标识,通过读取相应的数据做对比就得到了真实的格式。

以上几种格式中,bmp、gif、webp取到的数据,都能对应各自特有的署名标识,前面有提到 BMWEBP,gif格式的则是 GIF。可以运用字符编码方面的知识,如使用 String.fromCharCode 方法对数值进行转换,具体的前端字符编码知识见前文前端开发中需要搞懂的字符编码

// bmpString.fromCharCode(66) // BString.fromCharCode(77) // M// gifString.fromCharCode(71) // GString.fromCharCode(73) // IString.fromCharCode(70) // F// webpString.fromCharCode(87) // WString.fromCharCode(69) // EString.fromCharCode(66) // BString.fromCharCode(80) // P

gif格式的署名标识是和版本号一起处理的,一般最前面6个字节标识: 'G'、'I'、'F'、'8'、'7(9)'、'a'。第5个字节可取值7或者9,代表两个不同的版本,即1987年的版本和1989年的版本。

JS读取图片真实格式

当我们了解了前端二进制相关的知识后,就应该知道图片文件也是能通过WebAPI对象,读取到对应的数据:

const reader = new FileReader()reader.onload = () => {  const imgArrayBuffer = reader.result  const imgUint8Array = new Uint8Array(imgArrayBuffer)}reader.readAsArrayBuffer(file)

以上代码,就是通过 FileReader 对象读取文件的数据,这里是作为 ArrayBuffer 来读取的,然后就可以转换成类型数组进行处理了。

读取到图片文件的 Uint8Array 类型数组数据后,根据上文表格中提到的格式字节数据标识,我们以jpg、bmp和webp为例:

imgUint8Array[0] === 66 && imgUint8Array[1] === 77 // bmp 格式imgUint8Array[0] === 255 && imgUint8Array[1] === 216 && imgUint8Array[3] === 255 // jpg 格式imgUint8Array[8] === 87 && imgUint8Array[9] === 69 && imgUint8Array[10] === 66 && imgUint8Array[10] === 80 // webp 格式

到此,就可以使用这种方式来读取到图片的真实格式,部分判断代码如下:

// 各格式对应图像数据的标识数值const IMAGEFORMATS = [  { ext: 'png', data: [137, 80, 78, 71, 13, 10, 26, 10] },  { ext: 'jpg', data: [255, 216, 255] },  { ext: 'gif', data: [71, 73, 70] },  { ext: 'ico', data: [0, 0, 1, 0] },  { ext: 'bmp', data: [66, 77] },  { ext: 'webp', data: [87, 69, 66, 80], offset: 8 }]// 循环判断文件是否符合某个格式对应的标识数值for (let i = 0; i < IMAGEFORMATS.length; i++) {  const { data, offset, ext } = IMAGEFORMATS[i]  if (isEqualFormatPrefix(imgUint8Array, data, offset)) {    return ext  }}

不过以上的方式主要是针对位图,如果是svg的图片,则会稍微复杂一些,需要另行处理。

svg格式的判断

svg格式图片是矢量图,对应的数据一般使用 xml 标记语言进行描述,所以我们读取到图像数据后,需要对应的标识署名是 <svg,如果对应的图像数据中拥有该标识,则大致可以判定为svg格式的图片。

<svg标识有4个符号和字母,对应的数值:60, 115, 118, 103,接下来我就需要判断图像文件是否有同样的数据了。

imgUint8Array[0] === 60 && imgUint8Array[1] === 115 && imgUint8Array[3] === 118 && imgUint8Array[3] === 103 // svg 格式

以上代码就是简单的判断svg格式了。

但是,我们一般的svg图片,图像数据最开始是包含有xml标记语言的 <?xm 标签,这个时候我们根据格式再判断:

if (isEqualFormatPrefix(fileUint8Array, [60, 63, 120, 109], offset)) { // 判断是否以 <?xm 开头  if (isHasSignCodes(fileUint8Array, [60, 115, 118, 103])) { // 判断是否包含 <svg 标签    return'svg'  }}

注意:以上针对svg格式矢量图的这种判断方式,是以 xml 标记语言的标签符号进行判断的,只能处理通过更改后缀名的方式伪造的图片文件。当我们伪造一个假的文件,包含有 <svg 标签标识时,则可以逃避这种判断。

到此,关于“JavaScript如何实现获取图片文件真实格式”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯