# Copy/Paste klappt nicht einwandfrei



## kzimny (18. Okt 2012)

Hallo,

habe ein Problem mit der copy/paste Funktion bei gross dimensionierten Bildern ab ca. 1200px Breite. 
Mein Code scheint korrekt zu sein und funktioniert insofern, dass ich das Bild per copy aus einem anderen Werkzeug, z.B. Photoshop in die Java-Anwendung pasten kann.
Das Problem ist, dass das eingefügte Bild (nur ab 1200px Breite) nicht korrekt aus dem Clipboard "übergeben" und falsch dargestellt wird. Mit "übergeben" meine ich die gesuchte Problemstelle.


```
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        DataFlavor flavor = DataFlavor.imageFlavor;
        if (clipboard.isDataFlavorAvailable(flavor))
        {
            try {
                Image image = (Image) clipboard.getData(flavor);
                jLabel1.setIcon(new ImageIcon(image));
            } catch (UnsupportedFlavorException ex) {
                Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
```

Das Bild ist hier zu finden.
Und so sieht das Ergebnis aus.

Bei kleindimensionierten Bildern taucht das Problem nicht auf.

Danke für eure Hilfe! 
Viele Grüsse Krzysztof


----------



## Marco13 (18. Okt 2012)

Nochmal zu Klärung: 
Anwendung -> ClipBoard -> Java 
funktioniert nicht?

Und ... funktioniert
Anwendung -> ClipBoard -> AndereAnwendung
richtig?


----------



## kzimny (18. Okt 2012)

Photoshop -> Clipboard -> eigene Java Anwendung: Klappt bei gross dimensionierten Bildern nicht

Photoshop -> Clipboard -> Illustrator: klappt immer korrekt
Photoshop -> Clipboard -> Paint: klappt immer korrekt
PowerPoint -> Clipboard -> Paint: klappt immer korrekt


----------



## kzimny (22. Okt 2012)

Hallo, 
hat wirklich niemand eine Ahnung was das Problem verursacht?
Danke&Gruss
Krzysztof


----------



## Spacerat (22. Okt 2012)

Schuss ins Blaue: Der Java zugewiesene Speicher ist zu gering. Mehr zuweisen mit -Xms und -Xmx.


----------



## Marco13 (22. Okt 2012)

Naja, es scheinen ja schon alle Daten da zu sein, und ein OutOfMemoryError fliegt wohl auch nicht. Eine fundierte Begründung habe ich nicht, aber was viel erstaunlicher ist: Nichtmal irgendeine plausibel klingende Spekulation.... 

Mehr als ein bißchen "BlackBox-Debugging" würde mir da im Moment nicht einfallen. z.B. mal sehen, ob man die Bedingungen, wann das Problem auftritt, genauer eingrenzen kann. Z.B. mal ein Bild der Größe 1200x10 verwenden (oder 10x1200) um zu sehen, ob es an der Auflösung oder der Größe der Datenmenge liegt. Dann ggf. mal ein Bild mit vordefinierten Farben verwenden (z.B. ein Gradient-Fill) schauen, ob man eingrenzen kann, "an welcher Stelle" der Fehler auftritt. Evtl auch mal das Image in einen MediaTracker stecken und darauf warten, wer weiß was er bei halb-geladenen Bildern so alles macht... Oder mal 

```
Image image = (Image) clipboard.getData(flavor);

// Hier ggf. mit MediaTracker auf's Bild warten

BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.drawImage(image, 0,0, null);
g.dispose();
ImageIO.write(bi, "png", new File("DEBUG"+System.currentTimeMillis()+".PNG"); // als PNG raussschreiben
```
und schauen, wie das rausgeschriebene Bild aussieht. Ja, alles sehr hilflos, aber solange niemand "zielgerichterere" Ideen hat ... ist es zumindest eine Beschäftigung


----------



## Spacerat (22. Okt 2012)

Noch ein Schuss ins Blaue: Die Bildschirmauflösung 1280 = ~1200 ... das jetzt aber weit hergeholt.  Spekulationen, was bleibt einem übrig.


----------



## Empire Phoenix (22. Okt 2012)

Teste mal obs beim openjdk auch auftritt, (das teilt sich mit dem oracle ne gute menge an code)
Wenn ja dann kannste dort in die sources schauen und evtl wirste daraus dann schlauer.


----------



## kzimny (22. Okt 2012)

Super, danke für die Tipps! Ich habe eine heisse Spur. Das Problem liegt nicht im Java-Code, das steht schon fest.
Es sind die radiologischen Bilder welche mit 8 Bits Per Pixel (Grayscale) angefertigt werden.
Ab 24 Bits Per Pixel tritt bei mir das Problem nicht mehr auf, egal wie gross dimensioniert das Bild ist.
Jetzt ist nur die Frage, wie stelle ich ein solches Bild das mit 8 Bits Per Pixel angefertigt wurde im JLabel korrekt dar? Es tauchen auch Bilder mit 24 und 32 Bits Per Pixel auf.
Kann ich die Stufen irgendwie abfragen?

Gruss Krzysztof


----------



## Spacerat (22. Okt 2012)

