Java中进行图像I/O(即读图片和写图片,不涉及到复杂图像处理)有三个方法:

JAI 中的 Image I/O Tools,支持更多图片类型,例如JPEG-LS, JPEG2000, 和 TIFF。

主页:https://jai-imageio.dev.java.net/。JAI 是一个关于图像处理的框架,很庞大,

其中仅仅jai-imageio是关于图像I/O的,其他的可以不看。

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内置支持的图片格式。

1

2

3

4

5

6

7

8

9

10

11import 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)的图片很简单:

1

2File f = new File(“c:imagesmyimage.gif”);

BufferedImage bi = ImageIO.read(f);

Java Image I/O API 会自动探测图片的格式并调用对应的插件进行解码,当安装了一个新

插件,新的格式会被自动理解,程序代码不需要改变。

写图片同样简单:

1

2

3BufferedImage bi;

File f = new File(“c:imagesmyimage.png”);

ImageIO.write(im, “png”, f);

3.2 更进一步

上一节谈到的方法对于简单程序已经足够了。不过,Java Image I/O API 提供了为编写复

杂程序的能力。为了利用API的高级特性,应用程序应当直接使用类ImageReader 和

ImageWriter。

3.3 ImageReader 类

与其用ImageIO类来进行所有的解码操作,不如用ImageIO类去得到一个ImageReader对象,

再用这个对象去进行读操作:

1

2Iterator readers = ImageIO.getImageReadersByFormatName(“gif”);

ImageReader reader = (ImageReader)readers.next();

ImageReader对象也可以基于文件内容、文件后缀或MIME类型获得。这个用于查找和初始

化ImageReader对象的机制用到了javax.imageio.spi.ImageReaderSpi类,它可以在不用初

始化插件的情况下获得插件的信息。”service provider interfaces” (SPIs)将会在下一

章详细讨论。一旦获得了一个ImageReader对象,必须给它是指一个输入源。大部分

ImageReader对象可以从ImageInputStream类输入源读取数据,ImageInputStream是Image

I/O API定义的专用输入源。

获得一个ImageInputStream 是简单的。给定一个File或InputStream,一个

ImageInputStream对象可以通过调用如下函数产生:

1

2Object 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对象:

1ImageReadParam param = reader.getDefaultReadParam();

接下来,指定图片区域:

1

2

3

4

5

6import 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);

最后,读取图片:

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

结果是一张新图片,宽和高都只有原图片的一半。

另一个例子,为了读取每三个像素中的一个,产生一个原图片1/9大小的图片,可以用

ImageReadParam指定抽样因子:

1

2

3param = 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);

如果存在缩略图,可以调用如下代码获取:

1

2

3int thumbailIndex = 0;

BufferedImage bi;

bi = reader.readThumbnail(imageIndex, thumbnailIndex);

3.4 ImageWriter 类

就像我们可以用ImageIO 的一个方法获取某种图片格式的ImageReader对象一样,我们也可

以获取ImageWriter对象:

1

2

3

4

5

6

7Iterator writers = ImageIO.getImageWritersByFormatName(“png”);

ImageWriter writer = (ImageWriter)writers.next();

一旦获取了一个ImageWriter对象,必须给它设置一个输出源ImageOutputStream。

File f = new File(“c:imagesmyimage.png”);

ImageOutputStream ios = ImageIO.createImageOutputStream(f);

writer.setOutput(ios);

最后,可以把图片写入到输出源:

1

2BufferedImage bi;

writer.write(bi);

3.4.1 写多图片文件

IIOImage类用于存储图片,缩略图或元信息的引用。下一节将讨论Metadata,目前,我们

简单地给Metadata相关参数传递null。

ImageWriter 类有一个方法write(),用于从IIOImage创建一个新文件,还有一个方法

writeInsert(),用于向一个已存在文件添加一个IIOImage对象。通过调用这两者,可以创

建一个多图片文件:

1

2

3

4

5

6

7

8

