`
zhang_xzhi_xjtu
  • 浏览: 538372 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使用ImageIO.write存储png格式图片性能较差问题

    博客分类:
  • java
 
阅读更多
目前加载一个png格式的图片,做一些绘图工作,发现ImageIO.write存储png性能较差,转为存储jpg格式图片,性能可以提高6,7倍。
代码如下。

package test;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;

import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

import javax.imageio.ImageIO;

import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.*;

import org.junit.Before;
import org.junit.Test;

/**
 * 加载png格式图片,使用不同方式转为png或者jpg格式的性能对比。
 * */
public class PngJpgImagePerTest {

	private static String PNG = "png";
	private static String JPG = "jpg";

	private static String SimpleSavePNG = "__SimpleSavePNG.png";
	private static String Convert2ArrayAndSavePNG = "__Convert2ArrayAndSavePNG.png";
	private static String NewImageSavePNG = "__NewPNG.png";
	private static String NewImageSaveJPG = "__NewJPG.jpg";
	private static String SaveJPG = "__JPG_quality.jpg";

	/**
	 * 保存文件。
	 * */
	public static void save2File(String filePath, byte[] data) {

		BufferedOutputStream bufferOutput = null;

		try {
			bufferOutput = new BufferedOutputStream(new FileOutputStream(
					new File(filePath)), 1024);

			bufferOutput.write(data);
			bufferOutput.flush();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (bufferOutput != null) {
				try {
					bufferOutput.close();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

	/**
	 * load image
	 * */
	public static BufferedImage loadImage(String filePath) {
		try {
			return ImageIO.read(new File(filePath));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * simple save use ImageIO.write
	 */
	public static void saveImage(BufferedImage image, String format,
			String filePath) {
		try {
			ImageIO.write(image, format, new File(filePath));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * convert to byte array.
	 * */
	public static byte[] convert2bytes(BufferedImage image, String format) {
		try {
			ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
			ImageIO.write(image, format, bout);
			byte[] data = bout.toByteArray();
			return data;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * create new buffer image and save using png format.
	 * */
	public static void savePngImage(BufferedImage image, String format,
			String filePath) {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(), image
				.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
		bufferedImage.getGraphics().drawImage(image, 0, 0, null);
		saveImage(bufferedImage, PNG, filePath);
	}

	/**
	 * create new buffer image and save using jpg format.
	 * */
	public static void saveJpgImage(BufferedImage image, String format,
			String filePath) {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(), image
				.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
		bufferedImage.getGraphics().drawImage(image, 0, 0, null);
		saveImage(bufferedImage, JPG, filePath);
	}

	/**
	 * save jpg with specified quality. 为了图片质量,quality的值不能太低。
	 * */
	public static void saveImageUsingJPGWithQuality(BufferedImage image,
			String filePath, float quality) throws Exception {

		BufferedImage newBufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
		newBufferedImage.getGraphics().drawImage(image, 0, 0, null);

		Iterator<ImageWriter> iter = ImageIO
				.getImageWritersByFormatName("jpeg");

		ImageWriter imageWriter = iter.next();
		ImageWriteParam iwp = imageWriter.getDefaultWriteParam();

		iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
		iwp.setCompressionQuality(quality);

		File file = new File(filePath);
		FileImageOutputStream fileImageOutput = new FileImageOutputStream(file);
		imageWriter.setOutput(fileImageOutput);
		IIOImage iio_image = new IIOImage(newBufferedImage, null, null);
		imageWriter.write(null, iio_image, iwp);
		imageWriter.dispose();
	}

	public static void drawString(Graphics2D g2, String value, int x, int y) {
		Font font = new Font("Arial", Font.BOLD, 16);
		g2.setColor(Color.BLACK);
		g2.setFont(font);
		g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
				RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		g2.drawString(value, x, y);
	}

	private String sourceFilePath;
	private BufferedImage sourceImage;
	private int loop;
	private float quality;

	@Before
	public void setup() {
		sourceFilePath = "E:\\allencode\\ImgTest\\stat.png";
		sourceImage = loadImage(sourceFilePath);
		loop = 10;
		quality = 0.8F;
		Graphics2D g2 = sourceImage.createGraphics();
		draw(g2);
	}

	private void draw(Graphics2D g2) {
		drawString(g2, "Allen Hello world.", 500, 200);
	}

	/**
	 * ImageIO.write存储图片时主要的性能消耗在计算上。
	 * */
	@Test
	public void test_01() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < loop; i++) {
			long start = System.currentTimeMillis();
			saveImage(sourceImage, PNG, sourceFilePath + SimpleSavePNG);
			long end = System.currentTimeMillis();
			sb.append(" saveImage = " + (end - start));

			long convertStart = System.currentTimeMillis();
			byte[] pngData = convert2bytes(sourceImage, PNG);
			long convertEnd = System.currentTimeMillis();
			sb.append(" convert = " + (convertEnd - convertStart));

			long saveStart = System.currentTimeMillis();
			save2File(sourceFilePath + Convert2ArrayAndSavePNG, pngData);
			long saveEnd = System.currentTimeMillis();
			sb.append(" save = " + (saveEnd - saveStart));

			sb.append("\n");
		}

		System.out.println(sb);
	}

	/**
	 * ImageIO.write和新建一个BufferedImage,采用jpg或png保存的比较。
	 * */
	@Test
	public void test_02() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < loop; i++) {
			long start = System.currentTimeMillis();
			saveImage(sourceImage, PNG, sourceFilePath + SimpleSavePNG);
			long end = System.currentTimeMillis();
			sb.append(" saveImage = " + (end - start));

			start = System.currentTimeMillis();
			savePngImage(sourceImage, "png", sourceFilePath + NewImageSavePNG);
			end = System.currentTimeMillis();
			sb.append(" savePngImage = " + (end - start));

			start = System.currentTimeMillis();
			saveJpgImage(sourceImage, "jpg", sourceFilePath + NewImageSaveJPG);
			end = System.currentTimeMillis();
			sb.append(" saveJpgImage = " + (end - start));

			sb.append("\n");
		}

		System.out.println(sb);
	}

	/**
	 * ImageIO.write存储图片和保存jpg的时间对比。
	 * */
	@Test
	public void test_03() throws Exception {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < loop; i++) {
			long pngStart = System.currentTimeMillis();
			saveImage(sourceImage, PNG, sourceFilePath + SimpleSavePNG);
			long pngEnd = System.currentTimeMillis();
			sb.append(" saveImage = " + (pngEnd - pngStart));

			long jpgStart = System.currentTimeMillis();
			saveImageUsingJPGWithQuality(sourceImage, sourceFilePath + SaveJPG,
					quality);
			long jpgEnd = System.currentTimeMillis();
			sb.append(" JPGWithQuality = " + (jpgEnd - jpgStart));

			sb.append(" % = " + (pngEnd - pngStart) * 1D / (jpgEnd - jpgStart));
			sb.append("\n");
		}

		System.out.println(sb);
	}
}
3
0
分享到:
评论
1 楼 seraphim0930 2012-12-12  
楼主你太V5啦!

相关推荐

    Java图片处理ImageIO.read()问题

    1. **文件格式不支持**:`ImageIO`默认支持JPG、PNG、GIF等常见格式。如果尝试读取其他不支持的格式,会抛出`IOException`。解决方法是使用第三方库,如Apache Batik或ImageMagick,扩展支持更多格式。 2. **输入流...

    图片处理 javax.imageio.IIOException: Unsupported Image Type

    在Java编程环境中,图片处理是一项常见的任务,但有时可能会遇到“javax.imageio.IIOException: Unsupported Image Type”的错误。这个异常通常表示Java的`ImageIO`类库无法识别或支持所尝试读取或写入的图像格式。...

    java 使用ImageIO.writer从BufferedImage生成jpeg图像遇到问题总结及解决

    在这里,使用ImageIO.write时要确保传入的格式名是正确的,因为如果传入了错误的图像格式名,该方法会返回false并导致异常抛出。此外,在捕获异常时,应确保异常处理逻辑正确无误。 此外,为了确保图像数据能够被...

    tesseract识别中文的com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam下载

    TIFF(Tagged Image File Format)是一种灵活的位图格式,常用于存储高分辨率的扫描图像和专业摄影图像。在处理TIFF图像时,`TIFFImageWriteParam`参数类提供了对写入图像过程的高级控制,如压缩选项、分辨率设置、...

    webp-imageio-10.和1.6(不要积分)

    1. **读取图像**:使用`javax.imageio.ImageIO.read()`方法,可以读取各种支持的图像格式,如JPEG、PNG等,添加WebP插件后,也可以读取WebP格式。 2. **写入图像**:`javax.imageio.ImageIO.write()`方法用于将...

    tesseract识别中文的com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam.rar

    TIFF(Tagged Image File Format)是一种广泛使用的图像文件格式,尤其适用于包含多页或不同类型的图像,如扫描的文档。`com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam`是Java中的类,用于控制TIFF图像的...

    imageIo.dll.zip

    1. 图像读取与写入:ImageIo.dll支持多种常见的图像格式,如JPEG、PNG、BMP、GIF等,允许开发者轻松地从磁盘读取图片,并将其保存为不同的文件格式。 2. 图像格式转换:通过ImageIo.dll,开发者可以方便地将一种...

    webp-imageio-0.4.2.zip

    2. **写入 WebP 图像**:利用 ImageIO.write() 方法,将 Java 中的 BufferedImage 对象转换为 WebP 格式,进行文件保存或网络传输。 3. **支持透明度和动画**:由于 WebP 支持透明通道(Alpha 通道),这个库同样...

    javax.imageio-1.0.5.jar

    javax.imageio-1.0.5.jar, java处理图片的库。 从maven中央仓库下载的。实测可用。

    imageio-2.5.0.tar.gz

    image = imageio.imread('example.png') # 显示图片(需额外引入matplotlib库) import matplotlib.pyplot as plt plt.imshow(image) plt.show() ``` 总结,imageio是Python中一个强大且易用的图像和视频处理库,...

    jai_imageio.jar

    java高级图片处理工具 jai-imageio,可以修改图片分辨率等

    webp-imageio.7z

    它包含了各种功能,如将其他格式(如JPEG或PNG)转换为WebP,以及从WebP文件中提取元数据等。这个版本可能是较早的,但仍然包含了处理WebP文件的基本工具和库文件。 3. **cmake-3.1.0-rc2-Linux-i386.tar.gz**:这...

    webp-imageio built for x64

    java环境下生成webp文件所用到的库,libwebp-imageio.so for Linux,webp-imageio.dll for Windows,webp-imageio-1.0.0.jar for java project。项目文件:https://bitbucket.org/luciad/webp-imageio

    Java提取IPA中的png文件, 并进行解码还原png图片

    6. **保存或显示图片**:解码后的`BufferedImage`对象可以直接在Java环境中显示,也可以通过`ImageIO.write()`方法保存为新的PNG文件,这样就可以在任何支持PNG的平台上正常显示了。 7. **异常处理**:在整个过程中...

    详解Java中使用ImageIO类对图片进行压缩的方法

    本文将详细介绍如何使用 `ImageIO` 类来压缩图片,并按指定比例调整图片的宽高。 首先,我们需要了解 `ImageIO` 类的基本用法。`ImageIO` 提供了 `read()` 方法用于读取图像文件,`write()` 方法用于写入图像文件。...

    imageio源码深度学习

    在imageio-2.2.0的`README`中,通常会包含项目简介、安装指南、使用示例、API文档链接以及贡献和报告问题的指引。对于初学者,这是一份宝贵的资源,可以帮助快速上手并理解imageio的功能和工作方式。 imageio的源码...

    TwelveMonkeysImageIO:JavaImageIO的一个插件和扩展集合

    《TwelveMonkeys ImageIO:Java ImageIO的增强与扩展》 在Java开发领域,图像处理是一项不可或缺的任务,而Java自带的...对于需要处理多种格式图片,或者对性能有较高要求的Java项目,这是一个值得推荐的解决方案。

    Python-Imageio是一个Python库提供了一个简单的接口来读取和写入各种图像数据

    Imageio的核心功能在于其支持的广泛格式,包括但不限于JPEG、PNG、BMP、Tiff、GIF、PPM、PGM、PBM、WebP等常见图像格式,以及AVI、MP4、MOV等视频格式。此外,它还能处理一些科学图像格式,如Numpy数组和TIFF堆栈。...

    imageio-2.3.0-py2.py3-none-any.whl

    imageio 2.3.0版本,下载到本地进行安装,直接pip安装可能因为下载文件速度太慢而报错。安装方法:1.打开cmd 2.安装whl文件,pip install imageio-2.3.0-py2.py3-none-any.whl(依赖会自行安装,下载速度还可以)

    jai_codec-1.1.3.jar jai_core.jar jai_imageio.jar jimi-1.0.jar

    jai_codec-1.1.3.jar jai_core.jar jai_imageio.jar jimi-1.0.jar

Global site tag (gtag.js) - Google Analytics