如何使用 Java 调整图像的大小?

我需要调整 PNG,JPEG 和 GIF 文件的大小。如何使用 Java 做到这一点?

169964 次浏览

加载完图片后,你可以试试:

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;
}

Java Advanced Image 现在是开源的,并提供您需要的操作。

如果你正在处理大图片或者想要一个漂亮的结果,在 java 中这不是一个简单的任务。仅仅通过 Graphics2D 的重新缩放操作不会创建高质量的缩略图。您可以使用 JAI 来完成,但是要获得看起来不错的东西所需的工作量比您想象的要多,而且 JAI 有一个令人讨厌的习惯,即使用 OutOfMemory 错误也会使您的 JVM 崩溃。

如果可以的话,我建议使用 ImageMagick 作为外部可执行文件。它使用简单,它做的工作正确,所以你不必。

你不需要一个库来做这件事,你可以用 Java 自己来做。

克里斯坎贝尔有一个优秀的和详细的文章对缩放图像-见 这篇文章

Chet Haase 和 Romain Guy 在他们的书 肮脏的有钱客户中也有关于图像缩放的详细且信息量很大的文章。

如果可以选择在机器上安装 Imagemagick,我建议使用 Im4java。它在命令行界面上只是一个非常薄的抽象层,但它的工作做得非常好。

FWIW 我刚刚发布了一个简单的 Java 图像缩放库,名为 Imgscalr(可在 玛文中心上获得)。

这个库实现了几种不同的图像缩放方法(包括 Chris Campbell 的增量方法和一些小的增强) ,如果你要求的话,它会为你选择最优的方法,或者给你最快的或者最好看的(如果你要求的话)。

用法非常简单,只是一堆静态方法。最简单的用例是:

BufferedImage scaledImage = Scalr.resize(myImage, 200);

所有操作都保持图像的原始比例,因此在这种情况下,你要求 imgscalr 调整图像的大小在200像素宽和200像素高的范围内,默认情况下,它会自动选择最好看和最快的方法,因为它没有指定。

我意识到一开始这看起来像是自我推销(的确如此) ,但是我花费了大量的时间在 google 上搜索同一个主题,不断得到不同的结果/方法/想法/建议,并决定坐下来写一个简单的实现,解决80-85% 的用例——你有一个图片,可能需要一个缩略图——要么尽可能快,要么尽可能好看(对于那些尝试过的人,你会注意到做一个图形化的图像即使双三次插值足够小,它看起来仍然像垃圾)。

Thumbnailator 是一个开源的 Java 图像调整库,具有流畅的界面,分布在 MIT 许可下。

我之所以编写这个库,是因为用 Java 制作高质量的缩略图可能非常困难,而且最终的代码可能会非常混乱。使用 Thumbnailator,可以使用简单流畅的 API 来表达相当复杂的任务。

举个简单的例子

举个简单的例子,将一张图片的大小调整为100x100(保留原始图片的高宽比) ,并将其保存到一个文件中,只需要一句话:

Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");

一个先进的例子

使用 Thumbnailator 流畅的界面可以简化复杂的大小调整任务。

假设我们想做以下事情:

  1. 在一个目录中获取图像,
  2. 调整大小为100x100,与原始图像的长宽比,
  3. 将它们全部保存为质量设置为 0.85的 JPEG 格式,
  4. 文件名取自原文,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 在 肮脏的有钱客户中突出显示的 渐进式双线性缩放方法,以生成高质量的缩略图,同时确保可接受的运行时性能。

您可以尝试将 图像处理系统Im4java一起用作 Java 的命令行接口。

GraphicsMagick 有很多优点,但对所有人来说只有一个:

  • 通用汽车被用来加工数十亿 世界上最大照片的文件 网站(例如 Flickr 和 Etsy)。

有人提到了图像魔法。有一个名为 JMagick 的 JNI 前端项目。它不是一个特别稳定的项目(而且 Image Magick 本身已经被认为会改变很多,甚至会破坏兼容性)。也就是说,我们在生产环境中使用 JMagick 和一个兼容的 Image Magick 版本来以高吞吐量、低延迟率执行扩展的经验很丰富。比起我们之前尝试的全 Java 图形库,速度要快得多。

Http://www.jmagick.org/index.html

我已经开发了一个解决方案与免费可用的类(AnimatedGifEncoder,GifDecder,和 LWZEncoder)可用于处理 GIF 动画。
您可以下载 jgifcode jar 并运行 GifImageUtil 类。 链接: http://www.jgifcode.com/rel = “ nofollow”http://www.jgifcode.com

您可以使用 Marvin (纯 Java 图像处理框架)进行这种操作: Http://marvinproject.sourceforge.net

扩展插件: Http://marvinproject.sourceforge.net/en/plugins/scale.html

JavaAPI 没有为图像提供标准的缩放特性,也没有降低图像质量。

正因为如此,我尝试从 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);

你可以使用以下流行的产品: 缩略图

如果你不想导入 ImgScalr像@Riyad Kalla 答案上面我测试太工程罚款,你可以这样做 来自 Peter Walser 回答@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;
}
}

简单地使用 Burkhard 的回答,但是在创建图形之后添加这一行:

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

你也可以给 BICUBIC 设定价值,它将产生更好的图像质量,但运营成本更高。还有其他渲染提示您可以设置,但我已经发现插值产生最显着的效果。 请记住,如果你想放大很多,Java 代码很可能会非常慢。我发现较大的图像开始产生300% 左右的延迟变焦,即使所有渲染提示设置为优化速度高于质量。

事实证明,编写性能定标器并非易事。我曾经为一个开源项目 ImageScaler这样做过。

原则上是这样。Image # getScaledInstance (int,int,int)’也可以完成这项工作,但是这里有一个令人讨厌的 bug ——详情请参考我的链接。

尝试以下方法:

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);

你也可以使用

Process p = Runtime.getRuntime().exec("convert " + origPath + " -resize 75% -quality 70 " + largePath + "");
p.waitFor();

首先设计 jLabel:

JLabel label1 = new JLabel("");
label1.setHorizontalAlignment(SwingConstants.CENTER);
label1.setBounds(628, 28, 169, 125);
frame1.getContentPane().add(label1);   //frame1 = "Jframe name"

然后你可以在代码下面编写代码(添加你自己的高度和宽度) :

ImageIcon imageIcon1 = new ImageIcon(new ImageIcon("add location url").getImage().getScaledInstance(100, 100, Image.SCALE_DEFAULT)); //100, 100 add your own size
label1.setIcon(imageIcon1);