Java中如何獲取圖片文件格式(后綴)
Java獲取圖片文件格式(后綴)
今天做一個(gè)爬蟲,使用正則匹配到<img>標(biāo)簽以后,直接用InputStream流進(jìn)行下載到內(nèi)存,然后再使用FileOutputStream保存到硬盤,但是要獲取圖片文件格式再進(jìn)行保存。
一開始使用了正則截取,比如<img src="/book/en/v2/images/basic-branching-1.png" />,就直接用字符串截取.png的內(nèi)容
String imgSrc = "/book/en/v2/images/basic-branching-1.png"; String formatName = imgSrc.split("\\.")[1];
但是后來(lái)突然想到如果URL的path里就帶有 . 那怎么辦(雖然我沒(méi)見到過(guò))
假設(shè)一個(gè)圖片標(biāo)簽 <img src="/book/en/v2/.hahaha/basic-branching-1.png" />,那這樣就不能保證是截取到后綴。
想到PHP和Python都有直接處理圖片的庫(kù),很方便,Java應(yīng)該也有這種操作吧。
經(jīng)過(guò)去StackOverflow查找一番,發(fā)現(xiàn)確實(shí)Java這種操作很麻煩,所以自己實(shí)現(xiàn)了一個(gè)工具方法。
? ? public static List<String> getImageFormat(InputStream srcInputStream) throws IOException { ? ? ? ? List<String> formatNameList = new ArrayList<>(); ? ? ? ? // 獲取ImageInputStream 對(duì)象 ? ? ? ? ImageInputStream imageInputStream = ImageIO.createImageInputStream(srcInputStream); ? ? ? ? // 獲取ImageReader對(duì)象的迭代器 ? ? ? ? Iterator<ImageReader> iterator = ImageIO.getImageReaders(imageInputStream); ? ? ? ? // 如果能獲得ImageReader對(duì)象則說(shuō)明流中含有圖片文件 ? ? ? ? while(iterator.hasNext()) { ? ? ? ? ? ? // ImageReader對(duì)象的getFormatName()方法可以獲得圖片格式 ? ? ? ? ? ? formatNameList.add(iterator.next().getFormatName()); ? ? ? ? } ? ? ? ? return formatNameList; ? ? }
這樣我們就能從連續(xù)的圖片文件流中獲取多個(gè)圖片文件,實(shí)現(xiàn)獲取文件真實(shí)格式到的后綴。
Java代碼獲取圖片格式及顏色模型
近期服務(wù)器總是在上傳下載圖片的時(shí)候出現(xiàn)CPU飆高的情況,想對(duì)上傳方法進(jìn)行下改進(jìn),查到了一個(gè)方法使用ImageIO.read()讀取圖片,但是可能存在讀取CMYK編碼的JPEG圖片失真問(wèn)題,本片文章先用Java代碼查看給定圖片的格式以及顏色模型。
顏色模型
CMYK(Cyan, Magenta, Yellow, Black - Key Plate)模型,指的是使用(青色,品紅、黃、黑)4種印刷使用的油墨顏色,作為保存圖片的格式。它主要用在印刷中, 讓i印刷色彩更加逼真。
RGB模式,是使用(紅、綠、藍(lán))三基色, 作為保存圖片的格式。RGB值通常使用三個(gè)指定0到255之間的整數(shù),分別代表紅、綠、藍(lán)色的強(qiáng)度。它主要用于網(wǎng)頁(yè)設(shè)計(jì)中, 方便屏幕顯示。
二者在文件保存格式上是有區(qū)別的,我們可以通過(guò)JPG文件的保存格式上區(qū)分:
(1)CMYK模式:JPEG文件中前8個(gè)字節(jié)是FF D8 FF E1
(2)RGB模式:JPEG文件中前8個(gè)字節(jié)是FF D8 FF E0
Java代碼查看圖片類型,以及將圖片轉(zhuǎn)十六進(jìn)制
package com.flex; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import org.junit.Test; public class TestImage { @Test public void testImageFormat() { File img = new File("F:/1518048669186_0ssai3.jpg"); System.out.println(getImageFormat(img));//JPEG } @Test public void testColorFormat() { getImageHex("F:/1518048669186_0ssai3.jpg"); System.out.println("image.text長(zhǎng)度:" + new File("F:/image.txt").length()); } /* * 獲得圖片的格式,例如:JPEG、GIF等 */ public String getImageFormat(Object obj) { try { ImageInputStream iis = ImageIO.createImageInputStream(obj); Iterator<ImageReader> iterator = ImageIO.getImageReaders(iis); while (iterator.hasNext()) { ImageReader reader = (ImageReader) iterator.next(); return reader.getFormatName(); } } catch (IOException e) { e.printStackTrace(); } return null; } /* * 圖片轉(zhuǎn)十六進(jìn)制 */ public void getImageHex(String path) { try { Long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream(path); java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); byte[] buff = new byte[1024]; int len = 0; while ((len = fis.read(buff)) != -1) { bos.write(buff, 0, len); } // 得到圖片的字節(jié)數(shù)組 byte[] result = bos.toByteArray(); // 字節(jié)數(shù)組轉(zhuǎn)成十六進(jìn)制 String str = byte2HexStr(result); // 將十六進(jìn)制串保存到txt文件中 PrintWriter pw = new PrintWriter(new FileWriter("F:/image.txt")); pw.println(str); pw.close(); Long end = System.currentTimeMillis(); System.out.println("圖片轉(zhuǎn)十六進(jìn)制花費(fèi)時(shí)間:" + (end - start)); } catch (IOException e) { e.printStackTrace(); } } /* * 實(shí)現(xiàn)字節(jié)數(shù)組向十六進(jìn)制的轉(zhuǎn)換方法 */ public static String byte2HexStr(byte[] b) { String hs = ""; String stmp = ""; for (int n = 0; n < b.length; n++) { stmp = (Integer.toHexString(b[n] & 0XFF)); if (stmp.length() == 1) hs = hs + "0" + stmp; else hs = hs + stmp; } return hs.toUpperCase(); } }
結(jié)果如圖
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于spring-boot-maven-plugin插件打包lib文件外置的方法(layout模式為ZIP模式)
Maven是一個(gè)插件執(zhí)行框架,所有工作都由插件完成,同時(shí)?Maven?基于構(gòu)建生命周期的核心概念,明確定義了構(gòu)建和分發(fā)特定工件(項(xiàng)目)的過(guò)程,接下來(lái)通過(guò)本文給大家介紹下基于spring-boot-maven-plugin插件打包lib文件外置(layout模式為ZIP模式),需要的朋友可以參考下2022-09-09Java實(shí)現(xiàn)刪除排序鏈表中的重復(fù)元素的方法
這篇文章主要介紹了Java實(shí)現(xiàn)刪除排序鏈表中的重復(fù)元素的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法)
這篇文章主要介紹了把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法),然后在文章給大家提到了如何將Spring Boot項(xiàng)目打包部署到外部Tomcat,需要的朋友參考下吧2017-11-11Springboot?定時(shí)任務(wù)分布式下冪等性解決方案
這篇文章主要介紹了Springboot定時(shí)任務(wù)分布式下冪等性如何解決,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07java簡(jiǎn)單手寫版本實(shí)現(xiàn)時(shí)間輪算法
這篇文章主要為大家詳細(xì)介紹了java簡(jiǎn)單手寫版本實(shí)現(xiàn)時(shí)間輪算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04Java接口默認(rèn)方法帶來(lái)的問(wèn)題分析【二義性問(wèn)題】
這篇文章主要介紹了Java接口默認(rèn)方法帶來(lái)的問(wèn)題,結(jié)合實(shí)例形式分析了java接口帶來(lái)的二義性問(wèn)題,需要的朋友可以參考下2019-08-08使用MyBatis的動(dòng)態(tài)SQL注解實(shí)現(xiàn)實(shí)體的CRUD操作代碼
在使用MyBatis進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),動(dòng)態(tài)SQL注解提供了一種優(yōu)雅的方式來(lái)編寫動(dòng)態(tài)SQL語(yǔ)句,MyBatis?3.x?版本提供了下四個(gè)CRUD的高級(jí)注解,這些注解可以幫助開發(fā)者在Mapper接口中動(dòng)態(tài)地構(gòu)建SQL語(yǔ)句,本文給大家介紹了使用MyBatis的動(dòng)態(tài)SQL注解實(shí)現(xiàn)實(shí)體的CRUD操作2024-06-06