Java: sketching with transparency

I'm having trouble creating thumbnails of images with an alpha channel (transparency). The code I'm using 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 put, for example, a GIF image with a transparent background, I always get a black or color background.

EDIT:

This is called from the class using a sketch, I skipped the two-parameter version of the getThuimbnail () method for the last time:

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

Added methods used to obtain 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!

+4
source share
4 answers

Solved it using 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 image transparency.

+1
source

Scaling GIF images with transparent color should work fine. I agree with jarnbjo that the problem is most likely in generating a buffered generation.

Perhaps the following tips will help:

1) When creating the thumb, copy the type of image from the source, for example:

 BufferedImage thumb = new BufferedImage(fit, fit, image.getType()); 

2) Use the 2D approach:

 Graphics2D g = thumb.createGraphics(); 

Here is an example code for easy thumb creation (tested and working, GIF transparency inside, thumb keeping transparency):

  public static BufferedImage thumb(BufferedImage image, int fit) { //image = blur(image); BufferedImage thumb = new BufferedImage(fit, fit, image.getType()); Graphics2D g = thumb.createGraphics(); try { int width = image.getWidth(); int height = image.getHeight(); int sx1; int sy1; int sx2; int sy2; int tmp; if (height > width) { tmp = height - width; sx1 = 0; sy1 = tmp / 2; sx2 = width; sy2 = height - sy1; } else if (width > height) { tmp = width - height; sx1 = tmp / 2; sy1 = 0; sx2 = width - sx1; sy2 = height; } else { sx1 = 0; sy1 = 0; sx2 = width; sy2 = height; } g.drawImage( image, 0, 0, fit, fit, sx1, sy1, sx2, sy2, null ); } finally { g.dispose(); } return thumb; }//thumb 

Note: with a simple one, I mean that it will not produce high quality results if you try to scale too much in one step (for example, 2048 pixels, 100 pixels). You may need a multi-step approach, and probably you should contact AffineTransformOp for tips instead of using a graphics device.

+1
source

The code you use to write the file is correct, at least if you are using a format that supports transparency (like PNG). Most likely, bufferedThumb already damaged, so to help you, it would be more useful if you declared how you get bufferedImage and how you create bufferedThumb .

0
source

You can try it using the IO image library:

PFB code:

 package com.incture.thumbnail; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class Thumnail { public static void main(String[] args) { String source = "E:/Incture/APAutomation/NewWorkspace/BarCodeReading/download-button.gif"; String target = "E:/Incture/APAutomation/NewWorkspace/BarCodeReading/thumb1.jpg"; saveScaledImage(source, target); } public static void saveScaledImage(String filePath, String outputFile) { BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); try { Graphics g=img.getGraphics(); g.setColor(Color.white); g.fillRect(0, 0, img.getWidth(), img.getHeight()); g.drawImage(ImageIO.read(new File(filePath)), 0 , 0, 20, 20, null); ImageIO.write(img, "png", new File(outputFile)); System.out.println("done"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 
-one
source

Source: https://habr.com/ru/post/1299650/


All Articles