4

This program shall paste an image from clipboard into an ImageView (on Windows 10). Unfortunately the image is not correctly displayed.

public class PasteImageFromClipboard extends Application {

ImageView imageView = new ImageView();
Button bnPaste = new Button("Paste");

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

@Override
public void start(Stage stage) throws Exception {

    bnPaste.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
            Clipboard cb = Clipboard.getSystemClipboard();
            if (cb.hasImage()) {
                Image image = cb.getImage();
                imageView.setImage(image);
            }
        }
    });

    VBox vbox = new VBox();
    vbox.getChildren().addAll(bnPaste, imageView);
    Scene scene = new Scene(vbox);
    stage.setScene(scene);
    stage.setWidth(400);
    stage.setHeight(400);
    stage.show();
}
}

Steps to reproduce:

  • Start cmd.exe
  • Press ALT-Print to copy the cmd window into the clipboard
  • Start program PasteImageFromClipboard
  • Press "Paste" button in PasteImageFromClipboard

This result is displayed on my computer:

enter image description here

It should be like this:

enter image description here

Is there more code required to draw the image correctly?

wimix
  • 574
  • 1
  • 5
  • 16
  • 1
    Can you verify the image is "correct" in the clipboard (say by pasting it into another application)? It looks like the black window background is being shown as transparent. – James_D Jan 06 '16 at 21:46
  • Windows Paint and MS Word show the pasted image correctly. The example works correctly on other computers with Windows 7 Java8u65 and 2012 Java 8u66. – wimix Jan 07 '16 at 18:54
  • Any updates? java 8u101 on Win 10 and this issue persists – Shubham Sep 14 '16 at 11:39
  • I suspect this bug fix may have addressed the problem: https://bugs.java.com/view_bug.do?bug_id=8187928 I would try again with Java 1.8.0_172, when that version is available for general download. I assume the fix will be in the next release of Java 9 as well, though the bug page currently doesn’t mention it. – VGR Feb 22 '18 at 18:15
  • I'm experiencing the same problem, the image is all washed out. I'm using Java 1.8.0_202 – Brad Turek Mar 01 '19 at 17:18
  • After more research, it appears that certain pixels are getting set transparent: that's why the black part of the cmd window looks gray. The default background in JavaFX is showing through the image. – Brad Turek Mar 01 '19 at 18:31
  • Here's a [color checking TV graphic](https://i.stack.imgur.com/Q7kLH.png). The top is the original, the bottom is pasted into JavaFX on a `Color.ORANGE` background. White seems to come through, as well as yellows and pinks. What's going on here? @James_D, can you make any sense of this? I checked and the image is "correct"—I've tried with various images all with the same type of result. – Brad Turek Mar 04 '19 at 15:55

1 Answers1

3

found this solution by the help of https://community.oracle.com/thread/2238566

    package com.wilutions.jiraddin;

    import java.awt.Graphics;
    import java.awt.Toolkit;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.image.BufferedImage;
    import java.awt.image.RenderedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;

    import javax.imageio.ImageIO;

    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.image.ImageView;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;

    public class PasteImageFromClipboard extends Application {

        ImageView imageView = new ImageView();
        Button bnPaste = new Button("Paste");

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

        @Override
        public void start(Stage stage) throws Exception {

            bnPaste.setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent event) {
                    try {
                        java.awt.Image image = getImageFromClipboard();
                        if (image != null) {
                            javafx.scene.image.Image fimage = awtImageToFX(image);
                            imageView.setImage(fimage);
                        }
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

            VBox vbox = new VBox();
            vbox.getChildren().addAll(bnPaste, imageView);
            Scene scene = new Scene(vbox);
            stage.setScene(scene);
            stage.setWidth(400);
            stage.setHeight(400);
            stage.show();
        }

        private java.awt.Image getImageFromClipboard() {
            Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
            if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) {
                try {
                    return (java.awt.Image) transferable.getTransferData(DataFlavor.imageFlavor);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        private static javafx.scene.image.Image awtImageToFX(java.awt.Image image) throws Exception {
            if (!(image instanceof RenderedImage)) {
                BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null),
                        BufferedImage.TYPE_INT_ARGB);
                Graphics g = bufferedImage.createGraphics();
                g.drawImage(image, 0, 0, null);
                g.dispose();

                image = bufferedImage;
            }
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write((RenderedImage) image, "png", out);
            out.flush();
            ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
            return new javafx.scene.image.Image(in);
        }

    }
wimix
  • 574
  • 1
  • 5
  • 16
  • If I run this code, it works. If I integrate it into my JavaFX application, I get a `java.awt.HeadlessException`. It works when i set `java.awt.headless=fase` but this example doesn't do it either. Any idea why? – Michel Jung Nov 30 '17 at 21:02