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

发布于 2024-07-08 04:57:02 字数 54 浏览 5 评论 0原文

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

I need to resize PNG, JPEG and GIF files. How can I do this using Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

心清如水 2024-07-15 04:57:03

如果可以选择在您的机器上安装 imagemagick,我推荐 im4java。 它是命令行界面上一个非常薄的抽象层,但它的工作非常好。

If, having imagemagick installed on your maschine is an option, I recommend im4java. It is a very thin abstraction layer upon the command line interface, but does its job very well.

假面具 2024-07-15 04:57:03

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

The Java API does not provide a standard scaling feature for images and downgrading image quality.

Because of this I tried to use cvResize from JavaCV but it seems to cause problems.

I found a good library for image scaling: simply add the dependency for "java-image-scaling" in your pom.xml.

<dependency>
    <groupId>com.mortennobel</groupId>
    <artifactId>java-image-scaling</artifactId>
    <version>0.8.6</version>
</dependency>

In the maven repository you will get the recent version for this.

Ex. In your java program

ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
我也只是我 2024-07-15 04:57:03

您可以尝试将 GraphicsMagick 图像处理系统im4java 作为 Java 的命令行接口。

GraphicsMagick 的优点有很多,但有一个优点是:

  • GM 用于处理数十亿个数据
    世界上最大的照片文件
    网站(例如 Flickr 和 Etsy)。

You could try to use GraphicsMagick Image Processing System with im4java as a comand-line interface for Java.

There are a lot of advantages of GraphicsMagick, but one for all:

  • GM is used to process billions of
    files at the world's largest photo
    sites (e.g. Flickr and Etsy).
北方。的韩爷 2024-07-15 04:57:03

Image Magick 已被提及。 有一个名为 JMagick 的 JNI 前端项目。 这不是一个特别稳定的项目(众所周知,Image Magick 本身会发生很大的变化,甚至破坏兼容性)。 也就是说,我们在生产环境中使用 JMagick 和 Image Magick 的兼容版本以高吞吐量、低延迟率执行缩放方面拥有良好的经验。 速度比我们之前尝试过的全 Java 图形库要快得多。

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

Image Magick has been mentioned. There is a JNI front end project called JMagick. It's not a particularly stable project (and Image Magick itself has been known to change a lot and even break compatibility). That said, we've had good experience using JMagick and a compatible version of Image Magick in a production environment to perform scaling at a high throughput, low latency rate. Speed was substantially better then with an all Java graphics library that we previously tried.

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

漫漫岁月 2024-07-15 04:57:03

只需使用 Burkhard 的答案,但在创建图形后添加此行:

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

您还可以将值设置为 BICUBIC,它将产生更好质量的图像,但操作成本更高。 您还可以设置其他渲染提示,但我发现插值产生最显着的效果。
请记住,如果您想要放大很多,Java 代码很可能会非常慢。 我发现较大的图像开始在 300% 缩放时产生延迟,即使所有渲染提示都设置为优化速度而不是质量。

Simply use Burkhard's answer but add this line after creating the graphics:

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

You could also set the value to BICUBIC, it will produce a better quality image but is a more expensive operation. There are other rendering hints you can set but I have found that interpolation produces the most notable effect.
Keep in mind if you want to zoom in in a lot, java code most likely will be very slow. I find larger images start to produce lag around 300% zoom even with all rendering hints set to optimize for speed over quality.

故事灯 2024-07-15 04:57:03

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

缩放插件:
http://marvinproject.sourceforge.net/en/plugins/scale.html

You can use Marvin (pure Java image processing framework) for this kind of operation:
http://marvinproject.sourceforge.net

Scale plug-in:
http://marvinproject.sourceforge.net/en/plugins/scale.html

等待圉鍢 2024-07-15 04:57:03

事实证明,编写一个高性能的缩放器并不简单。 我为一个开源项目做过一次: ImageScaler

原则上“java.awt.Image#getScaledInstance(int, int, int)”也可以完成这项工作,但是这有一个令人讨厌的错误 - 有关详细信息,请参阅我的链接。

It turns out that writing a performant scaler is not trivial. I did it once for an open source project: ImageScaler.

In principle 'java.awt.Image#getScaledInstance(int, int, int)' would do the job as well, but there is a nasty bug with this - refer to my link for details.

亚希 2024-07-15 04:57:03

我开发了一个解决方案,其中包含可用于处理 GIF 动画的免费类(AnimatedGifEncoder、GifDecoder 和 LWZEncoder)。
您可以下载 jgifcode jar 并运行 GifImageUtil 类。
链接:http://www.jgifcode.com

I have developed a solution with the freely available classes ( AnimatedGifEncoder, GifDecoder, and LWZEncoder) available for handling GIF Animation.
You can download the jgifcode jar and run the GifImageUtil class.
Link: http://www.jgifcode.com

看轻我的陪伴 2024-07-15 04:57:03

您可以使用以下热门产品:thumbnailator

you can use following popular product: thumbnailator

安人多梦 2024-07-15 04:57:03

如果您不想导入 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;
        }
    }

