Java ImageIO 类详解

您所在的位置:网站首页 java处理图像的包 Java ImageIO 类详解

Java ImageIO 类详解

2023-08-27 01:12| 来源: 网络整理| 查看: 265

Java 中的 ImageIO 类是 Java 标准库中用于处理图像的一个非常常用的 API,它提供了读取和写入多种常见图像格式的功能,如 JPEG、PNG、BMP、GIF 等。开发者可以通过 ImageIO 类轻松地读取和写入图像,而无需考虑底层的细节。本文将全面详细地介绍 Java 中的 ImageIO 类的使用方法。

一、ImageIO 的基础知识 1.1 ImageIO 的作用

ImageIO 是 Java 标准库提供的一个类,它提供了读取和写入多种常见图像格式的功能。开发者可以使用 ImageIO 类快速、便捷地读取和写入图像,而无需关心底层的细节。

1.2 ImageIO 的特点

ImageIO 支持的图像格式非常广泛,包括 JPEG、PNG、BMP、GIF 等常见格式,同时也支持 TIFF、ICO、WBMP、JPEG 2000 等更加少见的格式。这使得开发者可以方便地读取和写入多种不同格式的图像。

ImageIO 还支持灵活的、可配置的图片格式转换。例如,可以将一张 JPEG 格式的图像读取到内存中,然后将其保存为 PNG 格式的图像。此外,ImageIO 还支持高级的图像处理操作,如裁剪、旋转、缩放、反转、镜像等。

1.3 ImageIO 的使用环境

ImageIO 是 Java 标准库中的一个类,因此不需要额外的库或安装,可以直接在 Java 应用程序中使用。它支持 Java SE 6 及以上版本,并且可以运行在所有常见的操作系统上。

1.4 ImageIO 的基本使用方法

使用 ImageIO 类读取和写入图像的基本流程如下:

通过 ImageIO 类的静态方法 read() 或者 write() 方法获取图片输入输出流;创建 ImageInputStream 或者 ImageOutputStream;读/写图像。

例如,读取一张 JPEG 格式的图片,代码如下:

