日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 读写图像

發布時間:2023/12/3 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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內置支持的圖片格式。

import javax.imageio.*; import java.util.Arrays;public class HelloWorld {public static void main(String args[]) {String readFormats[] = ImageIO.getReaderFormatNames();String writeFormats[] = ImageIO.getWriterFormatNames();System.out.println(“Readers: ” + Arrays.asList(readFormats));System.out.println(“Writers: ” + Arrays.asList(writeFormats));} }

主頁上有一個文檔,Java Image I/O API Guide,很通俗易懂,可以讓你快速上手。以下內容主要來自這個文檔的第3章。

第3章 編寫圖像I/O程序
3.1 讀寫圖片

javax.imageio.ImageIO類提供了一組靜態方法進行最簡單的圖像I/O操作。
讀取一個標準格式(GIF, PNG, or JPEG)的圖片很簡單:

File f = new File(“c:\images\myimage.gif”); BufferedImage bi = ImageIO.read(f);

Java Image I/O API 會自動探測圖片的格式并調用對應的插件進行解碼,當安裝了一個新插件,新的格式會被自動理解,程序代碼不需要改變。

寫圖片同樣簡單:

BufferedImage bi; File f = new File(“c:\images\myimage.png”); ImageIO.write(im, “png”, f);

3.2 更進一步
上一節談到的方法對于簡單程序已經足夠了。不過,Java Image I/O API 提供了為編寫復雜程序的能力。為了利用API的高級特性,應用程序應當直接使用類ImageReader 和ImageWriter。

3.3 ImageReader 類
與其用ImageIO類來進行所有的解碼操作,不如用ImageIO類去得到一個ImageReader對象,再用這個對象去進行讀操作:

Iterator readers = ImageIO.getImageReadersByFormatName(“gif”); ImageReader reader = (ImageReader)readers.next();

ImageReader對象也可以基于文件內容、文件后綴或MIME類型獲得。這個用于查找和初始化ImageReader對象的機制用到了javax.imageio.spi.ImageReaderSpi類,它可以在不用初始化插件的情況下獲得插件的信息。”service provider interfaces” (SPIs)將會在下一章詳細討論。一旦獲得了一個ImageReader對象,必須給它是指一個輸入源。大部分ImageReader對象可以從ImageInputStream類輸入源讀取數據,ImageInputStream是ImageI/O API定義的專用輸入源。

獲得一個ImageInputStream 是簡單的。給定一個File或InputStream,一個ImageInputStream對象可以通過調用如下函數產生:

Object source; // File or InputStream ImageInputStream iis = ImageIO.createImageInputStream(source);

一旦有了輸入源,可以把它與一個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對象:

ImageReadParam param = reader.getDefaultReadParam();

接下來,指定圖片區域:

import java.awt.Rectangle; int imageIndex = 0; int half_width = reader.getImageWidth(imageIndex)/2; int half_height = reader.getImageHeight(imageIndex)/2; Rectangle rect = new Rectangle(0, 0, half_width, half_height); param.setSourceRegion(rect);

最后,讀取圖片:

BufferedImage bi = reader.read(imageIndex, param);

結果是一張新圖片,寬和高都只有原圖片的一半。

另一個例子,為了讀取每三個像素中的一個,產生一個原圖片1/9大小的圖片,可以用ImageReadParam指定抽樣因子:

param = reader.getDefaultImageParam(); param.setSourceSubsampling(3, 3, 0, 0); BufferedImage bi3 = reader.read(0, param);

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 讀縮略圖?
有的圖片格式允許一個(或多個)小的預覽圖,與主圖片一起存儲在文件中。這些“縮略圖”對于快速識別圖片很有用,不用解碼整個圖片。

程序可以調用如下代碼,探測一張圖片有多少張縮略圖:

reader.getNumThumbnails(imageIndex);

如果存在縮略圖,可以調用如下代碼獲取:

int thumbailIndex = 0; BufferedImage bi; bi = reader.readThumbnail(imageIndex, thumbnailIndex);

3.4 ImageWriter 類?
就像我們可以用ImageIO 的一個方法獲取某種圖片格式的ImageReader對象一樣,我們也可以獲取ImageWriter對象:

Iterator writers = ImageIO.getImageWritersByFormatName(“png”); ImageWriter writer = (ImageWriter)writers.next();

一旦獲取了一個ImageWriter對象,必須給它設置一個輸出源ImageOutputStream。

File f = new File(“c:\images\myimage.png”); ImageOutputStream ios = ImageIO.createImageOutputStream(f); writer.setOutput(ios);

最后,可以把圖片寫入到輸出源:

BufferedImage bi; writer.write(bi);

3.4.1 寫多圖片文件
IIOImage類用于存儲圖片,縮略圖或元信息的引用。下一節將討論Metadata,目前,我們簡單地給Metadata相關參數傳遞null。ImageWriter 類有一個方法write(),用于從IIOImage創建一個新文件,還有一個方法writeInsert(),用于向一個已存在文件添加一個IIOImage對象。通過調用這兩者,可以創建一個多圖片文件:

BufferedImage first_bi, second_bi; IIOImage first_IIOImage = new IIOImage(first_bi, null, null); IIOImage second_IIOImage = new IIOImage(second_bi, null, null); writer.write(null, first_IIOImage, null); if (writer.canInsertImage(1)) { writer.writeInsert(1, second_IIOImage, null); } else { System.err.println(“Writer can’t append a second image!”); }

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 事件監聽


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Java 读写图像的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。