If you dont want to import imgScalr like @Riyad Kalla answer above which i tested too works fine, you can do this
taken from Peter Walser answer @Peter Walser on another issue though:

 /**
     * 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;
        }
    }
旧伤还要旧人安 2024-07-15 04:57:03

尝试以下方法:

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

Try this folowing method :

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);
情域 2024-07-15 04:57:03

你也可以使用

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

you can also use

Process p = Runtime.getRuntime().exec("convert " + origPath + " -resize 75% -quality 70 " + largePath + "");
            p.waitFor();
情深缘浅 2024-07-15 04:57:03

首先设计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);

Design jLabel first:

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

Then you can code below code(add your own height and width):

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);
薄暮涼年 2024-07-15 04:57:02

FWIW 我刚刚发布了(Apache 2,托管在 GitHub 上)一个简单的 Java 图像缩放库,名为 imgscalr (可在 Maven 中心 上获取)。

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

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

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

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

我一开始就意识到这看起来像是自我推销(确实如此),但我花了相当多的时间在谷歌上搜索这个完全相同的主题,并不断提出不同的结果/方法/想法/建议,并决定坐下来写一篇简单的实现可以解决 80-85% 的用例,在这些用例中,您有图像并且可能需要它的缩略图 - 要么尽可能快,要么尽可能好看(对于那些尝试过的人,您会注意到即使使用 BICUBIC 插值到足够小的图像进行 Graphics.drawImage,它仍然看起来像垃圾)。

FWIW I just released (Apache 2, hosted on GitHub) a simple image-scaling library for Java called imgscalr (available on Maven central).

The library implements a few different approaches to image-scaling (including Chris Campbell's incremental approach with a few minor enhancements) and will either pick the most optimal approach for you if you ask it to, or give you the fastest or best looking (if you ask for that).

Usage is dead-simple, just a bunch of static methods. The simplest use-case is:

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

All operations maintain the image's original proportions, so in this case you are asking imgscalr to resize your image within a bounds of 200 pixels wide and 200 pixels tall and by default it will automatically select the best-looking and fastest approach for that since it wasn't specified.

I realize on the outset this looks like self-promotion (it is), but I spent my fair share of time googling this exact same subject and kept coming up with different results/approaches/thoughts/suggestions and decided to sit down and write a simple implementation that would address that 80-85% use-cases where you have an image and probably want a thumbnail for it -- either as fast as possible or as good-looking as possible (for those that have tried, you'll notice doing a Graphics.drawImage even with BICUBIC interpolation to a small enough image, it still looks like garbage).

若沐 2024-07-15 04:57:02

加载图像后您可以尝试:

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

After loading the image you can try:

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;
    }
笨笨の傻瓜 2024-07-15 04:57:02

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

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

一个简单的例子

举个简单的例子,拍摄一张图像并将其大小调整为 100 x 100(保留原始图像的纵横比),然后将其保存到文件中可以通过一条语句实现:

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

< strong>高级示例

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

假设我们想要执行以下操作:

  1. 将图像放入目录中,
  2. 将其大小调整为 100 x 100,纵横比与原始图像相同,
  3. 将它们全部保存为 JPEG,质量设置为 0.85
  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 的 Filthy Rich Clients 中强调的渐进式双线性缩放方法Guy 为了生成高质量的缩略图,同时确保可接受的运行时性能。

Thumbnailator is an open-source image resizing library for Java with a fluent interface, distributed under the MIT license.

I wrote this library because making high-quality thumbnails in Java can be surprisingly difficult, and the resulting code could be pretty messy. With Thumbnailator, it's possible to express fairly complicated tasks using a simple fluent API.

A simple example

For a simple example, taking a image and resizing it to 100 x 100 (preserving the aspect ratio of the original image), and saving it to an file can achieved in a single statement:

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

An advanced example

Performing complex resizing tasks is simplified with Thumbnailator's fluent interface.

Let's suppose we want to do the following:

  1. take the images in a directory and,
  2. resize them to 100 x 100, with the aspect ratio of the original image,
  3. save them all to JPEGs with quality settings of 0.85,
  4. where the file names are taken from the original with thumbnail. appended to the beginning

Translated to Thumbnailator, we'd be able to perform the above with the following:

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

A note about image quality and speed

This library also uses the progressive bilinear scaling method highlighted in Filthy Rich Clients by Chet Haase and Romain Guy in order to generate high-quality thumbnails while ensuring acceptable runtime performance.

太阳哥哥 2024-07-15 04:57:02

你不需要图书馆来做到这一点。 您可以使用 Java 本身来完成此操作。

Chris Campbell 对缩放图像有一篇精彩而详细的文章 - 请参阅这篇文章

Chet Haase 和 Romain Guy 在他们的书中也有关于图像缩放的详细且内容丰富的文章,Filthy Rich Clients

You don't need a library to do this. You can do it with Java itself.

Chris Campbell has an excellent and detailed write-up on scaling images - see this article.

Chet Haase and Romain Guy also have a detailed and very informative write-up of image scaling in their book, Filthy Rich Clients.

英雄似剑 2024-07-15 04:57:02

Java Advanced Imaging 现已开源,并提供您需要的操作。

Java Advanced Imaging is now open source, and provides the operations you need.

呆° 2024-07-15 04:57:02

如果您正在处理大图像或想要一个漂亮的结果,那么在 java 中这不是一个简单的任务。 仅通过 Graphics2D 的重新缩放操作来执行此操作不会创建高质量的缩略图。 您可以使用 JAI 来做到这一点,但它需要比您想象的更多的工作才能获得看起来不错的东西,而且 JAI 有一个令人讨厌的习惯,即用 OutOfMemory 错误来破坏您的 JVM。

如果可以的话,我建议使用 ImageMagick 作为外部可执行文件。 它使用简单,并且可以正确完成工作,因此您无需这样做。

If you are dealing with large images or want a nice looking result it's not a trivial task in java. Simply doing it via a rescale op via Graphics2D will not create a high quality thumbnail. You can do it using JAI, but it requires more work than you would imagine to get something that looks good and JAI has a nasty habit of blowing our your JVM with OutOfMemory errors.

I suggest using ImageMagick as an external executable if you can get away with it. Its simple to use and it does the job right so that you don't have to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文