Kann es sein? Wir hatten hier schon mal ein ähnliches Thema mit radiologischen Bildern, es ging damals um die Veränderung des Kontrasts. Diese Bilder hatten aber (bzw sollten) durchweg 16 Bit Grayscale. Dieser Thread zog sich auch ein wenig, aber bietet neben der eigentlichen Lösung auch Algos für 16 Bit Grayscale aus relativ beliebigen Farbtiefen. Leider funktioniert mein Ansatz dort seit Java 7 nicht mehr (Damit wäre nebenbei auch ein Grund erbracht, warum man von "sun."- und "com.sun."-Paketen die Finger lassen sollte ), aber das lässt sich evtl. beheben. Der Lademechanismus sollte auch recht einfach auf die Zwischenablage umgeleitet werden können. Ich setz' mich mal dran.
[EDIT]Hier noch mal ein genauerer Link zu dem Code, wo Bilder geladen und wenn nötig konvertiert werden. Der Loader beginnt in Zeile 177.[/EDIT]


----------



## Marco13 (22. Okt 2012)

Das schwierige ist, dass man ja nicht weiß, in welcher Form die Daten im Speicher liegen - man kann nur "auf gut Glück" ein Image draus machen, und hoffen, dass das ohne Unfälle hinhaut... Aber vielleicht findest du ja eine Lösung.


----------



## Spacerat (23. Okt 2012)

Juhu, es hat geklappt. Nur zwei Dinge stossen bitter auf:
1. Die Tatsache, dass das normale WritableRaster noch wie vor über keine "markDirty()"-Funktion verfügt. Aber von so etwas lasse ich mich nicht mehr hinreissen, wenn es sich mit kleinen Tricks umgehen lässt. 
2. Windows ist von Haus aus nicht in der Lage 16 Bit pro Farbkanal in die Zwischenablage zu kopieren. Ob das in professionellen Zeichenprogrammen genauso ist, entzieht sich meiner Kenntnis. Jedenfalls habe ich es nicht geschafft, das grosse 16 Bit Bild in ebenfalls 16 Bit zu verkleinern, damit es in ein forumkonformes Archiv passt.
Was mir beim betrachten der Bilder des TO aber aufgefallen ist; Die Daten sind schon alle vorhanden, nur nicht in korrekter Reihenfolge. Deswegen nehme ich auch an, dass der Fehler schon im Code des TO zu finden ist, nämlich genau da, wo er die Bilder offensichtlich falsch an die Bildschirmauflösung anpasst.
Wie dem auch sei. Mein Code beläuft sich inzwischen auf ca. 500 Zeilen und ist deshalb inkl. Code und einem Teil des im anderen Thread verlinkten Bildes als Archiv verfügbar.


----------



## kzimny (23. Okt 2012)

Hallo, erstmal tausend Dank für die Hinweise, den Lösungsansatz und die investierte Zeit.
Mein Problem ist mit dem Lösungsvorschlag von Spacerat nicht gelöst. Wenn im Programm von Spacerat über die Paste-Funktion das Bild  mit 8 Bits Pro Pixel übergeben wird, wird es genauso wie in meinem ersten Ansatz falsch dargestellt.
Mir geht nicht um die Veränderung von Helligkeit oder Kontrast. Die Antworten von Spacerat beziehen sich eher auf das Thema. Im Moment fehlt mir den Anhaltspunkt wo ich anknüpfen könnte.


----------



## kzimny (23. Okt 2012)

Neue Erkenntnis: das Problem tritt nur bei Java 1.6 auf. Unter Java 1.7 wird das Bild korrekt wiedergeben. Leider kann ich im Projekt nicht auf die neue Java-Version umschalten.
Bringt die Information etwas zur Lösung bei?


----------



## Spacerat (24. Okt 2012)

@kzimmy: Okay, sorry... Nicht dein Code ist fehlerhaft, sondern der von Java 6, wer ahnt denn so etwas. Mit anderen Worten, ich habe den Fehler nachvollzogen.
Mit diesem Fehler hast du dir aber was aufgerissen... Der Methodenaufruf endet keine 5 Delegationen weiter direkt auf der nativen Seite der JVM und zwar ohne dass man sieht, wie die Daten in die Image-Klasse geladen werden. Darüber hinaus findet man gar nichts über dieses merkwürdige Verhalten der JVM, am allerwenigsten einen Hinweis, was man dagegen machen kann. Evtl. kann man da, ausser ein JVM-Update auch leider gar nichts machen, nicht mal herausfinden ab welcher Breite das Problem auftritt. Denn wenn man genau hinsieht, erkennt man beim linken (also dem eigentlich rechten) Abschnitt unten eine Bildzeile, die offensichtlich nicht zum original Bild gehört. Demzufolge würde die dadurch überschriebene Originalzeile in einem "restauriertem" Bild links oben oder unten fehlen.

[OT]Das die Kontrasteinstellungen in meiner Anwendung immer noch vorhanden sind, liegt ganz einfach daran, das ich schlicht das Clipboard als Quelle hinzugefügt habe.[/OT]


----------



## kzimny (24. Okt 2012)

Dann werde ich das Projekt wohl auf die JVM 1.7 updaten müssen. Einen anderen Weg sehe ich persönlich auch nicht. Schade. Noch zur Klärung der merkwürdigen Zeile im Bild am unteren Rand: es handelt sich um die Windows-Taskleiste. Sie wurde im Print-Screen mit aufgenommen. Offenbar ist es nicht möglich herauszufinden wie die Daten in die Image-Klasse aus der Zwischenablage geladen werden. Gut, ich schliesse die Diskussion . Vielen Dank für Eure Hilfe und bis zum nächsten Mal. Viele Grüsse Krzysztof


----------

