假设它OSDetector
工作正常,我能够让 OP 的代码在运行 Oracle JDK 1.8.0_131 的 Windows Server 2008R2 64 位上开箱即用。OP 省略了 的代码getBufferedImage()
,但我怀疑它是此博客中版本的一些变体。
当我在 Windows 上使用博客的版本getBufferedImage()
(忽略OSDetector
检查)测试代码时,我能够重现整个图像为黑色的问题的变体,结果证明这是异步调用的时间问题Image.getWidth()
, Image.getHeight()
,和Graphics.drawImage()
,所有这些都立即返回并采取观察者进行异步更新。博客代码通过null
(无观察者)所有这些调用,并期望立即返回结果,而我测试时并非如此。
一旦我修改getBufferedImage()
为使用回调,我重现了确切的问题:alpha 通道显示为黑色。这种行为的原因是具有透明度的图像被绘制到默认为黑色画布的图形上下文中。您所看到的正是您在具有黑色背景的网页上查看图像时所看到的。
为了改变这一点,我使用了这个 StackOverflow 答案的提示并将背景涂成白色。
我使用了这个站点ImageSelection
的实现,它简单地将一个实例包装在using 中。Image
Transferrable
DataFlavor.imageFlavor
最终,对于我的测试,原始图像和缓冲图像变体都可以在 Windows 上运行。下面是代码:
public static void getBufferedImage(Image image, Consumer<Image> imageConsumer) {
image.getWidth((img, info, x, y, w, h) -> {
if (info == ImageObserver.ALLBITS) {
BufferedImage buffered = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = buffered.createGraphics();
g2.setColor(Color.WHITE); // You choose the background color
g2.fillRect(0, 0, w, h);
if (g2.drawImage(img, 0, 0, w, h, (img2, info2, x2, y2, w2, h2) -> {
if (info2 == ImageObserver.ALLBITS) {
g2.dispose();
imageConsumer.accept(img2);
return false;
}
return true;
})) {
g2.dispose();
imageConsumer.accept(buffered);
}
return false;
}
return true;
});
}
public static void setClipboard(Image image) {
boolean testBuffered = true; // Both buffered and non-buffered worked for me
if (!testBuffered) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new ImageSelection(image), null);
} else {
getBufferedImage(image, (buffered) -> {
ImageSelection imgSel = new ImageSelection(buffered);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
});
}
}
我希望这有帮助。祝你好运。