[java] How can I resize an image using Java?

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

This question is related to java image resize

The answer is


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


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.


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


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

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.


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.


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


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.


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.


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


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


you can use following popular product: thumbnailator


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

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

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


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.


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.


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.


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


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


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

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

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.


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

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

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


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.


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.


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.


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


you can use following popular product: thumbnailator


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


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


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

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to image

Reading images in python Numpy Resize/Rescale Image Convert np.array of type float64 to type uint8 scaling values Extract a page from a pdf as a jpeg How do I stretch an image to fit the whole background (100% height x 100% width) in Flutter? Angular 4 img src is not found How to make a movie out of images in python Load local images in React.js How to install "ifconfig" command in my ubuntu docker image? How do I display local image in markdown?

Examples related to resize

Numpy Resize/Rescale Image AngularJS $watch window resize inside directive Input type "number" won't resize How can I make all images of different height and width the same via CSS? How to get full width in body element Rerender view on browser resize with React How to resize image automatically on browser width resize but keep same height? PHPExcel auto size column width Automatically resize images with browser size using CSS Change form size at runtime in C#