电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JavaScript實現獲取圖片文件真實格式的示例代碼

瀏覽:243日期:2022-06-01 09:14:35
目錄
  • 常見方式判斷圖片格式
  • 圖像數據簡單說明
  • JS讀取圖片真實格式
    • svg格式的判斷
  • 總結

    前面博文有提到,當前主流瀏覽器能支持的圖片格式,是七種:jpg、png、gif、bmp、ico、webp、svg,其中,前六種都是位圖,svg則是唯一的矢量圖。

    每種格式的圖片,都有自己特有的優缺點以及數據結構,本篇博文的目的就是基于不同格式的圖像二進制數據,獲取到圖片的真實格式。

    常見方式判斷圖片格式

    當我們進行前端開發,需要處理圖片上傳功能,針對圖片格式做判斷時,常規的方法都是使用文件后綴名來判斷,如下代碼所示:

    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,這個圖片文件依然可以正常使用:

    上圖所示,就是將png格式文件后綴名改成了gif,圖片系統信息顯示格式為gif,但是位深度還是32,圖像本質上還是png格式的。

    這個時候,單純的通過后綴名來判斷圖片的格式,就不再準確了,我們需要另外的方式來獲取圖片文件的真實格式。而這種方式就需要使用到前端二進制相關的知識,見前文介紹深入理解前端字節二進制知識以及相關API。

    修改后綴名的方式

    • 幾種位圖格式之間,是可以相互修改后綴名,圖片仍能正常使用
    • gif動圖后綴名改成其他位圖格式,則動效會失效,變成靜態圖
    • 位圖格式的后綴名如果改成矢量圖svg,則圖片失效,將無法使用
    • svg圖片文件后綴名改成位圖格式,圖片也將無法使用

    圖像數據簡單說明

    不同格式的圖像所存儲的數據是不一樣的,都有自己特殊的數據結構。

    依據各個格式圖像不同的數據結構,我們通過類型數組中的圖像數據,就能判斷出圖片的真實格式。

    • 如jpg格式,它的圖像數據結構中,最前面2個字節是一個固定取值 0xFFD8,第三個字節一般也是固定 0xFF
    • 如png格式,它的圖像數據結構中,最前面8個字節就是PNG文件署名域,可以很好的標識出當前圖像的格式就是PNG。
    • 如bmp格式,它的圖像數據結構中,最前面14個字節存儲的是文件頭信息,而最前面2個字節存儲的就是文件類型:BM
    • 如webp格式,需要從最前面移動8個字節以后,取接下來的4個字節的信息,代表文件類型:WEBP

    針對不同位圖的的數據判斷,可以使用下面表格列出的方式:

    格式標識的字節數對應的十進制值偏移量jpg3255 216 2550png8137 80 78 71 13 10 26 100gif371, 73, 700webp487, 69, 66, 808ico40, 0, 1, 00bmp266 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 標簽標識時,則可以逃避這種判斷。

    總結

    瀏覽器支持的圖片格式中,除了svg以外,其他幾種位圖格式,都可以較好的通過讀取圖像二進制數據的方式判斷出圖片文件的真實格式,能夠防止文件偽造繞開判斷,造成不必要的異常等問題。

    到此這篇關于JavaScript實現獲取圖片文件真實格式的示例代碼的文章就介紹到這了,更多相關JavaScript獲取圖片文件真實格式內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

    標簽: JavaScript
    主站蜘蛛池模板: 西门子伺服控制器维修-伺服驱动放大器-828D数控机床维修-上海涌迪 | 上海logo设计| 上海公众号开发-公众号代运营公司-做公众号的公司企业服务商-咏熠软件 | 浇钢砖,流钢砖_厂家价低-淄博恒森耐火材料有限公司 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 幂简集成 - 品种超全的API接口平台, 一站搜索、试用、集成国内外API接口 | 浙江华锤电器有限公司_地磅称重设备_防作弊地磅_浙江地磅售后维修_无人值守扫码过磅系统_浙江源头地磅厂家_浙江工厂直营地磅 | 微波萃取合成仪-电热消解器价格-北京安合美诚科学仪器有限公司 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | 广州番禺搬家公司_天河黄埔搬家公司_企业工厂搬迁_日式搬家_广州搬家公司_厚道搬迁搬家公司 | 老房子翻新装修,旧房墙面翻新,房屋防水补漏,厨房卫生间改造,室内装潢装修公司 - 一修房屋快修官网 | 硫酸钡厂家_高光沉淀硫酸钡价格-河南钡丰化工有限公司 | 正压送风机-多叶送风口-板式排烟口-德州志诺通风设备 | 便携式表面粗糙度仪-彩屏硬度计-分体式粗糙度仪-北京凯达科仪科技有限公司 | 电机修理_二手电机专家-河北豫通机电设备有限公司(原石家庄冀华高压电机维修中心) | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 刑事律师_深圳著名刑事辩护律师_王平聚【清华博士|刑法教授】 | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) | 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | 桐城新闻网—桐城市融媒体中心主办 | 隧道窑炉,隧道窑炉厂家-山东艾瑶国际贸易 | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 应急灯_消防应急灯_应急照明灯_应急灯厂家-大成智慧官网 | 二手电脑回收_二手打印机回收_二手复印机回_硒鼓墨盒回收-广州益美二手电脑回收公司 | WTB5光栅尺-JIE WILL磁栅尺-B60数显表-常州中崴机电科技有限公司 | 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 水冷式工业冷水机组_风冷式工业冷水机_水冷螺杆冷冻机组-深圳市普威机械设备有限公司 | 河南中整光饰机械有限公司-抛光机,去毛刺抛光机,精密镜面抛光机,全自动抛光机械设备 | 接地电阻测试仪[厂家直销]_电缆故障测试仪[精准定位]_耐压测试仪-武汉南电至诚电力设备 | 派财经_聚焦数字经济内容服务平台 | led太阳能路灯厂家价格_风光互补庭院灯_农村市政工程路灯-中山华可路灯品牌 | 高柔性拖链电缆-聚氨酯卷筒电缆-柔性屏蔽电缆厂家-玖泰电缆 | 创绿家招商加盟网-除甲醛加盟-甲醛治理加盟-室内除甲醛加盟-创绿家招商官网 | LOGO设计_品牌设计_VI设计 - 特创易 | 铸铁平台,大理石平台专业生产厂家_河北-北重机械 | 翅片管换热器「型号全」_厂家-淄博鑫科环保 | 中山市派格家具有限公司【官网】 | 包塑丝_高铁绑丝_地暖绑丝_涂塑丝_塑料皮铁丝_河北创筹金属丝网制品有限公司 | 日本东丽膜_反渗透膜_RO膜价格_超滤膜_纳滤膜-北京东丽阳光官网 日本细胞免疫疗法_肿瘤免疫治疗_NK细胞疗法 - 免疫密码 | 深圳品牌设计公司-LOGO设计公司-VI设计公司-未壳创意 | 地图标注-手机导航电子地图如何标注-房地产商场地图标记【DiTuBiaoZhu.net】 |