Java透明PNG到剪贴板

时间:2013-01-23 20:55:14

标签: java png clipboard transparent

我正在尝试将png文件复制到程序中的剪贴板,并在粘贴到另一个程序(例如ms office,paint,photoshop)时保持其alpha通道。问题是,在大多数程序中alpha通道变黑。我一直在网上搜索几个小时,但找不到解决方案。我正在使用的代码:

setClipboard(Toolkit.getDefaultToolkit().getImage(parent.getSelectedPicturePath()));

public static void setClipboard(Image image) {
    ImageSelection imgSel;
if (OSDetector.isWindows()) {
    imgSel = new ImageSelection(image);
} else {
    imgSel = new ImageSelection(getBufferedImage(image));
}
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
}

有没有办法在Java中维护alpha通道?我已经尝试将png转换为BufferedImage,Image等,并将其粘贴到剪贴板,但没有任何效果。

2 个答案:

答案 0 :(得分:1)

这是一个非常简单,自包含的示例。阅读或创建图像取决于您。此代码只是在alpha类型的BufferedImage上创建一个红色圆圈。当我将其粘贴到任何支持透明度的程序中时,它会正确显示。希望它有所帮助。

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class CopyImageToClipboard {
    public void createClipboardImageWithAlpha() {
        //Create a buffered image of the correct type, with alpha.
        BufferedImage image = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        //Draw in the buffered image.
        g2d.setColor(Color.red);
        g2d.fillOval(10, 10, 580, 580);

        //Add the BufferedImage to the clipboard with transferable image flavor.
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable transferableImage = getTransferableImage(image);
        clipboard.setContents(transferableImage, null);
    }

    private Transferable getTransferableImage(final BufferedImage bufferedImage) {
        return new Transferable() {
            @Override
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[] { DataFlavor.imageFlavor };
            }

            @Override
            public boolean isDataFlavorSupported(DataFlavor flavor) {
                return DataFlavor.imageFlavor.equals(flavor);
            }

            @Override
            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                if (DataFlavor.imageFlavor.equals(flavor)) {
                    return bufferedImage;
                }
                return null;
            }
        };
    }
}

答案 1 :(得分:1)

假设WebSecurityConfigurerAdapter工作正常,我能够让OP的代码在运行Oracle JDK 1.8.0_131的64位Windows Server 2008R2上开箱即用。 OP省略了OSDetector的代码,但我怀疑它是this blog版本的某种变体。

当我在Windows上使用博客版getBufferedImage()测试代码时(忽略getBufferedImage()检查),我能够重现整个图像为黑色的问题的变体,对OSDetectorImage.getWidth()Image.getHeight()的异步调用是一个时间问题,所有这些调用都会立即返回并带一个观察者进行异步更新。博客代码为所有这些调用传递Graphics.drawImage()(无观察者),并期望立即返回结果,而在我测试时则不是这样。

我修改null以使用回调后,我重现了确切的问题:Alpha通道显示为黑色。出现这种情况的原因是具有透明度的图像被绘制到默认为黑色画布的图形上下文中。如果您在黑色背景的网页上查看图像,您所看到的就是您所看到的。

为了改变这种情况,我使用了来自this StackOverflow answer的提示并将背景涂成了白色。

我使用了this site中的getBufferedImage()实现,该实现只是使用ImageSelectionImage实例封装在Transferrable中。

最终,对于我的测试,原始图像和缓冲图像变体都在Windows上运行。以下是代码:

DataFlavor.imageFlavor

我希望这会有所帮助。祝你好运。