Skip to content

Instantly share code, notes, and snippets.

@eagleon
Created June 20, 2012 06:06
Show Gist options
  • Save eagleon/2958383 to your computer and use it in GitHub Desktop.
Save eagleon/2958383 to your computer and use it in GitHub Desktop.
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment