Malakim Malakim - 4 months ago 16
Java Question

Java: Generating thumbnails with transparency

I'm having problems generating thumbnails of images with an Alpha channel (transparency). The code I use is this:

public void saveThumbnail(File file, String imageType) {
if (bufferedThumb == null) {
return;
}

if(bufferedImage.getColorModel().hasAlpha()) {
logger.debug("Original image has Alpha channel");
}

BufferedImage bi = new BufferedImage(bufferedThumb.getWidth(null), bufferedThumb.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.drawImage(bufferedThumb, 0, 0, null);
try {
ImageIO.write(bi, imageType, file);
} catch (IOException ioe) {
ioe.printStackTrace();
System.out.println("Error occured saving thumbnail");
}
}


However, if I supply for example a GIF image with a transparent background I always end up with a black or colored background.

EDIT:

This is how it's called from the class using the thumbnail, I missed the two-parameter version of the getThuimbnail()-method the last time:

Thumbnail th = new Thumbnail(file.getPath());
th.getThumbnail(100);


Added methods used for getting the images:

public Thumbnail(String fileName) {
try {
this.bufferedImage = ImageIO.read(new File(fileName));
} catch (IOException ex) {
logger.error("Failed to read image file: " + ex.getMessage());
}
}

public Image getThumbnail(int size) {
int dir = VERTICAL;
if (bufferedImage.getHeight() < bufferedImage.getWidth()) {
dir = HORIZONTAL;
}
return getThumbnail(size, dir);
}

/**
* Creates image with specifed max sized to a specified direction.
* Will use Image.SCALE_SMOOTH for scaling.
* @param size Maximum size
* @param dir Direction of maximum size - 0 = vertical, 1 = height.
* @return Resized image.
*/
public Image getThumbnail(int size, int dir) {
return getThumbnail(size, dir, Image.SCALE_SMOOTH);
}

/**
* Creates image with specified size.
* @param size Maximum size
* @param dir Direction of maximum size - 0 = vertical, 1 = height.
* @param scale Image.Scale to use for conversion.
* @return Resized image.
*/
public Image getThumbnail(int size, int dir, int scale) {
if (dir == HORIZONTAL) {
bufferedThumb = bufferedImage.getScaledInstance(size, -1, scale);
} else {
bufferedThumb = bufferedImage.getScaledInstance(-1, size, scale);
}
return bufferedThumb;
}


Thanks!

Answer

Solved it by using an AffineTransform scale operation:

AffineTransform af = new AffineTransform();
af.scale(scaleFactor, scaleFactor);

AffineTransformOp operation = new AffineTransformOp(af, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
bufferedThumb = operation.filter(bufferedImage, null);
return bufferedThumb;

This seems to preserve any transparency in the image.