Java 读写图像
轉載自??Java 讀寫圖像
Java中進行圖像I/O(即讀圖片和寫圖片,不涉及到復雜圖像處理)有三個方法:
1. Java Image I/O API,支持常見圖片,從Java 2 version 1.4.0開始就內置了。
主頁:http://java.sun.com/javase/6/docs/technotes/guides/imageio/index.html
2. JAI 中的 Image I/O Tools,支持更多圖片類型,例如JPEG-LS, JPEG2000, 和 TIFF。
主頁:https://jai-imageio.dev.java.net/。JAI 是一個關于圖像處理的框架,很龐大,其中僅僅jai-imageio是關于圖像I/O的,其他的可以不看。
3. JAI的com.sun.media.jai.codec 也有一定的圖像解碼能力
當然,還有眾多的java開源工具包可以讀寫圖像,例如JIMI, JMagic等,但JDK目前本身能夠讀寫圖片,就用JDK的,開發和部署方便,不需要額外下載jar包。
由于JAI是Java新加入的,很多組件不是正式規范,JDK不自帶,因此開發和部署需要額外安裝,安裝文件在官網https://jai.dev.java.net/下載得到。
如果你僅僅想讀取常見格式的圖片,不需要用JAI這么高級這么龐大的東西,用Java Image I/O API即可。
下面重點介紹 Java Image I/O API。
Java Image I/O API 主要在 javax.imageio 下面。JDK已經內置了常見圖片格式的插件,但它提供了插件體系結構,第三方也可以開發插件支持其他圖片格式。
下面這段代碼可以展示,JDK內置支持的圖片格式。
主頁上有一個文檔,Java Image I/O API Guide,很通俗易懂,可以讓你快速上手。以下內容主要來自這個文檔的第3章。
第3章 編寫圖像I/O程序
3.1 讀寫圖片
javax.imageio.ImageIO類提供了一組靜態方法進行最簡單的圖像I/O操作。
讀取一個標準格式(GIF, PNG, or JPEG)的圖片很簡單:
Java Image I/O API 會自動探測圖片的格式并調用對應的插件進行解碼,當安裝了一個新插件,新的格式會被自動理解,程序代碼不需要改變。
寫圖片同樣簡單:
3.2 更進一步
上一節談到的方法對于簡單程序已經足夠了。不過,Java Image I/O API 提供了為編寫復雜程序的能力。為了利用API的高級特性,應用程序應當直接使用類ImageReader 和ImageWriter。
3.3 ImageReader 類
與其用ImageIO類來進行所有的解碼操作,不如用ImageIO類去得到一個ImageReader對象,再用這個對象去進行讀操作:
ImageReader對象也可以基于文件內容、文件后綴或MIME類型獲得。這個用于查找和初始化ImageReader對象的機制用到了javax.imageio.spi.ImageReaderSpi類,它可以在不用初始化插件的情況下獲得插件的信息。”service provider interfaces” (SPIs)將會在下一章詳細討論。一旦獲得了一個ImageReader對象,必須給它是指一個輸入源。大部分ImageReader對象可以從ImageInputStream類輸入源讀取數據,ImageInputStream是ImageI/O API定義的專用輸入源。
獲得一個ImageInputStream 是簡單的。給定一個File或InputStream,一個ImageInputStream對象可以通過調用如下函數產生:
一旦有了輸入源,可以把它與一個ImageReader對象關聯起來:
reader.setInput(iis, true);
如果輸入源文件包含多張圖片,而程序不保證按順序讀取時,第二個參數應該設置為false。對于那些只允許存儲一張圖片的文件格式,永遠傳遞true是合理的。當ImageReader對象有了輸入源后,我們就可以獲取圖片信息而不用把整張圖片數據都讀入內存。例如,調用reader.getImageWidth(0)可以讓我們獲得文件中第一張圖片的寬度。一個好的插件會試圖解碼文件的必要部分,去獲得圖片的寬度,而不用讀取任何一個像素。為讀取圖片,可以調用reader.read(imageIndex), imageIndex是文件(當包含多張圖片時)中圖片的索引。這與上一節調用ImageIO.read()產生的結果相同。
3.3.1 ImageReadParam
如果需要更多的控制,可以向read()方法傳遞一個ImageReadParam類型的參數。一個ImageReadParam對象可以讓程序更好的利用內存。它不僅允許指定一個感興趣的區域,還可以指定一個抽樣因子,用于向下采樣。
例如,為了只解碼圖片的左上角的1/4,程序可以先獲取一個合適的ImageReadParam對象:
接下來,指定圖片區域:
最后,讀取圖片:
結果是一張新圖片,寬和高都只有原圖片的一半。
另一個例子,為了讀取每三個像素中的一個,產生一個原圖片1/9大小的圖片,可以用ImageReadParam指定抽樣因子:
3.3.2 IIOParamController
插件有時會提供一個IIOParamController類,這是可選的。略。
3.3.3 讀多圖片文件
ImageReader 中所有與圖片打交道的方法都有一個imageIndex 參數,這個參數用于讀取多圖片文件中的一張。
ImageReader.getNumImages()返回多圖片文件中的圖片個數。這個方法有一個boolean參數,allowSearch。有的圖片格式,典型的GIF,沒有提供任何獲取文件中的圖片個數方法,除非讀取整個進行解析。這樣代價很高,因此設置allowSearch為false可以讓方法直接返回-1,而不是實際的圖片個數。如果此參數是true,則該方法總會返回文件中實際的圖片個數。
即使在不知道文件中圖片個數的情況下,仍可以調用read(imageIndex); 如果索引值過大,該方法會拋出IndexOutOfBoundsException異常。因此,程序可以遞增索引去獲取圖片,直到異常。
3.3.4 讀縮略圖?
有的圖片格式允許一個(或多個)小的預覽圖,與主圖片一起存儲在文件中。這些“縮略圖”對于快速識別圖片很有用,不用解碼整個圖片。
程序可以調用如下代碼,探測一張圖片有多少張縮略圖:
如果存在縮略圖,可以調用如下代碼獲取:
3.4 ImageWriter 類?
就像我們可以用ImageIO 的一個方法獲取某種圖片格式的ImageReader對象一樣,我們也可以獲取ImageWriter對象:
一旦獲取了一個ImageWriter對象,必須給它設置一個輸出源ImageOutputStream。
最后,可以把圖片寫入到輸出源:
3.4.1 寫多圖片文件
IIOImage類用于存儲圖片,縮略圖或元信息的引用。下一節將討論Metadata,目前,我們簡單地給Metadata相關參數傳遞null。ImageWriter 類有一個方法write(),用于從IIOImage創建一個新文件,還有一個方法writeInsert(),用于向一個已存在文件添加一個IIOImage對象。通過調用這兩者,可以創建一個多圖片文件:
3.5? 處理 Metadata?
所有與像素無關的信息,都屬于在Metadata。javax.imageio.metadata 包含了用于訪問Metadata的類和接口。
Image I/O API 將stream metadata 和image metadata區別對待。stream metadata與一個文件中存儲了多張圖片有關,image metadata只與單個圖片有關。如果一個文件只包含一張圖片,那么就只存在image metadata。可以通過調用ImageReader.getStreamMetadata 和 getImageMetadata(int imageIndex)來獲取metadata。這些方法會返回一個實現了IIOMetadata接口的對象,該對象會被向上轉化為ImageReader類型,
3.6 編碼轉換
略
3.7 事件監聽
略
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
- 上一篇: 天龙八部12开需要换什么电脑配置?
- 下一篇: java美元兑换,(Java实现) 美元