我有一张尺寸为800x800、大小为170 kb的图片。我想将这张图片调整为600x600的尺寸,并减小图像大小。如何实现?
我有一张尺寸为800x800、大小为170 kb的图片。我想将这张图片调整为600x600的尺寸,并减小图像大小。如何实现?
仅仅调整图片大小并不需要使用一个完整的图像处理库。
建议的方法是使用渐进双线性缩放,如下所示(可以直接在你的代码中使用此方法):
public BufferedImage scale(BufferedImage img, int targetWidth, int targetHeight) {
int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = img;
BufferedImage scratchImage = null;
Graphics2D g2 = null;
int w = img.getWidth();
int h = img.getHeight();
int prevW = w;
int prevH = h;
do {
if (w > targetWidth) {
w /= 2;
w = (w < targetWidth) ? targetWidth : w;
}
if (h > targetHeight) {
h /= 2;
h = (h < targetHeight) ? targetHeight : h;
}
if (scratchImage == null) {
scratchImage = new BufferedImage(w, h, type);
g2 = scratchImage.createGraphics();
}
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(ret, 0, 0, w, h, 0, 0, prevW, prevH, null);
prevW = w;
prevH = h;
ret = scratchImage;
} while (w != targetWidth || h != targetHeight);
if (g2 != null) {
g2.dispose();
}
if (targetWidth != ret.getWidth() || targetHeight != ret.getHeight()) {
scratchImage = new BufferedImage(targetWidth, targetHeight, type);
g2 = scratchImage.createGraphics();
g2.drawImage(ret, 0, 0, null);
g2.dispose();
ret = scratchImage;
}
return ret;
}
以下内容是从 Filthy Rich Clients 获取并经过修改和清理的代码。
根据您的评论,可以通过以下方式降低质量并对JPEG字节进行编码:
image
是BufferedImage对象。
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.2f); // Change this, float between 0.0 and 1.0
writer.setOutput(ImageIO.createImageOutputStream(os));
writer.write(null, new IIOImage(image, null, null), param);
writer.dispose();
现在,由于os
是一个ByteArrayOutputStream
,你可以对它进行Base64编码。
String base64 = Base64.encode(os.toByteArray());
ImageIO
实现此操作。 - LanguagesNamedAfterCofeeimport org.imgscalr.Scalr.*; // static imports are awesome with the lib
... some class code ...
// This is a super-contrived method name, I just wanted to incorporate
// the details from your question accurately.
public static void resizeImageTo600x600(BufferedImage image) {
ImageIO.write(resize(image, 600), "JPG", new File("/path/to/file.jpg"));
}
注意: 如果上面的看起来奇怪,静态导入允许我直接使用resize调用而不需要指定Scalr.resize(...)
此外,如果缩放后写出的图像质量不够好(尽管会快速地写出),您可以使用更多参数来调用resize方法,例如:
public static void resizeImageTo600x600(BufferedImage image) {
ImageIO.write(resize(image, Method.ULTRA_QUALITY, 600), "JPG", new File("/path/to/file.jpg"));
}
如果缩小图像使其看起来不够平滑,您甚至可以将BufferedImageOp应用于结果以软化它:
public static void resizeImageTo600x600(BufferedImage image) {
ImageIO.write(resize(image, Method.ULTRA_QUALITY, 600, Scalr.OP_ANTIALIAS), "JPG", new File("/path/to/file.jpg"));
}
您可以通过在Maven POM中添加以下依赖项来开始使用该库(imgscalr在Maven中央仓库中):
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
使用一些支持Java图像处理的好框架,例如IamageJ
此外,Java还通过一些类提供了基本的支持,如MemoryImageSource和PixelGrabber。
ImageCompressionDemo
获取示例源代码。 - Andrew Thompson