-3

Not sure what I am doing wrong, but the image that is saved is the same as the original ~ 500px high. I am trying to set the image to 100px high and keep the aspectratio the same. Then save the smaller version.

BufferedImage original = ImageIO.read(inputStream);
Integer width = original.getWidth();
float aspectratio = (float)original.getWidth()/(float)original.getHeight();
Integer newwidth= Math.round(100*aspectratio);
BufferedImage scaledImage = new BufferedImage(newwidth,100,original.getType());
Graphics2D g = scaledImage.createGraphics();
g.drawImage(scaledImage,0,0,null);
g.dispose();
ImageIO.write(scaledImage, "PNG", result);
Harald K
  • 26,314
  • 7
  • 65
  • 111
mike628
  • 45,873
  • 18
  • 40
  • 57
  • You might Ike to consider having a look at [this example](http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928) and [this example](http://stackoverflow.com/questions/14115950/quality-of-image-after-resize-very-low-java/14116752#14116752) for some pointers on scaling images – MadProgrammer May 21 '14 at 21:18
  • 1
    Not the downvoter, but I would "guess" that the answer to your problem could be easily researched by googling, searching SO or reading the JavaDocs...at a "guess" – MadProgrammer May 22 '14 at 05:02
  • As you create `scaledImage` with explicit height `100`, there's no chance that the resulting image will be anything but 100 pixels tall. However, there's an obvious typo in your code, `g.drawImage(scaledImage,0,0,null)` draws `scaledImage` onto itself... So what you should have is a completely transparent or black image with the correct size. Unless there's something you've left out. ;-) – Harald K May 22 '14 at 07:53

2 Answers2

0

The problem is that drawImage(Image, int, int, ImageObserver) doesn't scale the image. Also, you are drawing the image to itself. You need to use the overload of drawImage that scales the image, like this:

// ...
Graphics2D g = scaledImage.createGraphics();
g.drawImage(original, 0, 0, scaledImage.getWidth(), scaledImage.getHeight(), 0, 0, original.getWidth(), original.getHeight(), null);
// ...

See more info on the JavaDocs for Graphics.

DankMemes
  • 2,085
  • 2
  • 21
  • 30
  • FYI although the OPs code will handle this, beware that this version of drawImage will stretch the image to meet the requirements of the destination width/height, without consideration of original images aspect ratio – MadProgrammer May 21 '14 at 21:19
  • The OP _had_ aspect ratio preserved in his new image size – DankMemes May 21 '14 at 22:27
  • Yes, I said that, but letting the OP know what the method does is always a nice heads-up ;) – MadProgrammer May 21 '14 at 23:36
  • The OP could have simply used `Image#getScaledInstance` and passed a `-1` to either width or height parameter and had the whole done for them as well, but wouldn't be my preferred solution ;) – MadProgrammer May 21 '14 at 23:37
0

Small example depending on your code

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;


public class ImageScaler {


    public static void main(String[] args) {
        try {
            // Load the original image
            BufferedImage image = ImageIO.read(new File(("PATH_TO_YOUR_ORIGINAL_IMAGE")));
            float wh = (float)image.getWidth()/(float)image.getHeight();
            int aspect = Math.round(100*wh);
            // get a scaledInstance from the original image depending on your
            // calculated aspectRation
            Image scaledInstance = image.getScaledInstance(aspect, 100, Image.SCALE_SMOOTH);
            // convert the Image to BufferedImage
            BufferedImage bi = getScaledBufferedImage(scaledInstance);
            // Write it out
            File outputFile = new File("PATH_TO_SAVE_THE_SCALED_VERSION");
            ImageIO.write(bi, "png", outputFile);
        } catch (IOException ex) {
            Logger.getLogger(ImageScaler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Converts a given Image instance to a BufferedImage
     * @param image
     * @return BufferedImage
     */
    private static BufferedImage getScaledBufferedImage(final Image image) {

        // check if image is instanceof BufferedImages
        if(image instanceof BufferedImage) {
            return (BufferedImage)image;
        }

        // create a new BufferedImage
        BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);

        // get the Graphics Object from the BufferedImage
        Graphics g = bi.getGraphics();
        // draw the Image to the BufferedImage
        g.drawImage(image, 0, 0, null);
        // dispose the Graphics
        g.dispose();

        return bi;
    }

}

Patrick

Patrick
  • 4,532
  • 2
  • 26
  • 32
  • 2
    Nice example, but why should the OP choose to use it? Also, you're not disposing of the graphics context which could, on some systems, prevent anything from been painted ;) – MadProgrammer May 21 '14 at 21:22
  • 1
    @MadProgrammer: If you want to be picky, `dispose()` should be invoked from a `finally` block, otherwise an exception may prevent disposal of the native graphics context. ;-) – Harald K May 22 '14 at 12:55