Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将图像对象复制到剪贴板时出错_Java_Clipboard - Fatal编程技术网

Java 将图像对象复制到剪贴板时出错

Java 将图像对象复制到剪贴板时出错,java,clipboard,Java,Clipboard,我试图将一个图像对象放入剪贴板,但我遇到了一个奇怪的错误 这就是问题所在 ByteArrayInputStream bis = new ByteArrayInputStream(clipboardObject.data); try(ObjectInput in = new ObjectInputStream(bis)) { ImageIcon img = (ImageIcon) in.readObject(); ImageTransferable t = new ImageTra

我试图将一个图像对象放入剪贴板,但我遇到了一个奇怪的错误

这就是问题所在

ByteArrayInputStream bis = new ByteArrayInputStream(clipboardObject.data);
try(ObjectInput in = new ObjectInputStream(bis)) {
    ImageIcon img = (ImageIcon) in.readObject();
    ImageTransferable t = new ImageTransferable(img.getImage());
    Toolkit.getDefaultToolkit().getSystemClipboard()
            .setContents(t, null);
} catch(Exception e) {
    e.printStackTrace();
}
这是我的
课程

static class ImageTransferable implements Transferable
{
    private Image image;

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

    public Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException
    {
        if (isDataFlavorSupported(flavor))
        {
            return image;
        }
        else
        {
            throw new UnsupportedFlavorException(flavor);
        }
    }

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

    public DataFlavor[] getTransferDataFlavors ()
    {
        return new DataFlavor[] { DataFlavor.imageFlavor };
    }
}
这就是我得到的错误

java.io.IOException:注册的服务提供商编码失败BufferedImage@5f341870:type=2 DirectColorModel:rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 integerinerInterleavedMaster:width=2227 height=2225#Bands=4 xOff=0 yOff=0 dataOffset[0]0到图像/jpeg
位于java.desktop/sun.awt.datatransfer.datatransfer.imageToStandardBytesImpl(未知源)
位于java.desktop/sun.awt.datatransfer.datatransfer.imageToStandardBytes(未知源)
位于java.desktop/sun.awt.windows.wdataTransfer.imageToPlatformBytes(未知源)
位于java.desktop/sun.awt.datatransfer.datatransfer.translateTransferable(未知源)
位于java.desktop/sun.awt.windows.wdataTransfer.translateTransferable(未知源)
位于java.desktop/sun.awt.windows.WClipboard.setContentsActive(未知源)
位于java.desktop/sun.awt.datatransfer.sunciplate.setContents(未知源)
位于com.bruhclp.ClipboardManager.setData(ClipboardManager.java:75)
位于com.bruhclp.Main.Main(Main.java:12)

做了一些研究后,OpenJDK实现中似乎不再支持JPEG图像的alpha通道。因此,您必须将要放入剪贴板的图像转换为
buffereImage。键入\u INT\u RGB

这就是你能做到的

ByteArrayInputStream bis = new ByteArrayInputStream(clipboardObject.data);
try(ObjectInput in = new ObjectInputStream(bis)) {
        ImageIcon img = (ImageIcon) in.readObject();
        Image original =  img.getImage();

        BufferedImage newImage = new BufferedImage(
                original.getWidth(null), original.getHeight(null), BufferedImage.TYPE_INT_RGB);

        Graphics2D g = newImage.createGraphics();
        g.drawImage(original, 0, 0, null);
        g.dispose();
        ImageTransferable t = new ImageTransferable(newImage);
        Toolkit.getDefaultToolkit().getSystemClipboard()
                .setContents(t, null);
}catch(Exception e)
{
        e.printStackTrace();
}
这不是错误,只是调试信息 请注意,控制台中显示的此异常实际上不是一个错误,也不是从
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(t,null)抛出的方法调用

Java中的JPEG现在不支持透明(),但是复制的图像实际上被压缩为PNG(或者其他格式),并且剪贴板被正确设置,即使使用
buffereImage.TYPE\u INT\u ARGB
image TYPE。至少在JDK14上它对我有效

因此,控制台中的这个异常只是一个调试信息(我已经调查了几个小时来理解它,并发现它确实有效)。答案在OpenJDK
sun.awt.windows.WClipboard.setContentsActive(可转移内容)
方法中:

         for (Long format : formatMap.keySet()) {
            DataFlavor flavor = formatMap.get(format);

            try {
                byte[] bytes = WDataTransferer.getInstance().
                    translateTransferable(contents, flavor, format);
                publishClipboardData(format, bytes);
            } catch (IOException e) {
                // Fix 4696186: don't print exception if data with
                // javaJVMLocalObjectMimeType failed to serialize.
                // May remove this if-check when 5078787 is fixed.
                if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) &&
                      e instanceof java.io.NotSerializableException)) {
                    e.printStackTrace();
                }
            }
        }
我希望这能节省别人的时间