String imageFilePath = "image.jpg"; try { InputStream inputStream = new FileInputStream(new File(imageFilePath)); BufferedImage bufferedImage = ImageIO.read(inputStream); // 图像处理逻辑 } catch (IOException e) { e.printStackTrace(); }

上述代码通过 FileInputStream 打开文件输入流,然后通过 ImageIO.read() 方法读取图像数据,最后对图像进行了处理操作。

下面我们将详细介绍 ImageIO 类的各个方面,包括读取、写入、压缩、格式转换以及高级操作等。

二、ImageIO 的读取操作 2.1 ImageIO 的 read() 方法

ImageIO 的 read() 方法是最常见的读取图像的方式,它有多个重载形式,可以用来读取 File、InputStream、URL 和 ImageInputStream 等多种类型的输入流。此外,ImageIO 还支持从 byte 数组读取或者从任意 SeekableStream 中读取文件。

例如,通过 ImageIO 的 read() 方法从本地文件读取一张图片:

String imageFilePath = "image.jpg"; try { BufferedImage bufferedImage = ImageIO.read(new File(imageFilePath)); // 图像处理逻辑 } catch (IOException e) { e.printStackTrace(); }

read() 方法返回了一个 BufferedImage 对象,开发者可以对这个对象进行各种操作,如裁剪、旋转、缩放等。注意:当读取的图像不是 RGB 格式时,返回的 BufferedImage 对象可能为 null。

2.2 以 Byte 数组形式读取图像

有些场景下,开发者需要将图片数据保存在内存中,然后再进行处理。ImageIO 的 read() 方法提供了一个重载形式,可以将图像数据读取到 byte 数组中,示例代码如下:

String imageFilePath = "image.jpg"; try { File file = new File(imageFilePath); BufferedImage bufferedImage = ImageIO.read(file); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); // 处理字节数组中的图像 } catch (IOException e) { e.printStackTrace(); }

在上述代码中,首先使用 ImageIO.read() 方法将图片读取到内存中,并得到了一个 BufferedImage 对象。然后,使用 ImageIO.write() 方法将 BufferedImage 对象写入到 ByteArrayOutputStream 中,最终得到了字节数组形式的图像数据。

2.3 指定图像格式

ImageIO 的 read() 方法可以自动识别常见的图像格式,但有时候需要指定特定的格式。通过 ImageIO 的 getReaderFormatNames() 方法可以查看支持的格式列表,示例代码如下:

String[] formatNames = ImageIO.getReaderFormatNames(); for (String format : formatNames) { System.out.println(format); }

如果要指定读取的格式,可以使用 ImageIO 的 getImageReadersByFormatName() 方法指定,例如:

File file = new File("image.xx"); Iterator readers = ImageIO.getImageReadersByFormatName("xxx"); try { ImageReader reader = readers.next(); ImageInputStream inputStream = ImageIO.createImageInputStream(file); reader.setInput(inputStream); BufferedImage image = reader.read(0); // 处理读取的图像 } catch (IOException e) { e.printStackTrace(); }

在上述代码中,getImageReadersByFormatName() 方法传入的参数是指定的图像格式名,然后通过 Iterator 获取到 ImageReader 对象,再使用 ImageIO.createImageInputStream() 方法创建 ImageInputStream 对象,并通过 setInput() 方法设置输入源。最后通过 reader.read() 方法读取图像。

三、ImageIO 的写入操作 3.1 ImageIO 的 write() 方法

ImageIO 的 write() 方法是写入图像的主要方法,它可以将 BufferedImage 对象写入到文件或者输出流中。除此之外,ImageIO 还提供了其他的方法来指定写出的格式和压缩质量等参数。

下面是一个将 BufferedImage 写入 PNG 格式的简单示例:

BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); try { ImageIO.write(image, "png", new File("output.png")); } catch (IOException e) { e.printStackTrace(); }

在上述代码中,使用 ImageIO.write() 方法将 BufferedImage 对象写入到本地文件 output.png 中。

3.2 指定图像格式

与读取图像类似,ImageIO 的 write() 方法默认会根据扩展名或者其他信息自动识别输出的图片格式。但是有些场景下需要手动指定输出的图像格式,可通过如下方式进行设置:

BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); try { File file = new File("output.xx"); ImageWriter writer = ImageIO.getImageWritersByFormatName("xxx").next(); ImageOutputStream outputStream = ImageIO.createImageOutputStream(file); writer.setOutput(outputStream); writer.write(image); outputStream.close(); } catch (Exception e) { e.printStackTrace(); }

在上述代码中,getImageWritersByFormatName() 方法传入指定的图像格式名,然后通过 ImageWriter 对象设置 ImageOutputStream,最后通过 write() 方法写入图像。

3.3 指定压缩质量

在写入图像时,ImageIO 还可以控制输出的压缩质量,从而控制输出图像文件的大小。不过需要注意的是,并非所有的图像格式都支持压缩。目前只有 JPEG 和 PNG 格式支持压缩功能。

下面是一个将 BufferedImage 写入 JPG 格式并指定压缩质量的示例:

BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); try { File file = new File("output.jpg"); // 获取 JPEG 格式的 ImageWriter ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); // 设置输出流 ImageOutputStream outputStream = ImageIO.createImageOutputStream(file); writer.setOutput(outputStream); // 设置压缩参数 JPEGImageWriteParam param = (JPEGImageWriteParam) writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(0.8f); // 写入图像 writer.write(null, new IIOImage(image, null, null), param); outputStream.close(); } catch (Exception e) { e.printStackTrace(); }

在上述代码中,首先从 ImageIO 中获取 JPEG 格式的 ImageWriter 对象,然后设置输出流和压缩参数。其中,setCompressionQuality() 方法用于设置压缩质量,值范围为 0.0~1.0,其中 1.0 表示不压缩,0.0 表示最大压缩。

3.4 指定保存位置

如果需要将 BufferedImage 对象写入到指定的文件目录下,可以使用 ImageIO 的 write() 方法进行操作。下面是一个将 BufferedImage 写入本地文件的示例:

BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); try { File file = new File("output.png"); ImageIO.write(image, "png", file); } catch (Exception e) { e.printStackTrace(); }

需要注意的是,write() 方法不支持压缩参数设置,如果需要控制输出文件大小,需要使用上述的 ImageWriter 方式。

四、ImageIO 的格式转换

在实际开发中,经常需要将图像从一种格式转换成另一种格式。ImageIO 提供的格式转换功能非常灵活,可以通过如下代码片段实现:

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); File outputFile = new File("output.png"); // 获取 png 格式的 ImageWriter ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next(); // 设置输出流 ImageOutputStream outputStream = ImageIO.createImageOutputStream(outputFile); writer.setOutput(outputStream); // 写入图像 writer.write(null, new IIOImage(srcImage, null, null), null); outputStream.close();

在上述代码中,首先使用 ImageIO.read() 方法读取 JPEG 格式的图像,然后通过 getImageWritersByFormatName() 方法获取 PNG 格式的 ImageWriter 对象。接着创建 ImageOutputStream 对象,并写入转换后的 PNG 格式图像。

需要注意的是,有些格式转换可能会导致图像信息的丢失,例如将 24-bit 的 RGB 图像转换成 8-bit 的 GIF 图像,会导致颜色数量减少,从而造成图像质量下降。

