当前位置: 首页 > 知识库问答 >
问题:

Java透明PNG到剪贴板

许亦
2023-03-14

我试图将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转换为BuffereImage、Image等,并将其粘贴到剪贴板,但没有任何效果。

共有3个答案

丘智志
2023-03-14

这是一个非常简单、独立的示例。读取或创建图像取决于您。此代码只是在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;
            }
        };
    }
}
堵宪
2023-03-14

这是正确的答案吗?你试过这个吗?

    public void doCopyToClipboardAction()
{
  // figure out which frame is in the foreground
  MetaFrame activeMetaFrame = null;
  for (MetaFrame mf : frames)
  {
    if (mf.isActive()) activeMetaFrame = mf;
  }
  // get the image from the current jframe
  Image image = activeMetaFrame.getCurrentImage();
  // place that image on the clipboard
  setClipboard(image);
}


// code below from exampledepot.com
//This method writes a image to the system clipboard.
//otherwise it returns null.
public static void setClipboard(Image image)
{
   ImageSelection imgSel = new ImageSelection(image);
   Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
}


// This class is used to hold an image while on the clipboard.
static class ImageSelection implements Transferable
{
  private Image image;

  public ImageSelection(Image image)
  {
    this.image = image;
  }

  // Returns supported flavors
  public DataFlavor[] getTransferDataFlavors()
  {
    return new DataFlavor[] { DataFlavor.imageFlavor };
  }

  // Returns true if flavor is supported
  public boolean isDataFlavorSupported(DataFlavor flavor)
  {
    return DataFlavor.imageFlavor.equals(flavor);
  }

  // Returns image
  public Object getTransferData(DataFlavor flavor)
      throws UnsupportedFlavorException, IOException
  {
    if (!DataFlavor.imageFlavor.equals(flavor))
    {
      throw new UnsupportedFlavorException(flavor);
    }
    return image;
  }
}

资料来源:http://alvinalexander.com/java/java-copy-image-to-clipboard-example

我自己没试过,我也不确定。希望你得到正确的答案。

洪高阳
2023-03-14

假设OSDetector工作正常,我就能够在运行Oracle JDK 1.8.0131的Windows Server 2008R2 64位上,让OP的代码开箱即用。OP省略了GetBuffereImage()的代码,但是我怀疑它是这个博客版本的变体。

当我在Windows上使用博客版本的getBufferedImage()测试代码时(忽略OSDetector检查),我能够重现整个图像为黑色的问题变体,结果证明这是对图像的异步调用的时间问题。getWidth()图像。getHeight()图形。drawImage(),所有这些都会立即返回,并观察异步更新。博客代码通过所有这些调用的null(无观察者),并期望立即返回结果,而我测试时不是这样。

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

为了改变这一点,我使用了这个答案的提示,并将背景涂成白色。

在这个示例中,只需使用图像代码 就可以实现图像。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);
        });
    }
}

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

 类似资料:
  • 这是我目前拥有的:

  • 问题内容: 嘿,当我从png创建缩略图时,尝试保持png的透明度时遇到麻烦,有人对此有任何经验吗?任何帮助都会很棒,这是我目前正在做的事情: 问题答案: 过去,我已经成功地做到了: 我发现输出图像使用质量更好的比

  • 我正试图重新设计我的网站,使我原来的方形、基于瓷砖的图像渲染更像是图像的剪贴画。。。为了摆脱网格模式。 这是它最初的样子。。。 这是我想要的一个粗略的模型: 所以我重新保存了一个透明背景的图像缩略图。。。我只想让狗展示,正方形是透明的,可以在下面显示网站的背景。 然而,当我在页面上呈现它时,它的背景是黑色的。 我已经检查了我的CSS,看看是否有某种img类,或用于渲染漫画的类。。。甚至可以通过引导

  • 问题内容: 我正在使用以下代码读取PNG图片: 在显示时,有一个黑色背景,我知道是由PNG透明性引起的。 我找到了建议使用的解决方案,但是我不确定如何将其应用于上面的代码。 问题答案: 创建第二个类型… 将原件涂到副本上… 您现在有了图像的非透明版本… 要保存图像,请看写/保存图像

  • 在系统剪贴板上执行复制和剪贴操作 进程: 主进程, 渲染进程​ 复制字符串例子: 1 const {clipboard} = require('electron') 2 clipboard.writeText('Example String') Copied! 在X Window系统上,还有一个选择剪贴板。要操作它,你需要传递selection到每个方法: 1 const {clipboard}

  • 在系统剪贴板上执行复制和粘贴操作。 进程: Main, Renderer 下面的示例演示如何将字符串写入剪贴板: const { clipboard } = require('electron') clipboard.writeText('Example String') On Linux, there is also a selection clipboard. To manipulate it