# Vorhandenes Graphicsobjekt auf Componente zeichnen



## BlackCraze (10. Jan 2007)

Hallo an alle 

Meine Frage:

Es ist mir bekannt, dass ich mit der paint()-Methode einer JComponent auf irgendein Graphics-Objekt zeichen kann. Was ist aber, wenn ich ein schon fertiges Graphics-Objekt habe und dessen Inhalt sozusagen auf die JComponent (oder Panel oder was weiß ich - das ist nicht so wichtig) malen möchte?  ???:L 

Ich zerbrech mir schon ne ganze Weile den Kopf darüber und mir will einfach keine Lösung einfallen. Entweder ich steh total aufm Schlauch, oder ich weiß auch nicht ^^

Noch fürs Verständnis:

Graphics pagedGraphic = component.getGraphics().create(0, 612, 612, 953); //component ist eine JComponent
/*
 * und jetzt sowas wie:
 * pagedGraphic.paint(mySecondComponent);
 * nur, dass Graphics natürlich keine paintmethode hat
 * wollte nur verdeutlichen, was ich möchte 
 */

Danke
Der Craze


----------



## Wildcard (10. Jan 2007)

Der Fehler fängt schon bei getGraphics an. Diese Methode solltest du niemals(zumindest solange du nicht weißt warum man es nicht macht) aufrufen.
Wenn du das nicht getan hättest, wäre deine Frage also gar nicht aufgekommen  :wink:


----------



## BlackCraze (10. Jan 2007)

Tut mir leid, ich kann aus deinem Post keine Lösung für mich finden. Warum sollte ich das grapficsObjekt nicht abrufen dürfen?


----------



## Wildcard (10. Jan 2007)

Weil sowohl in Swing als auch in AWT passiv gezeichnet wird.
Du klaust dir nicht einfach ein dahergelaufenes Graphics Objekt und schmierst darauf rum, sondern du überschreibst paintComponent (bzw. paint) und wartest schön artig in der Ecke bis AWT dir ein Graphics Objekt gibt. Dann zeichnest du.


----------



## BlackCraze (10. Jan 2007)

Okay das sehe ich ein. Aber wie bekomme ich jetzt einen beliebigen ausschnitt einer Componente auf eine andere?


----------



## Wildcard (10. Jan 2007)

Versuch mal das gewünschte Ergebnis genauer zu beschreiben. Ich bin nicht sicher was du machen willst.


----------



## BlackCraze (10. Jan 2007)

ich habe eine riesige Componente, in die eine Grafik gezeichnet wurde. Diese Grafik soll als Bilddatei gespeichert werden. Leider geht es nicht, dass ich einfach ein Bild mit den ausmaßen dieser Componente erzeuge, da der Speicher dafür nicht ausreicht. Nun wollte ich einzelne Ausschnitte dieser großen Componente einzeln speichern. So dass ich sie danach evtl als PDF zusammenfügen könnte. Also ein Bildausschnitt pro Blatt oder so. 

Alternativ hatte ich auch überlegt die daten als bytestrom direkt an das ende der Bilddatei zu schreiben. Allerdings könnte ich es da nur unkomprimiert machen - was ziemlich viel speicher fressen wird, und außerdem muss man das Bild ja auch irgendwie wieder anzeigen können ^^. Deswegen wäre mir diese ausschnittsache lieber.


----------



## Wildcard (10. Jan 2007)

Der Speicher reicht nicht aus?  :shock: 
Wie groß ist denn ein 4GB großes Bild?


----------



## BlackCraze (10. Jan 2007)

ziemlich groß halt  es geht wirklich nicht ^^


----------



## Wildcard (10. Jan 2007)

Ok, versuch's mal so:
Erzeug dir ein BufferedImage und ruf darauf createGraphics auf (bei Images darf man das  :wink: )
dann rufst du auf dem Graphics Objekt setClip auf um einen Bereich festzulegen.
Anschließend die Komponente in das Graphicsobjekt zeichnen lassen.
Neuen Clip festlegen, wieder zeichnen lassen, usw.


----------



## BlackCraze (10. Jan 2007)

hatte ich schon getestet.
Das Problem dabei ist, dass mir java bereits beim Anlegen des BufferedImages schon sagt, dass der Speicher nicht reicht. Denn das Objekt des BufferedImages muss ja auch in den Speicher.


----------



## Wildcard (10. Jan 2007)

Das Image muss natürlich kleiner sein als die Komponente.
Wozu denn sonst der ganze Umstand mit dem Clip?  :?


----------



## BlackCraze (11. Jan 2007)