五、ImageIO 的高级操作

除了基本的格式读取、写入和转换外,ImageIO 还提供了一些高级的图像处理操作,如裁剪、旋转、缩放、反转、镜像等。下面简单介绍一下这些操作。

5.1 裁剪图像

通过 ImageIO.read() 方法读取的 BufferedImage 对象支持裁剪功能。可以通过调用 getSubimage() 方法获取指定区域的子图像。例如:

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); BufferedImage destImage = srcImage.getSubimage(10, 10, 100, 100);

上述代码从 (10,10) 开始,截取 100x100 的矩形区域作为 destImage 对象,并对其进行操作。

5.2 旋转图像

ImageIO 也支持对图像进行旋转操作。可以通过 AffineTransform 类来实现图像的旋转变换。

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); double radian = Math.toRadians(30); // 旋转角度为 30 度 AffineTransform transform = new AffineTransform(); transform.rotate(radian, srcImage.getWidth() / 2, srcImage.getHeight() / 2); AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); BufferedImage destImage = op.filter(srcImage, null);

在上述代码中,radian 变量表示旋转的角度,AffineTransform 类用于创建旋转变换,AffineTransformOp 类用于将变换应用到图像上。

5.3 缩放图像

缩放图像同样是 ImageIO 的高级操作之一。可以通过 AffineTransform 类来实现图像的缩放变换。

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); AffineTransform transform = new AffineTransform(); double scale = 0.5; // 图像缩小一倍 transform.scale(scale, scale); AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); BufferedImage destImage = op.filter(srcImage, null);

在上述代码中,通过 AffineTransform 的 scale() 方法设置缩放比例,AffineTransformOp 类用于将变换应用到图像上。

5.4 反转图像

对于需要水平或垂直翻转的图像,ImageIO 提供了如下方式实现:

``` // 读取输入图像(示例中为名为 input.png 的图像) BufferedImage srcImage = ImageIO.read(new File("input.png")); // 水平镜像 AffineTransform transform = new AffineTransform(-1, 0, 0, 1, srcImage.getWidth(), 0); AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); BufferedImage horizontalFlipped = op.filter(srcImage, null); // 垂直镜像 transform = new AffineTransform(1, 0, 0, -1, 0, srcImage.getHeight()); op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); BufferedImage verticalFlipped = op.filter(srcImage, null); // 上下颠倒 transform = new AffineTransform(-1, 0, 0, -1, srcImage.getWidth(), srcImage.getHeight()); op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); BufferedImage upsideDown = op.filter(srcImage, null); // 保存结果图像(保存为 PNG 格式的文件) ImageIO.write(horizontalFlipped, "png", new File("horizontal.png")); ImageIO.write(verticalFlipped, "png", new File("vertical.png")); ImageIO.write(upsideDown, "png", new File("upside_down.png")); 5.5 镜像图像

对于需要镜像的图像,ImageIO 提供了如下方式实现:

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); // 水平镜像 AffineTransform transform = new AffineTransform(-1, 0, 0, 1, srcImage.getWidth(), 0); // 垂直镜像 AffineTransform transform = new AffineTransform(1, 0, 0, -1, 0, srcImage.getHeight());

在上述代码中,水平镜像通过将 x 轴翻转并沿 y 轴平移一段距离实现,垂直镜像通过将 y 轴翻转并沿 x 轴平移一段距离实现。

5.6 组合操作

同时进行多个图像变换时,可以通过 AffineTransform 中的 concatenate() 方法,将多个变换组合到一起进行处理。例如:

BufferedImage srcImage = ImageIO.read(new File("input.jpg")); AffineTransform transform1 = new AffineTransform(); AffineTransform transform2 = new AffineTransform(); double scale = 0.5; transform1.scale(scale, scale); transform2.translate(50, 50); transform1.concatenate(transform2); // 将两个变换组合在一起 AffineTransformOp op = new AffineTransformOp(transform1, AffineTransformOp.TYPE_BILINEAR); BufferedImage destImage = op.filter(srcImage, null);

在上述代码中,首先创建两个不同的 AffineTransform 对象,一个用于缩放,一个用于平移,然后将其组合在一起。注意,组合时要先进行平移变换,再进行缩放变换,否则会产生错误的结果。

六、注意事项

在使用 ImageIO 时,需要注意以下几点:

避免频繁的读写文件,选择合适的内存缓存方式进行操作;在处理不同格式的图像时,应该注意色彩模式、透明度等方面的差异,以避免图像信息的丢失;在进行高级操作时,应该考虑到图像质量的问题,避免操作过度造成图像质量的下降。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3