{"id":2250,"date":"2013-09-06T21:53:14","date_gmt":"2013-09-06T19:53:14","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2250"},"modified":"2013-09-06T21:53:15","modified_gmt":"2013-09-06T19:53:15","slug":"alles-wird-bunt-mit-farbmodellen","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/09\/alles-wird-bunt-mit-farbmodellen\/","title":{"rendered":"Alles wird bunt mit Farbmodellen"},"content":{"rendered":"<p>Ein besonderer Produzent, der sich um alles k\u00fcmmert, was das Bilderzeugen angeht, ist der <i>Image Producer<\/i>. Im Gegensatz dazu sind es die <i>Image Consumer<\/i>, die etwaige Bilddaten benutzen. Bei den Produzenten- und Konsumentenmodell von Image-Objekten stehen die Daten der Pixel immer in einem Byte- oder Integer-Feld zur Verf\u00fcgung und stehen im Mittelpunkt des Interesses. Oft \u00fcbersprungen wird das Farbmodell bei MemoryImageSource und einem createImage(). Doch das wollen wir uns nun genauer anschauen.<\/p>\n<p>Die Eintr\u00e4ge der Felder sind Pixel, und die Werte standen f\u00fcr Farbinformationen, genauer gesagt f\u00fcr Rot, Gr\u00fcn und Blau. Stillschweigend wird angenommen, dass diese in 24 Bit abgelegt sein m\u00fcssen. Dies muss jedoch nicht so sein, und die Interpretation der Farbwerte in einem Informationswort bestimmt ein Farbmodell. F\u00fcr Farbmodelle gibt es in Java die Klasse ColorModel. Mit der Klasse lassen sich dann aus einem Pixel die roten, gr\u00fcnen, blauen und transparenten Anteile bestimmen. Der transparente Teil, auch Alpha-Komponente genannt, bestimmt, in welcher Intensit\u00e4t die Farbinformationen wirken. Alpha-Werte lassen sich nur in Zusammenhang mit Bildern anwenden. Mit der Graphics-Klasse l\u00e4sst sich ein Alpha-Wert nicht einstellen, der dann alte Zeichenoperationen beeinflusst. Bei den Farbmodellen ist der Anteil der Transparenz genauso lang wie ein Farbwert, n\u00e4mlich acht Bit. Ein Wert von 255 sagt aus, dass der Farbwert zu 100% sichtbar ist. Ist der Wert 0, so ist die Farbe nicht zu sehen.<\/p>\n<p>Java macht das Programmierleben so plattformunabh\u00e4ngig wie m\u00f6glich. Bei wenigen oder vielen Farben auf der Zielplattform wird eine optimale Ann\u00e4herung an unsere Wunschfarben errechnet. So k\u00f6nnen wir alles in 24 Bit Farbtiefe errechnen, die Dislay-Komponente sucht die wichtigsten Farben heraus und fasst Gruppen \u00e4hnlicher Farben zusammen.<\/p>\n<p><b>Die abstrakte Klasse ColorModel<\/b><\/p>\n<p>Die abstrakte Klasse ColorModel beschreibt alle Methoden f\u00fcr konkrete Farbklassen, sodass die Informationen \u00fcber die Farbwerte und die Transparenz erreichbar sind. Obwohl die Klasse abstrakt ist, besitzt sie zwei Konstruktoren, die von den Unterklassen benutzt werden. Direkte Unterklassen sind ComponentColorModel, IndexColorModel und PackedColorModel.<\/p>\n<p><b>abstract class java.awt.image.ColorModel      <br \/>implements Transparency<\/b><\/p>\n<ul>\n<li>ColorModel( int pixel_bits, int bits[], ColorSpace cspace, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType ) <\/li>\n<li>ColorModel(int bits) <\/li>\n<\/ul>\n<p>Der zweite Konstruktor ist praktisch, da dieser nur die Farbtiefe in Bits erwartet. Diese abstrakte Klasse besitzt jedoch die statische Fabrik-Methode getRGBdefault(), die ein ColorModel-Objekt zur\u00fcckliefert. Das Standardfarbmodell, auch sRGB genannt, ist ein Farbmodell, welches die Werte als 24-Bit-Tupel mit den Komponenten Alpha, Rot, Gr\u00fcn und Blau enth\u00e4lt. Dieses Farbmodell l\u00e4sst sich etwa f\u00fcr ein Memory-Image einsetzen. Der erste Konstruktor ist noch leistungsf\u00e4higer und seit Java 1.2 dabei. Mit seiner Hilfe muss ein Farbwert nicht zwingend in einem Integer kodiert sein.<\/p>\n<p>Die Methode getPixelSize() liefert die Farbtiefe eines Farbmodells. Das Standardmodell besitzt eine Tiefe von 32 Bit (24 f\u00fcr die Farben und dann noch den Alpha-Kanal). So gibt auch die folgende Zeile als Anwort auf die Frage nach der Anzahl der Farben im Standardmodell 32 Bit aus:<\/p>\n<pre>System.out.println( ColorModel.getRGBdefault().getPixelSize() );<\/pre>\n<p>Die Hauptaufgabe einer Farbmodell-Klasse ist die Auswertung der Farbinformationen aus einem Speicherwort. Mit drei Methoden lassen sich die verschiedenen Farben auslesen. getRed(int pixel), getGreen(int pixel) und getBlue(int pixel), hinzu kommt noch getAlpha(int pixel). Jede dieser Methoden ist abstrakt und liefert eine Ganzzahl mit dem Farbwert zur\u00fcck. Wie wir sp\u00e4ter sehen werden, ist das einfachste Modell genau jenes, das wir bisher immer benutzt haben. Dieses liest n\u00e4mlich genau von den Stellen 24, 16 und 8 die Farbwerte aus. Da die Methoden abstrakt sind, m\u00fcssen Unterklassen dieses Verhalten programmieren.<\/p>\n<p>Eine weitere Methode ist getRGB(), welche ein int mit allen Farben im entsprechenden Farbformat zur\u00fcckliefert. Die Implementierung basiert auf den Anfrage-Methoden.<\/p>\n<pre>public int getRGB(int pixel) {\n  return (getAlpha(pixel) &lt;&lt; 24) | (getRed(pixel) &lt;&lt; 16) | (getGreen(pixel) &lt;&lt; 8) | (getBlue(pixel) &lt;&lt; 0);\n}<\/pre>\n<p>Im Folgenden eine Auflistung der wichtigsten Methoden:<\/p>\n<p><b>abstract class java.awt.image.ColorModel<br \/>\n    <br \/>implements Transparency<\/b><\/p>\n<ul>\n<li>abstract int getAlpha( int pixel )<br \/>\n    <br \/>Liefert den Alpha-Wert im Bereich 0 bis 255. <\/li>\n<li>abstract int getBlue( int pixel )<br \/>\n    <br \/>Liefert den Blauanteil des Pixels. <\/li>\n<li>ColorSpace getColorSpace()<br \/>\n    <br \/>Liefert den Farbraum, der mit dem ColorModel verbunden ist. <\/li>\n<li>int[] getComponents( int pixel, int components[], int offset )<br \/>\n    <br \/>Liefert ein Feld mit nicht normalisierter Farb- und Alpha-Komponente f\u00fcr ein Pixel. <\/li>\n<li>abstract int getGreen( int pixel )<br \/>\n    <br \/>Liefert den Gr\u00fcnanteil. <\/li>\n<li>int getNumColorComponents()<br \/>\n    <br \/>Gibt die Anzahl der Farben zur\u00fcck. <\/li>\n<li>int getNumComponents()<br \/>\n    <br \/>Liefert die Anzahl der Komponenten (mit Alpha). <\/li>\n<li>int getPixelSize()<br \/>\n    <br \/>Wie viele Pixel beschreiben eine Farbe? <\/li>\n<li>abstract int getRed( int pixel )<br \/>\n    <br \/>Liefert den Rotanteil. <\/li>\n<li>int getRGB( int pixel )<br \/>\n    <br \/>Gibt Farb- und Alpha-Komponente des Pixels im sRGB-Farbmodell wieder. <\/li>\n<li>static ColorModel getRGBdefault()<br \/>\n    <br \/>Liefert ein DirectColorModel mit dem sRGB-Modell. <\/li>\n<li>int getTransparency()<br \/>\n    <br \/>Liefert die Art der Transparenz. Dies ist entweder OPAQUE, BITMASK oder TRANSLUCENT. Es sind Konstanten aus der Schnittstelle Transparency. Sie k\u00f6nnen aber auch \u00fcber ColorModel verwendet werden, da ColorModel diese Schnittstelle implementiert. <\/li>\n<li>boolean hasAlpha()<br \/>\n    <br \/>Fragt an, ob das Farbmodell Transparenz unterst\u00fctzt. <\/li>\n<li>boolean isCompatibleRaster( Raster raster )<br \/>\n    <br \/>Liefert true, falls das Raster mit dem Farbmodell kompatibel ist. <\/li>\n<\/ul>\n<p>Nun lassen sich auf der Basis dieser Klassen verschiedene Farbmodelle entwerfen. Einige sind von den Entwicklern der Java-Bibliotheken schon vorgefertigt, wie etwa eine Farbklasse, die die Informationen gleich im Pixel selbst speichert, wie im Beispiel RGB, oder eine Klasse, die einen Index auf einen Farbwert verwaltet. Als eigene Erg\u00e4nzung k\u00f6nnen wir Farbklassen implementieren, die Graustufen direkt unterst\u00fctzen oder etwa andere Farbr\u00e4ume wie HSB (Hue, Saturation, Brightness). Die einzige Aufgabe, die uns als Implementierer der abstrakten Methoden \u00fcbrig bleibt, ist, die Farbwerte aus dem Pixelwert zu extrahieren. Im Fall von HSB ist das einfach. Die Methoden getRed(), getGreen() und getBlue() m\u00fcssen nur aus dem internen HSB-Wert den Anteil liefern.<\/p>\n<p><b>Farbwerte im Pixel mit der Klasse DirectColorModel<\/b><\/p>\n<p>Mit Hilfe der Klasse DirectColorModel werden die Farbwerte Rot, Gr\u00fcn, Blau und Alpha direkt aus dem Farbtupel extrahiert. Die Klasse geh\u00f6rt zu einer der gr\u00f6\u00dften im Image-Paket. Als Beispiel f\u00fcr das direkte Format kennen wir Standard-RGB. F\u00fcr dieses gilt, dass die Farben jeweils acht Bit in Anspruch nehmen. Das muss aber nicht so sein, und im Konstruktor von DirectColorModel l\u00e4sst sich bestimmen, wie und an welcher Stelle die Bits f\u00fcr die Farben sitzen. Wir d\u00fcrfen dies jedoch nicht damit verwechseln, dass wir die Anzahl der Bits angeben. Nur die Positionen sind m\u00f6glich. Daraus ergibt sich auch, dass die Werte zusammenh\u00e4ngend sind und nicht etwa Folgendes auftreten kann: 0xrrbgbg. Die Bitanzahl kann aber f\u00fcr die Farben unterschiedlich sein. Auch der Alpha-Wert kann frei gew\u00e4hlt werden. F\u00fcr das Standardmodell ergibt sich eine einfache Zeile:<\/p>\n<pre>DirectColorModel rgbModel = new DirectColorModel(32,\n0xff0000, 0x00ff00, 0x0000ff, 0xff000000);<\/pre>\n<p>Ist das Objekt einmal angelegt, so sind nun die Anfrage-Methoden wie getRed() m\u00f6glich, da DirectColorModel als konkrete Klasse, von der auch ein Exemplar erzeugt werden kann, diese abstrakten Methoden alle \u00fcberschreibt und mit Implementierung versieht. Eine wichtige Eigenschaft dieser Methoden ist, dass sie final sind und ihren Farbwert mit dem Alpha-Wert kombinieren. Da sie final sind, k\u00f6nnen sie von Unterklassen nicht mehr \u00fcberschrieben werden. Letzteres verlangt aber die aktuelle Implementierung der AWT-Bibliothek.<\/p>\n<p>Beispiel Implementierung von getRed()<\/p>\n<pre>final public int getRed(int pixel) {\n  int r = ((pixel &amp; maskArray[0]) &gt;&gt;&gt; maskOffsets[0]);\n  if (scaleFactors[0] != 1.)\n    r = (int)(r * scaleFactors[0]);\n  if (isAlphaPremultiplied) {\n    int a = getAlpha(pixel);\n    r = (a == 0) ? 0 : (r * 255\/a);\n  }\n  return r;\n}<\/pre>\n<p>Im Parameter pixel ist die Farbe Rot an einer Bitposition (meistens ab 24 Bit) abgelegt. Damit wir diesen Wert auslesen und mit dem Alpha-Wert kombinieren k\u00f6nnen, muss er zun\u00e4chst ausmaskiert werden. Daher wird pixel mit der Maske verkn\u00fcpft, sodass nur die Bits \u00fcbrig bleiben, die auch wirklich die Farbe Rot beschreiben. Anschlie\u00dfend verschieben wir die Rot-Pixel so weit nach rechts, dass die Gr\u00fcn- und Blau-Werte verschwinden. Die Felder maskArray und maskOffsets sowie scaleFactors sind in der direkten abstrakten Oberklasse PackedColorModel angelegt. Doch bleiben wir bei getRed(). Hier sehen wir noch deutlich, wie der Alpha-Wert in die Berechnung mit eingeht. Ist der Farbwert 0, so ist auch das Ergebnis 0. Ist er ungleich 0, so wird die Farbe nach dem Apha-Wert gewichtet. Der Skalierungsfaktor skaliert die Werte auf 256. Denn haben wir beispielsweise nur zwei Bits f\u00fcr einen Farbwert, dann m\u00fcssen wir mit 128 multiplizieren, um wieder eine Acht-Bit-Darstellung zu bekommen.<\/p>\n<p><b>Die Klasse IndexColorModel<\/b><\/p>\n<p>Im Gegensatz zur Klasse DirectColorModel verwaltet ein IndexColorModel die Farben und Transparenzen nicht im Pixel, sondern in einer eigenen Tabelle, die auch Color-Map oder Palette genannt wird. Das Modell ist vergleichbar mit dem Dateiformat GIF. Dort stehen maximal 256 Farben in einer Tabelle zur Verf\u00fcgung und alle Punkte in einem GIF-Bild m\u00fcssen einer dieser Farben entsprechen. Eine GIF-Datei mit zwei Farben definiert etwa eine Farbe mit schweinchenrosa und eine zweite Farbe mit hornhautumbra. Der Pixel selbst ist dann nur ein Index auf einen Eintrag. Dieses Verfahren ist sehr speicherschonend, ein Kriterium, das vor ein paar Jahrzehnten noch z\u00e4hlte. An Stelle von 24 Bit f\u00fcr einen Pixel wird der Index etwa zehn Bit breit gemacht und stellt dann bis zu 1.024 Farben dar. Das ist immerhin eine Reduktion des Bildschirmspeichers um die H\u00e4lfte. Leider sind damit aber auch hohe Berechnungskosten verbunden. F\u00fcr eine Verwendung dieser Klasse spricht die Abstraktion von den konkreten Farben. Ein Beispiel daf\u00fcr w\u00e4re ein Fraktalprogramm. Einer berechneten Zahl wird direkt ein Farbwert zugeordnet. Somit l\u00e4sst sich leicht eine Farbverschiebung programmieren, die sich auf Englisch color-cycle nennt.<\/p>\n<p>Wenn wir ein IndexColorModel verwenden wollen, geben wir im Konstruktor eine Anzahl Bits pro Pixel zusammen mit einer Tabelle an, die die Komponenten Rot, Gr\u00fcn und Blau sowie optional die Transparenzen enth\u00e4lt. Die Farbtabelle, die \u00fcber einen Index die Farbe verr\u00e4t, kann maximal 256 Farben aufnehmen. Dies ist leider eine Einschr\u00e4nkung, beschr\u00e4nkt aber den Speicher, da nur ein byte an Stelle eines short belegt wird.<\/p>\n<p><b>class java.awt.image.IndexColorModel<br \/>\n    <br \/>extends ColorModel<\/b><\/p>\n<ul>\n<li>IndexColorModel( int bits, int size,<br \/>\n    <br \/>byte r[], byte g[], byte b[], byte a[] ) <\/li>\n<li>IndexColorModel( int bits,int size,<br \/>\n    <br \/>byte r[], byte g[], byte b[], int trans ) <\/li>\n<li>IndexColorModel( int bits, int size<br \/>\n    <br \/>byte r[], byte g[], byte b[] ) <\/li>\n<li>IndexColorModel( int bits, int size, byte cmap[],<br \/>\n    <br \/>int start, boolean hasalpha, int trans ) <\/li>\n<li>IndexColorModel( int bits, int size, byte cmap[],<br \/>\n    <br \/>int start, boolean hasalpha ) <\/li>\n<li>IndexColorModel( int bits, int size, int cmap[],<br \/>\n    <br \/>int start,boolean hasalpha, int trans, <\/p>\n<p>int transferType ) <\/li>\n<\/ul>\n<p>An den Konstruktoren l\u00e4sst sich ablesen, dass mehrere Wege gegangen werden k\u00f6nnen. Die Farben k\u00f6nnen als Einzelfelder einem IndexColorModel \u00fcbergeben werden oder als zusammengepacktes Feld. Dann erfolgt die Speicherung nach dem Standard-RGB-Modell. Vorsicht ist bei einem Alpha-Wert geboten. Dieser folgt nach dem Blauton. So ist die Reihenfolge bei Transparenz 0xRRGGBBAA. Das ist sehr verwirrend, da wir es gewohnt sind, den Alpha-Wert vor dem Rotwert zu setzen.<\/p>\n<p>Intern werden die Werte in einem Feld gehalten. Der erste Wert gibt die Anzahl der Bits an, die einen Pixel beschreiben. Er darf acht Bit nicht \u00fcberschreiten, da die L\u00e4ngenbeschr\u00e4nkung 2^8 = 256 maximale Farben vorgibt. Der n\u00e4chste Wert size ist die Gr\u00f6\u00dfe der Tabelle. Sie sollte mindestens 2^bits gro\u00df sein. Andernfalls werden Farben fehlerhaft zugeordnet. Pr\u00e4ziser hei\u00dft dies, dass sie Null sind, da ja der new-Operator das Feld automatisch mit Null-Werten belegt. Sind in der Farbtabelle Apha-Werte abgelegt, dann sollte hasalpha den Wert true annehmen. Sind alle Werte in einer Tabelle, berechnet sich der Farbwert zu einem Index wie folgt: Betrachten wir keinen Alpha-Wert und unser Pixel hat den Wert f(arbe),<\/p>\n<ul>\n<li>dann ist der Rotwert an der Stelle colorMap[start+3*f] und <\/li>\n<li>der Gr\u00fcnwert an der Stelle colorMap[start+3*f+1] und <\/li>\n<li>der Blauwert schlie\u00dflich bei colorMap[start+3*f+2]. <\/li>\n<\/ul>\n<p>Um Informationen \u00fcber die internen Werte und die Gr\u00f6\u00dfe der Tabelle zu erhalten, reicht ein toString(). Die Gr\u00f6\u00dfe der Tabelle liefert die Methode getMapSize().<\/p>\n<p>Mit den finalen Methoden getReds(byte redArray[]), getGreens(byte greenArray[]), getBlues(byte blueArray[]) und getAlphas(byte alphaArray[]), deren R\u00fcckgabewert void ist, lassen sich die Farbinformationen auslesen und als Ergebnis in das Feld legen. Die Felder m\u00fcssen schon die passende Gr\u00f6\u00dfe haben, die sich jedoch mit final int getMapSize() erfragen l\u00e4sst. Die Methode getTransparentPixel() liefert den Index des transparenten Pixels. Gibt es keinen, ist der Wert -1.<\/p>\n<p>Werfen wir zur Demonstration noch einen Blick auf die Methode getGreens(). Wir sehen deutlich, dass das Feld eine passende Gr\u00f6\u00dfe haben muss.<\/p>\n<pre>final public void getGreens(byte g[]) {\n  for (int i = 0; i &lt; map_size; i++)\n  g[i] = (byte) (rgb[i] &gt;&gt; 8);\n}<\/pre>\n<p>An getRed() sehen wir ebenso, dass der Pixel auch direkt ein Index f\u00fcr das private Feld rgb ist. Wenn der Index \u00fcber die Feldgr\u00f6\u00dfe l\u00e4uft, m\u00fcssen wir den Fehler selbst behandeln.<\/p>\n<pre>final public int getRed(int pixel) {\n  return (rgb[pixel] &gt;&gt; 16) &amp; 0xff;\n}<\/pre>\n<p>Wenden wir unsere Aufmerksamkeit auf ein Programm, welches ein Bytefeld erzeugt und aus sechs Farben die Pixel in das Feld schreibt. Zum Schluss konvertieren wir das Bytefeld mit einem MemoryImageSource in ein Image-Objekt. F\u00fcr diese Klasse k\u00f6nnen wir ein IndexColorModel angeben, das dann folgendes Format hat:<\/p>\n<pre>ColorModel cm = IndexColorModel( 8, colorCnt, r, g, b );<\/pre>\n<p>Hier handelt es sich um ein Farbmodell mit acht Bits und sechs Farben. Die folgenden Werte zeigen auf die drei Felder mit den Farbwerten. Anschlie\u00dfend erzeugt createImage() mit diesem Farbmodell das Image-Objekt.<\/p>\n<pre>Image i = createImage( new MemoryImageSource(w,h,cm,pixels,0,w) );<\/pre>\n<p>Zum kompletten Beispiel: <\/p>\n<pre>import java.awt.*;\nimport java.awt.image.*;\n\npublic class IndexColorModelDemo extends Frame\n{\n  Image i;\n  private final static int w = 400, h = 400;\n\n  int pixels[] = new int [w*h];\n\n  Color colors[] = {\n    Color.red, Color.orange, Color.yellow, Color.green, Color.blue, Color.magenta\n  };\n\n  IndexColorModelDemo()\n  {\n    int colorCnt = colors.length;\n\n    byte r[] = new byte[colorCnt],\n    g[] = new byte[colorCnt],\n    b[] = new byte[colorCnt];\n\n    for ( int i = 0; i &lt; colorCnt; i++ ) {\n      r[i] = (byte) colors[i].getRed();\n      g[i] = (byte) colors[i].getGreen();\n      b[i] = (byte) colors[i].getBlue();\n    }\n\n    int index = 0;\n    for ( int y = 0; y &lt; h; y++ )\n      for ( int x = 0; x &lt; w; x++ )\n        pixels[index++] = (int)(Math.random() * colorCnt);\n    i = createImage( new MemoryImageSource( w, h, new IndexColorModel(8, colorCnt, r, g, b), pixels, 0, w) );\n  }\n\n  public void paint( Graphics g )\n  {\n    if ( i != null )\n      g.drawImage( i, 0, 0, this );\n  }\n\n  public static void main( String args[] )\n  {\n    IndexColorModelDemo d = new IndexColorModelDemo();\n    d.setSize( w, h );\n    d.show();\n  }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Ein besonderer Produzent, der sich um alles k\u00fcmmert, was das Bilderzeugen angeht, ist der Image Producer. Im Gegensatz dazu sind es die Image Consumer, die etwaige Bilddaten benutzen. Bei den Produzenten- und Konsumentenmodell von Image-Objekten stehen die Daten der Pixel immer in einem Byte- oder Integer-Feld zur Verf\u00fcgung und stehen im Mittelpunkt des Interesses. Oft [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-2250","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2250"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2250\/revisions"}],"predecessor-version":[{"id":2251,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2250\/revisions\/2251"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}