SVG Unterknoten extrahieren / Kartenspiel

Evil83

Grünschnabel
Hallo zusammen,

erst einmal danke für das nette Forum, auch wenn das hier mein erstes Posting ist, habt ihr mir doch schon indirekt geholfen und zwar hiermit.

Vielleicht bin ich ja auch aktuell auf den falschen Boot, weswegen ich vielleicht erstmal mein kleines Projekt beschreibe:
Ich bin gerade wiedermal dabei mich in Java einzuarbeiten, nachdem ich mehrmals schon was gemacht habe, aber immer halt nur soviel wie ich gerade brauchte - also eine Art Lernprojekt für mich.
Ich möchte mir gerne ein Java Programm basteln, welches ein Kartenspiel als Desktop Anwendung implementiert. Das Ganze soll dann stufenweise wachsen, Netzwerk, vielleicht KI mal sehen.
Aber erstmal bin ich bei den ganz grundlegenden Sachen: Oberfläche und Darstellung.

Nachdem ich mit AWT und BufferedImages angefangen habe bin ich nun bei Swing angekommen und versuche mich gerade daran SVGs als Kartengrafik zu nehmen.
Was ich gerne mit den Karten machen möchte ist:
- darstellen
- drehen
- highlighten, d.h. z.B. invertieren, Farbfilter oder irgendwas in der Richtung
Das ganze kann ich natürlich auf dem Grafikkontext des Fensters machen (dachte da an JPanel) - d.h. ich lese die SVGs ein, wandle sie irgendwie zu einem BufferedImage um indem ich sie raster und muss dann bei jeder Größenänderung des Fensters die Bilder wieder neurastern. Das dürfte machbar sein, wenn auch vielleicht nicht ganz sinnvoll.

Meine hoffentlich bessere Idee jetzt ist erstmal was anderes auszuprobieren: Karten von JComponent ableiten und als JSVGCanvas wie in der oberen Hilfe darstellen lassen. Der Vorteil ist, dass dort viel schon gemacht ist. Allerdings muss ich schauen, ob ich die Anordnung der Komponenten auf dem Panel dann so hinbekomme, wie ich das will... mal schauen.
Evtl eigene Panels definieren, mit eigenen LayoutManagern um z.B. eine Kartenhand darzustellen.

Frage 1 ist also:
Konzeptionell ist das so überhaupt möglich oder hab ich da was grundlegendes übersehen?


So, die andere Frage die ich habe betrifft SVG und Batik.
Ich habe aktuell Batik als Darstellungsengine für SVG genommen. Ist zwar etwas groß aber scheint relativ gut zu sein. Ich möchte nun folgendes machen: Ich habe im Internet eine "freie SVG Kartensammlung" gefunden. Das ist für mich ja eigentlich ideal.
Problematisch ist, dass das Bild die komplette Kartensammlung umfasst, aber netterweise hat der Autor die einzelnen Karten in Gruppen eingeteilt.
Meine Frage ist nun also:
Wie komme ich mit SVG an diese Untergruppen ran?!

Probiert habe ich folgendes:
Code:
try {
        Document oldDoc = f.createDocument("file:///C:/svg-cards.svg");       
        SVGDocument svgDoc = (SVGDocument) oldDoc;
        Element cardRoot = svgDoc.getElementById("1_club");
}
um bspw. das Pik Ass zu bekommen. Dann habe ich zwar den Oberknoten des Pik Asses, aber wie mache ich daraus nun ein eigenes Bild?
Wenn ich ein neues SVG Dokument bastel und einfach locker, frech fröhlich frei diesen Knoten als einziges Kind anhängen will, haut mir Java eine Exception um die Ohren, dass der Knoten nicht von dem Dokument erstellt wurde... da hat er Recht! Aber das ist ja auch der Sinn gewesen... klappt so für mich also nicht.

Oder kann ich dem SVG Bild sagen, bitte stelle mir nur diesen Knoten dar? Wenn ja, wie?
 
Ich habe selbst noch nicht so viel Ahnung von Java. Aber da Du ja nur die Bilder der Karten haben möchtest: versuche doch, die SVG-Datei mit Inkscape (für alle Betriebsysteme und kostenlos und nach meiner Erfahrung auch ziemlich gut) zu öffnen und dann für jede Gruppe ein Bild einzeln abzuspeichern. Ist zwar nicht so elegant wie Dein Versuch und mit etwas Klickarbeit behaftet, aber es kommt vermutlich das gleiche bei raus.
 
Das Thema ist mittlerweile über ein Jahr als, ob es überhaupt noch interessiert weiß ich zwar nicht, aber über Google findet man immer noch nicht wesentlich mehr zu derlei Suchbegriffen - deswegen antworte ich mir mal einfach selbst in der Hoffnung, dass es irgendwer irgendwann mal gebrauchen kann.

1) SVG Element <use>, welches man auch auf andere Grafikern verweisen kann.
Problem: Damit referenziert man nur das Bildelement - es steht aber noch an derselben STelle wie zuvor. Eigentlich mochte ich nur die Karte und damit in voller Sicht haben.
Das wäre Aufgabe einer ViewBox. Das mit Use irgendwie hinzubekommen ist mir bisher nicht gelungen.

2) Komplette Grafik laden und zurechtschneiden. Klappt freilich nur, wenn keine anderen Elemente drüber liegen, was für meinen Zweck aber ausreicht.
Dafür muss man sich den Rahmen der (Bounding)Box holen, die die Karte umfasst, mit SVGSalamander geht das in etwa skizziert so:
Code:
// Suche Bounding Box der Gruppe mit der ID - keine Ausnahmebehandlung
com.kitfox.svg.Group cardGroup = (com.kitfox.svg.Group) svgDiagram.getElement(cardID);
Rectangle2D boundingBox = cardGroup.getBoundingBox();
Dann die ViewBox des Bildes auf diese Box setzen (dafür muss man sie in einen String umwandeln) und das Dokument aktualisieren.
Sich dann ein BufferedImage besorgen, darauf den Graphic Kontext holen und das Dokument mittels svgRoot.render(G2D-Kontext) darauf rendern lassen.
(Böse Falle: svgDiagram.setIgnoringClipHeuristic(true) setzen)

Fertig und müsste mit eigentlich allen SVG Grafiken ähnlich laufen können
(vorausgesetzt die freizuziehenden Elemente sind nicht überlappend)
 
Zurück