Java ImageIO 类详解

这篇具有很好参考价值的文章主要介绍了Java ImageIO 类详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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 类读取和写入图像的基本流程如下:

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

例如,读取一张 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<ImageReader> 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 时,需要注意以下几点:文章来源地址https://www.toymoban.com/news/detail-627067.html

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

到了这里,关于Java ImageIO 类详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ImageIO的应用 (AWT和Swing初接触)

    在讲imageio之前,我们先来复习一下IO流的使用。 这里我建立一个Java类,用来实现读取文档中的内容,并且能够识别换行,话不多说,上代码: 代码是不是简洁易懂?有手就行。 注意一下,这里的文档需要建立在 F:Java_PrjJava_Project 包下 这里贴张图,展示一下文档内容 然后

    2024年02月08日
    浏览(70)
  • 苹果macOS 13.5.2正式发布 修复ImageIO进程

    9 月 8 日消息,苹果今日向 Mac 电脑用户推送了 macOS 13.5.2 更新(内部版本号:22G91),本次更新距离上次发布隔了 21 天。 需要注意的是,因苹果各区域节点服务器配置缓存问题,可能有些地方探测到升级更新的时间略有延迟,一般半小时内,不会太久。 苹果支持页面,macO

    2024年02月09日
    浏览(40)
  • Python编程:学习Python自带库imageio和pickle的详细指南

    Python编程:学习Python自带库imageio和pickle的详细指南 Python是一种流行的动态编程语言,它具有简单易学、高效灵活等特点,因此备受欢迎。随着其应用领域的不断扩展,Python付带的自带库变得越来越丰富。在本篇文章中,我们将重点介绍Python常用的自带库imageio和pickle,包括这

    2024年02月08日
    浏览(44)
  • Java高级语言实现插入排序算法

    【引言】 插入排序算法是一种简单且常用的排序算法。它通过依次将未排序的元素插入已排序序列中的正确位置来达到排序的目的。本文将使用Java高级语言实现插入排序算法,并讲解其核心思想和代码实现。 【算法思想】 插入排序的核心思想是通过构建有序序列,对于未排

    2024年02月11日
    浏览(47)
  • 编程开发8大语言详解,为什么Java是我最推荐的?

    很多没有接触过编程语言的同学,都会觉得编程开发特别高端和神奇,担心理解不了更担心学不会。 当然,也有人会认为,你既然是做编程的,那么你应该什么都会,什么软件的开发都能完成,这是平哥经常听到的两种声音。 在此,平哥需要给大家科普一下, 编程确实改变

    2024年02月05日
    浏览(73)
  • Java高级开发面试题整理

    1、什么是进程和线程? 进程是指程序的一次执行过程,是系统运行程序的基本单位,系统运行一个程序就是一个进程创建、运行、到销毁的过程;一个进程可以有多个线程。比如我跑一个java的main方法,系统就创建了一个java进程,这个main方法所在的线程就是这个进程的一个

    2024年02月08日
    浏览(48)
  • Java高级实战--高级开发和架构师的秘籍

    本JavaWeb高级实战教程全网最强!本教程是 实际项目中真正会用到的技术 ,学完就能成为 真正的技术大佬 , 有亮点的大佬 !此教程包含: 高并发、项目架构、全局处理、自动化处理、链路追踪、应用监控 等,也包含 Spring、SpringMVC、SpringBoot、Redis、MQ 的 高级 用法等。 很多

    2024年01月25日
    浏览(44)
  • Java语言开发在线小说推荐网 小说推荐系统 基于用户、物品的协同过滤推荐算法 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、人工智能、机器学习开发

    1、开发工具和使用技术 MyEclipse10/Eclipse/IDEA,jdk1.8,mysql5.5/mysql8,navicat数据库管理工具,tomcat,SSM(spring+springmvc+mybatis)开发框架,jsp页面,javascript脚本,jquery脚本,bootstrap前端框架(用户端),layui前端框架(管理员端),layer弹窗组件等。 2、实现功能 前台用户包含:注

    2023年04月26日
    浏览(84)
  • 【Java数据结构与算法】Day2-高级排序(希尔、归并、快速、计数)

    ✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。 🍎个人主页:Hhzzy99 🍊个人信条:坚持就是胜利! 💞当前专栏:【Java数据结构与算法】 🥭本文内容:Java数据结构与算法中的比较高级的排序,希尔排序、归并排序、快速排序、计数排序

    2024年02月02日
    浏览(64)
  • 🔥🔥Java开发者的Python快速进修指南:面向对象--高级篇

    首先,让我来介绍一下今天的主题。今天我们将讨论封装、反射以及单例模式。除此之外,我们不再深入其他内容。关于封装功能,Python与Java大致相同,但写法略有不同,因为Python没有修饰符。而对于反射来说,我认为它比Java简单得多,不需要频繁地获取方法和属性,而是

    2024年02月05日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包