2
\$\begingroup\$

I took a little heat on a method I had to resize an image and I'm hoping I can get a little help on the best way to do it. This is intended for a simple Java Helper Library I'm developing. I have a few ways to do it.

New Method:

/**
* This method resizes the given image
*
* @param image
* @param width
* @param height
* @param max if true, sets the width and height as maximum heights and widths, if false, they are minimums
* @return
*/
public static BufferedImage resizeImage(BufferedImage image, int width, int height, boolean max) {
  int type = (image.getTransparency() == Transparency.OPAQUE)
          ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
  BufferedImage bi = new BufferedImage(width, height, type);
  Graphics2D graphics = bi.createGraphics();
  graphics.drawImage(image, 0, 0, width, height, null);
  graphics.dispose();
  return bi;
}

Original Method:

/**
* This method resizes the given image
*
* @param width
* @param height
* @param max if true, sets the width and height as maximum heights and widths, if false, they are minimums
* @return
*/
public static ImageIcon resizeImage(ImageIcon imageIcon, int width, int height, boolean max) {
  Image image = imageIcon.getImage();
  Image newimg = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH);
  int width1 = newimg.getWidth(null);
  if ((max && width1 > width) || (!max && width1 < width)) {
    newimg = image.getScaledInstance(width, -1, java.awt.Image.SCALE_SMOOTH);
  }
  return new ImageIcon(newimg);
}

Are these kinds of convenience methods ok?

/**
* Convenience method. Creates ImageIcon from the given file location and calls resizeImage with it
*
* @param location
* @param width
* @param height
* @param max
* @return
*/
public static ImageIcon resizeImageFromFile(String location, int width, int height, boolean max) {
  ImageIcon imageIcon = new ImageIcon(location);
  return resizeImage(imageIcon, width, height, max);
}

/**
* Convenience method. Creates ImageIcon from the given resource location and calls resizeImage with it
*
* @param location
* @param width
* @param height
* @param max
* @return
*/
public static ImageIcon resizeImageFromResource(String location, int width, int height, boolean max) {
  ImageIcon imageIcon = new ImageIcon(SwingHelper.class.getResource(location));
  return resizeImage(imageIcon, width, height, max);
}
\$\endgroup\$
1
  • \$\begingroup\$ Doing this correctly (working around some bugs in the Java2D pipeline, incompatible image types or poorly chosen image types, etc.) is actually not as straight forward as it seems -- you might give imgscalr a try, this is exactly what it does (and all it does -- just some static methods) thebuzzmedia.com/software/imgscalr-java-image-scaling-library \$\endgroup\$ Apr 29 '12 at 21:55
2
\$\begingroup\$

Edit: about the new method, I'd say Graphics2D is a bit overkill (look at Konrad Rudolph's comment for another opinion). And you don't use the max parameter anymore. Does it stretch the image?

The original method is better, but you should have a real if else: resizing the image twice is a hack. It would look like this: you just have to fill in the if.

public static ImageIcon resizeImage(ImageIcon imageIcon, int width, int height, boolean max) {
  Image image = imageIcon.getImage();
  Image newimg;
  if(/* think what condition would work here */) {
    newimg = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH);
  } else {
    newimg = image.getScaledInstance(width, -1, java.awt.Image.SCALE_SMOOTH);
  }
  return new ImageIcon(newimg);
}

I think the helper methods are useless since there is no abstraction: it just does two separate things. This does not help that much, and it's better if opening the file is explicit: the code is easier to read.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ That’s wrong. Graphics2D is about painting on an image. It is not in any way about “displaying” images. It just so happens that most UI widgets manage their own drawing object rather than just the underlying buffered image (For performance reasons I imagine). That said, the new code doesn’t have any advantage over the old code in this particular instance. But as soon as you need to actually draw, use a Graphics2D object. \$\endgroup\$ Apr 26 '12 at 16:11
  • \$\begingroup\$ Reworded my answer. \$\endgroup\$ Apr 26 '12 at 19:05
  • \$\begingroup\$ Now I agree: for this case, it’s overkill. \$\endgroup\$ Apr 26 '12 at 19:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.