首页 文章

如何使用透明填充缩放Graphics2D图像

提问于
浏览
3

我正在尝试编写一个小方法,它采用 BufferedImage 图像和新的宽度和高度,并通过根据图像向左/右或上/下添加透明边框来缩放图像以保持纵横比 . 缩放工作正常,但对于我的生活,我不能让边框透明 .

到目前为止,我有following code posted on pastebin.com可以很好地进行缩放 .

我已经阅读了很多手册和其他SO问题无济于事 . 我尝试了很多填充,复合类型,图像类型等的排列 . 有时我得到一个蓝色的背景,有时是白色但它似乎永远不会透明 .

BufferedImage newImg = new BufferedImage(newWidth, newHeight, img.getType());
Graphics2D g = newImg.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, newWidth, newHeight);
g.drawImage(img, x, y, x + scaledWidth, y + scaledHeight, 0, 0,
    currentWidth, currentHeight, Color.WHITE, null);
g.dispose();
return newImg;

知道我需要做什么Graphics2D才能使 Color.WHITE 背景透明并在新的上面绘制旧图像?谢谢你的帮助 .

Edit:

事实证明,我遇到的问题是我试图用JPEG图像生成透明色 . JPEG不支持透明度 . 咄 .

4 回答

  • 3

    我刚试了一下它就可以了 .

    只需将 Color.WHITE 替换为 new Color(0, 0, 0, 0) ,将 img.getType() 替换为 BufferedImage.TYPE_INT_ARGB .


    BufferedImage img = ImageIO.read(new File("image.png"));
    BufferedImage outImage = scaleWithPadding(img, 300, 100);
    ImageIO.write(outImage, "png", new File("newImage.png"));
    

    image.png: (204x53)

    enter image description here

    newImage.png: (300x100)

    enter image description here

  • 0

    我和你的帖子有相同的要求,how to make a color transparent上的这个页面给了我很多帮助 .

    这是我的最终代码:

    public BufferedImage getTransparentScaledImage(BufferedImage originalImage, int finalWidth, int finalHeight) {
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
    
        int newWidth;
        int newHeight;
        if (originalWidth == 0 || originalHeight == 0
                || (originalWidth == finalWidth && originalHeight == finalHeight)) {
            return originalImage;
        }
    
        double aspectRatio = (double) originalWidth / (double) originalHeight;
        double boundaryAspect = (double) finalWidth / (double) finalHeight;
    
        if (aspectRatio > boundaryAspect) {
            newWidth = finalWidth;
            newHeight = (int) Math.round(newWidth / aspectRatio);
        } else {
            newHeight = finalHeight;
            newWidth = (int) Math.round(aspectRatio * newHeight);
        }
    
        int xOffset = (finalWidth - newWidth) / 2;
        int yOffset = (finalHeight - newHeight) / 2;
    
        LoggerManager.getInstance().debug("frontoffice",
                "Image Servlet: [" + xOffset + "] [" + yOffset + "] [" + newWidth + "] [" + newHeight + "] [" + originalWidth + "] [" + originalHeight + "] [" + finalWidth + "] [" + finalHeight + "]");
    
        BufferedImage intermediateImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D gi = intermediateImage.createGraphics();
        gi.setComposite(AlphaComposite.SrcOver);
        gi.setColor(Color.WHITE);
        gi.fillRect(0, 0, finalWidth, finalHeight);
        gi.drawImage(originalImage, xOffset, yOffset, xOffset + newWidth, yOffset + newHeight, 0, 0, originalWidth, originalHeight, Color.WHITE, null);
        gi.dispose();
    
        //if image from db already had a transparent background, it becomes black when drawing it onto another
        //even if we draw it onto a transparent image
        //so we set it to a specific color, in this case white
        //now we have to set that white background transparent
        Image intermediateWithTransparentPixels = makeColorTransparent(intermediateImage, Color.WHITE);
    
        //finalize the transparent image
        BufferedImage finalImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gf = finalImage.createGraphics();
        gf.setComposite(AlphaComposite.SrcOver);
        gf.setColor(new Color(0, 0, 0, 0));
        gf.fillRect(0, 0, finalWidth, finalHeight);
        gf.drawImage(intermediateWithTransparentPixels, 0, 0, finalWidth, finalHeight, new Color(0, 0, 0, 0), null);
        gf.dispose();
    
        return finalImage;
    }
    
    public static Image makeColorTransparent(Image im, final Color color) {
        ImageFilter filter = new RGBImageFilter() {
            // the color we are looking for... Alpha bits are set to opaque
            public int markerRGB = color.getRGB() | 0xFF000000;
    
            public final int filterRGB(int x, int y, int rgb) {
                if ((rgb | 0xFF000000) == markerRGB) {
                    // Mark the alpha bits as zero - transparent
                    return 0x00FFFFFF & rgb;
                } else {
                    // nothing to do
                    return rgb;
                }
            }
        };
    
        ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
        return Toolkit.getDefaultToolkit().createImage(ip);
    }
    
  • 3

    我实施了上述解决方案(或非常相似),如果你不使用,请注意

    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
    graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON;
    

    您的图像将以非常差的质量生成(由于缩放)

  • 0

    您的原始 drawImage() 方法没有透明背景,因为正在使用背景颜色 . 替换为以下内容:

    g.drawImage(img, x, y, x + scaledWidth, y + scaledHeight, 0, 0, currentWidth, currentHeight, null);
    

相关问题