You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing粘贴ChemDraw分子图透明区域变黑问题求助

解决ChemDraw分子图像粘贴到Java Swing时透明区域变黑的问题

问题场景

将ChemDraw(分子绘制工具)中复制的分子图像粘贴到Java Swing GUI时,使用以下代码实现:

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

public class Demo1 extends JFrame {
    public Demo1() throws UnsupportedFlavorException, IOException {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        BufferedImage image = (BufferedImage) clipboard.getData(DataFlavor.imageFlavor);
        JLabel imageLabel = new JLabel(new ImageIcon(image));
        imageLabel.setMinimumSize(new Dimension(200, 180));
        add(imageLabel);
        setSize(200, 180);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                new Demo1();
            } catch (UnsupportedFlavorException | IOException e) {
            }
        });
    }
}

图像显示正常,但透明区域变为黑色。该问题与同类场景一致,解决方案指向使用支持image\x-emf MIME类型的自定义系统格式,去除前8字节后转为BufferedImage。

剪贴板内容探查

为确定正确的图像来源,使用以下代码探查剪贴板内容:

import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.imageio.ImageIO;

public class Demo2 {
    public static void main(String[] args) {
        String[] formats = new String[] { "ChemDraw Interchange Format", "Embed Source",
                "Object Descriptor", "CF_ENHMETAFILE", "CF_METAFILEPICT", "ChemDraw Structure Data",
                "MDLSK", "MDLCT", "SMILES", "SLNSTRING" };

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
        int i = 0;
        for (String format : formats) {
            // The exact MIME is not important for getting from clipboard. There are could
            // be anything
            DataFlavor newDataFlavor = new DataFlavor(
                    "app/format" + (i++) + ";class=java.io.InputStream", format);
            systemFlavorMap.addFlavorForUnencodedNative(format, newDataFlavor);
        }
        Transferable transferable = clipboard.getContents(null);
        i = 0;
        for (String format : formats) {
            System.out.println(format);
            DataFlavor newDataFlavor = new DataFlavor(
                    "app/format" + (i++) + ";class=java.io.InputStream", format);
            if (transferable.isDataFlavorSupported(newDataFlavor)) {
//              Only ENHMETAFILE and METAFILEPICT didn't take "true"
                System.out.println(true);
                try {
                    InputStream data = (InputStream) clipboard.getData(newDataFlavor);
                    byte[] bytes = data.readAllBytes();
                    System.out.print(new String(bytes, StandardCharsets.UTF_8));
                    System.out.print("\n\n");

//                  Trying to make image
                    InputStream inputStream = new ByteArrayInputStream(bytes);
                    BufferedImage image = ImageIO.read(inputStream);
//                  I didn't have any success(
                    if (image != null) System.out.println("SUCCESS");
                } catch (Exception e) {
                }
            }
            System.out.println();
        }
    }
}

探查结果显示:CF_ENHMETAFILE和CF_METAFILEPICT无法通过该方式访问;Object Descriptor、MDLCT、SMILES、SLNSTRING、MDLSK、ChemDraw Interchange Format、Embed Source均非图像来源。

JavaFX的异常情况

与Swing不同,JavaFX无法检测到剪贴板中的图像,测试代码如下:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.input.Clipboard;
import javafx.stage.Stage;

public class Demo3 extends Application {
    @Override
    public void start(Stage primaryStage) {
        Clipboard clipboard = Clipboard.getSystemClipboard();
        System.out.print(clipboard.hasImage()); // Prints false     
        Platform.exit();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

求助需求

  1. 解决Java Swing中粘贴ChemDraw分子图像时透明区域变黑的问题
  2. 找到从剪贴板获取ChemDraw图像的正确方式

内容的提问来源于stack exchange,提问作者Senti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:14:56