Bildskalierung mit Java ohne getScaledInstance()
/ Autor: Thomas, 04 Jul 2008Um Bilder von Java skalieren zu lassen gibt es die komfortable Funktion getScaledInstance(), die wie der Name sagt eine skalierte Instanz eines BufferedImage zurückliefert. Diese auf den ersten Blick praktische Funktion sollte gemieden werden, da sie veraltet ist und zu langsameren und qualitativ schlechteren Ergebnissen führt als die Skalierung über RenderingHints. Beim im Vergleich mit einer schnellern Methode und identischen Bildern sind die Ergebnisse der Skalierung um 50% – 70% schneller gewesen, trotz ähnlicher oder besserer Qualität am Ende.
Bei der schnelleren Variante habe ich die drawImage()-Funktion des Graphics2D Kontextes eines BufferedImage verwendet, die es als Ausprägung mit Parametern zum skalierten Zeichnen gibt. Dabei wird auch der RenderingHint eingesetzt, der dafür zuständig ist, wie ein grafischer Kontext gerendert wird. Dabei muss dem Rendering-Hint ein Hint-Key und der Wert des Keys mitgegeben werden. Der Key gibt den Wert des zu beeinflussenden Rendering-Filters an, über den Wert des Keys stellt man den Algorithmus zur Neuberechnung ein. Für die Skalierung ist der Wert KEY_INTERPOLATION wichtig. Er gibt an wie die Interpolation, also die Neuberechnung der Pixel in einem Bild erfolgen soll. Dazu gibt es verschiedene Algorithmen, welche dafür verwendet werden können. Wer schon mal mit professionellen Bildbearbeitungstools gearbeitet hat, dem sollten die einstellbaren Algorithmen wie “bicubic interpolation” oder “nearest neighbor” zumindest namentlich ein Begriff sein. Von der Wahl des Algorithmus ist dann die Berechnungsgeschwindigkeit und die Qualität des Ergebnisses abhängig. Als Wert für KEY_INTERPOLATION stehen dabei folgende Werte aufsteigend in Qualität zur Verfügung
VALUE_INTERPOLATION_NEAREST_NEIGHBOR
VALUE_INTERPOLATION_BILINEAR
VALUE_INTERPOLATION_BICUBIC
Weitere Informationen zu Rendering-Hints gibt es wie immer in der API-Spezifikation. Es lohnt sich einen Blick in die Spezifikation der Rendering-Hints zu werfen, da noch andere Einstellungen beim Erzeugen oder Manipulieren von Bildern gemacht werden können.
Wie schon zu Beginn des Posts sollte man also auf getScaledInstance() verzichten und stattdessen den grafischen Kontext eines Bildes verkleinert oder vergrößert zeichnen, da der Geschwindigkeitgewinn im Vergleich erheblich sein kann und sich keine signifikanten Qualitätsunterschiede ergeben. Zudem ist über RenderingHints auch der gesamte Prozess einfach einzustellen.


Leave a Reply