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是Image
I/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 事件监听
略
本文转自:http://blog.csdn.net/perfect2011/article/details/6874287
Java 读写图像的更多相关文章
- Java读写文本文件操作
package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...
- java实现图像灰度化
/*在研究Java实现将一张图片转成字符画的时候,发现将图像转化字符串是根据照片的灰度采用不同的字符画出来,形成一个灰度表.于是就研究了下关于灰度值这个东西,于是跳了一个大坑...因为鄙人用的ubun ...
- GDAL关于读写图像的简明总结
读写影像可以说是图像处理最基础的一步.关于使用GDAL读写影像,平时也在网上查了很多资料,就想结合自己的使用心得,做做简单的总结. 在这里写一个例子:裁剪lena图像的某部分内容,将其放入到新创建的. ...
- java 读写word java 动态写入 模板文件
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import ja ...
- Java读写文件方法总结
Java读写文件方法总结 Java的读写文件方法在工作中相信有很多的用处的,本人在之前包括现在都在使用Java的读写文件方法来处理数据方面的输入输出,确实很方便.奈何我的记性实在是叫人着急,很多时候既 ...
- Java读写文件的几种方式
自工作以后好久没有整理Java的基础知识了.趁有时间,整理一下Java文件操作的几种方式.无论哪种编程语言,文件读写操作时避免不了的一件事情,Java也不例外.Java读写文件一般是通过字节.字符和行 ...
- java读写文件大全
java读写文件大全 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中 write(char[] ch,int o ...
- Java读写Windows共享文件夹 .
版权声明:本文为博主原创文章,未经博主允许不得转载. 项目常常需要有访问共享文件夹的需求,例如共享文件夹存储照片.文件等.那么如何使用Java读写Windows共享文件夹呢? Java可以使用JCIF ...
- 【转】Java 读写Properties配置文件
[转]Java 读写Properties配置文件 1.Properties类与Properties配置文件 Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形 ...
随机推荐
- ubuntu搭建lamp环境
首先安装软件: sudo apt-get install apache2 sudo apt-get install php5 sudo apt-get install mysql-server sud ...
- ios图标和默认图像
Icon.png和Default.png是两个重要的图像文件.Icon.png充当应用程序的图标,这些图标用于在SpringBoard主屏幕上表示应用程序.Default.png(也称"启动 ...
- .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程
原文来自VAllen cnblogs 一.使用教程1.解压后,双击Reflector.exe,如果有选择默认版本的.Net Framework,根据需要选择即可.你选择的版本不同则出现的默认程序集也不 ...
- SharePoint 2010 隐藏快速启动栏之使用内容编辑器webpart
SharePoint 2010 自带的webpart里有一个叫内容编辑,在媒体和内容分类里面: 将其添加到页面后效果: 点击用于添加新内容,此时注意Ribbon菜单中的变化: 这里可以看到,你可以插入 ...
- Selenium测试Ajax程序(转)
上周末参加了Qclub的百度技术沙龙,听了百度的孙景卫讲了Web自动化测试,讲的非常好,然后在小组讨论时又有幸座在了一起.我们讨论的一个内容,就是Ajax应用程序比原来的非Ajax程序更不易测试,这里 ...
- ndk编译protobuf库
ndk_r9编译通过,里面带了自动生成代码的脚本(tool/createPBFile.bat). 下载地址
- Python多进程(1)——subprocess与Popen()
Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...
- hdu 3032 Nim or not Nim? (SG函数博弈+打表找规律)
Nim or not Nim? Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Sub ...
- ThreadGroup分析
本文为转载:http://sunboyyyl.blog.163.com/blog/static/2247381201211531712330/ 在Java中每一个线程都归属于某个线程组管理的一员,例如 ...
- July 17th, Week 30th Sunday, 2016
You are beautiful, but that is not why I love you. 你如此美丽,但我并非因此而爱你. Although we have always been tol ...