我需要调整PNG,JPEG和GIF文件的大小。我怎么能用Java做到这一点?
答案 0 :(得分:178)
FWIW我刚刚发布了(Apache 2,托管在GitHub上)一个简单的Java图像缩放库,名为imgscalr(可在Maven central上找到)。
该库实现了一些不同的图像缩放方法(包括Chris Campbell的渐进式方法和一些小改进),如果您要求它,或者为您提供最佳或最佳的方法,请选择最佳方法(如果你要求的话)。
用法很简单,只是一堆静态方法。最简单的用例是:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
所有操作都保持图像的原始比例,因此在这种情况下,您要求imgscalr在200像素宽和200像素高的范围内调整图像大小,默认情况下,它会自动选择最佳外观和最快速的方法因为它没有指定。
我在一开始就意识到这看起来像是自我推销(它),但我花了相当多的时间在谷歌搜索这个完全相同的主题,并不断提出不同的结果/方法/想法/建议,并决定坐下来并写一个简单的实现,解决80-85%的用例,你有一个图像,可能需要一个缩略图 - 尽可能快或尽可能好看(对于那些尝试过的人,你我会注意到做了一个Graphics.drawImage,即使用BICUBIC插值到一个足够小的图像,它仍然看起来像垃圾。)
答案 1 :(得分:84)
加载图片后,您可以尝试:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
答案 2 :(得分:49)
Thumbnailator是一个用于Java的开源图像大小调整库,具有流畅的界面,分布在MIT license.
下我编写了这个库,因为在Java中制作高质量的缩略图可能会非常困难,并且生成的代码可能非常混乱。使用Thumbnailator,可以使用简单流畅的API表达相当复杂的任务。
一个简单的例子
举一个简单的例子,拍摄一张图像并将其大小调整为100 x 100(保留原始图像的宽高比),并将其保存到文件中可以在一个语句中实现:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
高级示例
使用Thumbnailator的流畅界面简化了复杂的大小调整任务。
我们假设我们想要做以下事情:
0.85
,thumbnail.
附加到开头转换为Thumbnailator,我们可以通过以下方式执行上述操作:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
关于图像质量和速度的说明
此库还使用Chet Haase和Romain Guy在Filthy Rich Clients中突出显示的渐进式双线性缩放方法,以便在确保可接受的运行时性能的同时生成高质量的缩略图。
答案 3 :(得分:11)
您不需要库来执行此操作。你可以用Java本身来做。
克里斯·坎贝尔(Chris Campbell)对缩放图像进行了精彩而详尽的报道 - 请参阅this article。
Chet Haase和Romain Guy在他们的书Filthy Rich Clients中也有一个详细而且非常丰富的图像缩放文章。
答案 4 :(得分:10)
Java Advanced Imaging现在是开源的,并提供您需要的操作。
答案 5 :(得分:9)
如果您正在处理大型图像或想要一个漂亮的结果,那么在java中这不是一项微不足道的任务。只需通过Graphics2D通过rescale op进行操作就不会创建高质量的缩略图。你可以使用JAI来完成它,但是它需要比你想象的更多的工作来获得看起来很好的东西而且JAI有一个讨厌的习惯,就是用OutOfMemory错误来破坏你的JVM。
如果您可以使用它,我建议您使用ImageMagick作为外部可执行文件。它使用简单,它可以正常工作,所以你不必这样做。
答案 6 :(得分:4)
如果您的机器上安装了imagemagick是一个选项,我建议im4java。它在命令行界面上是一个非常薄的抽象层,但它的工作非常好。
答案 7 :(得分:3)
Java API不为图像提供标准缩放功能并降低图像质量。
因此我尝试使用JavaCV中的cvResize,但它似乎会导致问题。
我找到了一个很好的图像缩放库:只需在pom.xml中添加“java-image-scaling”的依赖项。
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
在maven存储库中,您将获得最新版本。
实施例。在你的java程序中
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
答案 8 :(得分:2)
您可以尝试将GraphicsMagick Image Processing System与im4java一起用作Java的命令行界面。
GraphicsMagick有很多优点,但对所有人来说都是:
答案 9 :(得分:1)
Image Magick已被提及。有一个名为JMagick的JNI前端项目。这不是一个特别稳定的项目(而且已知Image Magick本身会发生很大的变化,甚至会破坏兼容性)。也就是说,我们在生产环境中使用JMagick和Image Magick的兼容版本以高吞吐量,低延迟率执行扩展已经有了很好的经验。使用我们之前尝试过的全Java图形库,速度要好得多。
答案 10 :(得分:1)
事实证明,编写高性能的缩放器并非易事。我为开源项目做了一次:ImageScaler。
原则上&#39; java.awt.Image#getScaledInstance(int,int,int)&#39;也会做这个工作,但这有一个讨厌的错误 - 请参阅我的链接了解详情。
答案 11 :(得分:1)
只需使用Burkhard的答案,但在创建图形后添加此行:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
您还可以将值设置为BICUBIC,它将生成质量更好的图像,但操作更昂贵。您可以设置其他渲染提示,但我发现插值产生最显着的效果。 请记住,如果你想要放大很多,java代码很可能会非常慢。我发现较大的图像开始产生大约300%变焦的延迟,即使所有渲染提示都设置为优化速度而不是质量。
答案 12 :(得分:1)
您可以使用Marvin(纯Java图像处理框架)进行此类操作: http://marvinproject.sourceforge.net
扩展插件: http://marvinproject.sourceforge.net/en/plugins/scale.html
答案 13 :(得分:0)
您可以使用以下热门产品:thumbnailator
答案 14 :(得分:0)
如果您不想导入imgScalr像@Riyad Kalla上面的答案,我测试过的也很好,你可以这样做 取自Peter Walser answer @Peter Walser的另一个问题:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}
答案 15 :(得分:0)
我开发了一个可用于处理GIF动画的免费类(AnimatedGifEncoder,GifDecoder和LWZEncoder)的解决方案。
您可以下载jgifcode jar并运行GifImageUtil类。
链接:http://www.jgifcode.com
答案 16 :(得分:0)
尝试以下方法:
ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);