Funktioniert leider nicht. Damit kann ich immer nur das erste Bild erstellen. Wenn ich den Clip auf das kleine "bild" anwende, malt er mir ja trotzdem das obere normale bild hinein, nur mit ner schwarzen Ecke oben drin.

Wende ich den Clip auf das große bild an - also auf die Componente - Ist das der Gleiche effekt, da der sichtbare Bildausschnitt trotzdem noch dort positioniert ist, wo er ursprünglich war. Lasse ich jetzt die Componente auf das Graphics-object painten, habe ich wieder diese ecke :-/

zur sicherheit, dass wir das gleiche meinen:


```
BufferedImage img = new BufferedImage(953,612,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

g2d.setClip(0,300,953,612); //oder halt component.setClip...

component.paint(g2d);
```
wenn ich diesen Bildausschntt jetzt noch in die Obere Linke ecke positionieren könnte ohne das bild in der componente dauerhaft zu schädigen, würde es gehen. Den Clip brauche ich dann ja auch nicht mehr.


----------



## Wildcard (11. Jan 2007)

Ich dachte du willst das Bild schritt für Schritt rauskopieren?  ???:L 
Ich hatte das so gedacht das du einen Teil rauskopierst, speicherst, clip verschiebst, speicherst, usw.

Übrigens:
Ich hab spaßeshalber mal überschlagen wieviel Pixel die VM theoretisch im Speicher halten kann.
Wenn ich mich nicht blöd verrechnet habe sollten 9.000.000.000 Pixel drin sein ~30.000x30.000  :shock:


----------



## BlackCraze (11. Jan 2007)

das tue ich ja auch - die fixen zaheln habe ich nur geschrieben, damit ich nicht beim testen immer das ganze bild berechnen muss. das dauert ja ewig ^^

Edit:
der Clip ist ja nur wie eine "Maske", die über die gesamtgrafik gelegt wird. es wird in das kleine Bild mit 

component.paint(g2d);

ja immer nur der oberste linke teil landen. wenn der bildauschnitt daneben aber geclipt wird, ist das gespeierte Bild schwarz. Da über diesem Teil die Maske liegt.

und ja - es ist nunmal so groß ^^ - das momentane zwar nicht ("nur" 1580x67850), aber es kann durchaus so groß werden!


----------



## Wildcard (11. Jan 2007)

damn  :shock: 

Das Problem versteh ich jetzt aber immer noch nicht. Was tut an der clip Lösung nicht das was du willst?


----------



## BlackCraze (11. Jan 2007)

ich habs mal aufgemalt.
beim erstenmal klappt es noch. Danach ist jedes Bild schwarz. Ich müsste den zu speichernden bereich auch noch verschieben. Aber das, ohne das Bild kaputt zu machen


----------



## Wildcard (11. Jan 2007)

ok ok, sehe das Problem.
Versuch mal das Graphics vom BufferedImage bzw der Komponente auf Graphics2D zu casten und dann mit translate den Ursprungspunkt zu ändern.


----------



## BlackCraze (11. Jan 2007)

Jetzt dachte ich so bei mir *NATÜRLICH!!!* So muss es einfach klappen. Doch leider macht


```
BufferedImage img = new BufferedImage(953,612,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
component.getGraphics().setClip(0,300,953,612);
component.getGraphics().translate(0, 300);
component.paint(g2d);
```

das gleiche Bild wie


```
BufferedImage img = new BufferedImage(953,612,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
component.getGraphics().setClip(0,300,953,612);
//component.getGraphics().translate(0, 300);
component.paint(g2d);
```

und auch mit Casten gehts net. Das habe ich auch probiert:

((Graphics2D)component.getGraphics()).translate(0, 300);
((Graphics2D)component.getGraphics()).setClip(0,300,953,612);

habe auch den Clip und das translate mal getauscht. So als verzweiflungsakt ^^ - bringt auch nix


----------



## BlackCraze (11. Jan 2007)

hi ... es funktioniert

ich weiß zwar nicht warum, aber wenn man mit translate() den Koordinatenursprung Graphics-Objektes ins negative verschiebt, funktioniert es.


```
BufferedImage img = new BufferedImage(953,612,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();		
g2d.translate(0, -300);
g2d.setClip(0,300,953,612);
component.paint(g2d);
```

Die Zahlenwerte sind natürlich nur Beispielhaft 

Was man außerdem beachten sollte:
Wenn man mit Java5 arbeitet, bekommt man durch den FileSave-Dialog unter Umständen einen grauen "Kasten" auf das Bild. Das passiert meiner Meinung nach, weil der Dialog erst nach der Dateispeicherung geschlossen wird. Im Java6 habe ich das Problem allerdings nicht.

danke für die Hilfe 
so long

Craze


----------