9BufferedImage 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 imageio_Java使用imageio 读写图像相关推荐

  1. 2.1 基于文件读写图像数据

    基于文件读写图像数据,获取图像文件的内容信息 Image Processing Toolbox™ 使您能够读取和写入许多常见文件格式的图像文件,包括 BMP.GIF.JPEG.PNG 和 TIFF.该 ...

  2. Java程序利用POJ读写Excel的.xls或.xlsx文件所需的3个jar包

    Java程序利用POJ读写Excel文件时,不能只用poi的jar包,因为它还依赖于xmlbeans的jar包,xmlbeans又以来与common-collections的jar包,因此,正常使用P ...

  3. java流与文件——读写二进制数据(DataOutput + DataInput)

    [0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--读写二进制数据(DataOutput + DataInput)的相关知识: 0.2) ...

  4. java对excel经行读写

    java对excel经行读写 package com.common.tool.util;import org.apache.poi.hssf.usermodel.*; import org.apach ...

  5. java 管道流的读写操作 用于两个线程之间的通信

    /* java 管道流的读写操作 用于两个线程之间    PipedOutputStream    PipedInputStream  连接起来就是一个管道     管道输出流可以向管道写入数据   ...

  6. gdal读写图像分块处理

    转自赵文原文 gdal读写图像分块处理(精华版) Review: 用gdal,感觉还不如直接用C++底层函数对遥感数据进行处理.因为gdal进行太多封装,如果你仅仅只是Geotif等格式进行处理,IO ...

  7. java使用jxl包读写excel表格文件,即xls格式文件

    全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用jxl包读写excel表格文件,即xls格式文件 本实例演示使用jxl包实现对excel文件的操作,下载 测试代码 public st ...

  8. OpenCV 读写图像、读写像素、修改像素值(案例:图像反处理)

    文章目录 读写图像 1. `imread` 可以指定加载为灰度或者RGB图像. 2. `imwrite` 保存图像文件,类型由扩展名决定. 读写像素 读一个GRAY像素点的像素值(CV_8UC1) 读 ...

  9. Java OpenCV 图像处理34 图形图像 分水岭 watershed

    Java OpenCV 图像处理34 图形图像 分水岭 watershed package com.xu.opencv;import org.opencv.core.Core; import org. ...

最新文章

  1. java父子表_数据库二维表转父子关系,java,stream,list
  2. 苹果开年第一购!买下仅24名员工的AI音乐公司,可根据环境动态生成音乐
  3. cordova 一个将web应用程序封装成app的框架
  4. vscode中如何运行git
  5. ss模型复模态的物理意义及adams复模态振型求解
  6. 关于int类型除以1000后保留两位小数的问题,并且在excel里打印出来
  7. 基于STM32F1单片机、ESP8266WIFI模块、DHT11温湿度传感的WIFI网络温湿度传输系统
  8. js将数组中一个或多个字段相同的子元素中合并
  9. 跨境电商将成全球贸易的主角,下半年跨境电商趋势是什么?
  10. 创建 OVS vlan100 netwrok - 每天5分钟玩转 OpenStack(137)
  11. 复旦大学网络认证linux,复旦大学校园网有线上网认证流程
  12. 【网络知识】Wireshark抓不到vlan tag问题解决
  13. 搜狗输入法弹出搜狗新闻的解决办法
  14. 【算法竞赛入门经典】习题1-4:正弦和余弦
  15. 参考美团大众点评合并,掌握APP推广妙招
  16. 如何在计算机查找类型文件类型,怎样在电脑中查找某一类型文件?比如查 txt...
  17. 统计行业板块内涨停板数量,跟踪热点板块!股票量化分析工具QTYX-V2.6.0
  18. 迪文串口屏(DMG10600C101-03WTC)的使用测试
  19. linux 串口格式化输出字符串,glibc中的printf如何输出到串口
  20. Proxmox VE ZFS 开启Thin Provision(精简配置)

热门文章

  1. 解决Win10更新后无法开启移动热点的问题
  2. 04 ElasticSearch分词及高阶搜索
  3. LSVGlobal Mapper应用----影像下载
  4. 企业微信登录报错:应用程序无法正常启动(0xc0000142);Win10应用程序无法正常启动0xc0000142错误的解决方法
  5. mapreduce面试问题_MapReduce问题与解答第2部分
  6. DDR2 sodimm + Flash + Triple-Speed Ethernet + IO in nios
  7. Codeforces Round #550 (Div. 3)C. Two Shuffled Sequences
  8. JavaScript 正则匹配中英文姓名
  9. 6m缓存和8m缓存差距_6张图,就可以了解1660Ti与RX590的差距
  10. 学生个人单页面网页作业 学生网页设计成品 静态HTML网页单页制作 dreamweaver网页设计与制作代码 web前端期末大作业