bilder performant und unhässlich skalliert darstellen?

Status
Nicht offen für weitere Antworten.

asarnil

Mitglied
Hallo comunity,

hab mich grade registriert, also erstmal einen Gruß in die Runde.

Ich hab da ein Problem mit der Performance von einem meiner Javaprojekte: Es geht um ein gui für so etwas wie ein Brettspiel. Ein Bild sagt mehr als 1000 worte deshalb erstmal Screenshots:

scviewer.png

scviewer2.png


Ich lasse derzeit für jeder der Welten (die runden Scheiben inkl. der Raumschiffe) eine Grafik im voraus zeichnen und im Arbeitsspeicher ablegen. Der untere Screenshot zeigt die native Auflösung, und damit auch die maximale gewünschte Zoomstufe. Was ich jetz gerne implementiert hätte wäre eine Methode die mir die welten performant mit beliebiger zoomstufe/bildausschnitt in mein Applet zeichnet.

Mit bruteforce (also bei jedem Frame die Welten per drawimage() an die passende stelle zu zeichnen) klappt es überhauptnicht.

Ich denke ich bin da konzeptionell voll auf dem Holzweg und deshalb will ich euch fragen, wie man so etwas vllt so performant hinkriegt, dass am Ende sogar sanfte Zoomübergänge möglich wären.
 

Ebenius

Top Contributor
Ich würde wohl vollständig auf die Images verzichten und gleich zeichnen. Habe schon wesentlich komplexere Dinge auf wesentlich langsameren Rechnern (als heute üblich) gezeichnet und erwarte da keine Probleme.

Ebenius
 

asarnil

Mitglied
du meinst alles mit "malen nach zahlen"? ich benutze halt derzeit externe Grafiken für die Rohstoffe und die Schiffe z.B.. Ich verstehe das jetzt so, dass ich für jedes Bild dass ich bisher als png vorliegen habe, eine Methode baue, die mir aus den grund-Zeichenfunktionen das entsprechende Objekt in beliebiger Größe an eine beliebige Position im Applet zeichnet. Das derzeitige grafische Niveau könnte ich bestimmt mit shapes realisieren, aber ich befürchte hinterher könnten mir dann die Hände etwas gebunden sein, wenn ich es grafisch ausarbeiten will.

Aber ich werde es jetzt mal ausprobieren, wieviel Performance das bringt.
 

Ebenius

Top Contributor
Achso... Die Screenshots sahen mir so aus, als ob Du sie direkt in ein Image gezeichnet hättest. Wie wäre es denn mit skalierbaren Bildern für die Rohstoffe? Hab in Java noch nicht mit SVG gearbeitet, aber das geht doch bestimmt total hübsch, oder?

Ebenius
 

Wolfgang Lenhard

Bekanntes Mitglied
Ich empfehle "On-the-fly-Scaling" direkt bei Anzeige mit entsprechenden RenderingHints (VALUE_INTERPOLATION_BICUBIC, falls höchste Qualität gewünscht ist): java.net: The Perils of Image.getScaledInstance(). Wenn Du es bereits so gemacht hast und es nicht klappt, dann hast Du ein Problem. Es ist nämlich die effizienteste Möglichkeit, Bilder skaliert anzuzeigen (Bug ID: 6196792 Update Image.getScaledInstance with acceleration or documentation)
Wenn das nicht klappt, dann wirst Du vermutlich wirklich direkt mit Graphics2D zeichnen müssen. Das braucht dann tatsächlich sehr wenige Ressourcen.

P.S.: Was noch hilfreich sein könnte: Einschränkung des Zeichen-Bereichs mit Graphics2D.setClip()
 
Zuletzt bearbeitet:

Fu3L

Top Contributor
du meinst alles mit "malen nach zahlen"? ich benutze halt derzeit externe Grafiken für die Rohstoffe und die Schiffe z.B.. Ich verstehe das jetzt so, dass ich für jedes Bild dass ich bisher als png vorliegen habe, eine Methode baue, die mir aus den grund-Zeichenfunktionen das entsprechende Objekt in beliebiger Größe an eine beliebige Position im Applet zeichnet. Das derzeitige grafische Niveau könnte ich bestimmt mit shapes realisieren, aber ich befürchte hinterher könnten mir dann die Hände etwas gebunden sein, wenn ich es grafisch ausarbeiten will.

Aber ich werde es jetzt mal ausprobieren, wieviel Performance das bringt.

Wenn du auf PNG verzichten kannst, benutze kein PNG. Hatte auch mal hier wegen nem Performanceproblem gefragt und die Ursache war einfach, dass das Zeichnen von PNG-Bildern wohl sehr aufwendig sein muss.

Dadurch das ich das Hintergrundbild in jpg abgespeichert und verwendet hab und nichmehr in png, bin ich von ner Prozessorauslastung von 100% auf ~10% runtergekommen...
 

Marco13

Top Contributor
Letzteres könnte damit zusammenhängen, dass PNG Transparenz unterstützt, und er deswegen aufwändigst mit Transparenzberechnungen rumwurschtelt (auch wenn keine Transparenz im Bild enthalten ist!)

Die Geschwindigkeit... OK ... ggf. kannst du etwas "cachen". Die Bilder könnten einmal in Originalauflösung vorliegen, und einmal passend zur aktuellen Zoomstufe ... Im Pseudocode
Code:
Image original = ...
Image scaled = ..

public void paint()
{
    if (istFürDieAktuelleZoomStufeNICHTPassend(scaled))
    {
        scaled = machePassendFürAktuellenZoom();
    }
    g.drawImage(scaled);
}
... aber mußt halt erstmal überlegen, ob das für dich OK ist. ("Flüssiges" reinzoomen geht damit auch nicht, weil sich dann ja bei jedem neuzeichnen die Größe ändern würde...)
 

Ebenius

Top Contributor
Was Fuel3 da schreibt, ergibt schon Sinn. Manchmal bekommt man die Geschwindigkeit dadurch erhöht, dass man die gemalten Bilder in ein neues BufferedImage des geeigneten Typs zeichnet.

Ebenius
 

0x7F800000

Top Contributor
Und wenn du weder die Hardware mit OpenGL o.ä. , noch die (wohl ebenfalls recht effizienten) Zeichenroutinen des Graphics 2D nutzen willst, deine Grafiken aber in einer recht hohen auflösung vorliegen, dann erzeuge dennoch mipmaps! ist ja vom prinzip her sehr billig, wenn da aber 500 "Raumschiffe" zeichnen willst, und dazu pro frame 50 verschiedene bilder von 512x512px auf 10x10 px runterskalieren musst, muss es einfach irgendwann mal ruckeln. Mit mipmaps wird dies aber ziemlich sicher vermieden.
 

asarnil

Mitglied
Vielen Dank erstmal für die zahlreichen anregungen!

Letzteres könnte damit zusammenhängen, dass PNG Transparenz unterstützt, und er deswegen aufwändigst mit Transparenzberechnungen rumwurschtelt (auch wenn keine Transparenz im Bild enthalten ist!)

Ich benutze transparente pngs, und brauche auch die transparenz, weil der hintergrund zB der Rohstoffe von die Playerfarbe sein soll.

Ich empfehle "On-the-fly-Scaling" direkt bei Anzeige mit entsprechenden RenderingHints (VALUE_INTERPOLATION_BICUBIC, falls höchste Qualität gewünscht ist)

Hab ich alles durchprobiert :(

Wenn das nicht klappt, dann wirst Du vermutlich wirklich direkt mit Graphics2D zeichnen müssen. Das braucht dann tatsächlich sehr wenige Ressourcen.

Das werde ich bald mal ausprobieren, das wird aber einiges an Programmierzeit brauchen (zumindest für meine Maßstäbe).

..., dann erzeuge dennoch mipmaps!

Das habe ich gemacht (ohne zu wissen was mipmaps sind). Hat auch was gebracht, aber leider nicht genug.

Das Spiel um dass es geht ist ein play-by-email-game sprich man bekommt ein turnsheet per mail, welches mein gui hübsch darstellen soll. Daraufhin schreibt man seine Befehle für die Runde zurück und wartet auf die nächste mail. Dadurch ist der darzustellende Inhalt extrem statisch. Imgrunde könnte ich ein großes jpg rendern lassen und den rest meinem Bildervorschauprogramm überlassen. Ich will aber durch clicken auf bestimmte stellen auf dieser Karte Dinge passieren lasse (z.B. Befehle in ein textfenster schreiben oder metainfo über die Welten anzeigen lassen)

Deshalb denke ich darüber nach mich mit meinem gui mehr an googlemaps zu orientieren. Dass immer ein etwa passender Screenshot der Karte im Buffer ist und dieser ab und zu aktualisiert wird. Dieser Screenshot wird dann immer entsprechend der aktuellen kameraeinstellung zurechtgeschnitten.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Bilder werden unscharf angezeigt Spiele- und Multimedia-Programmierung 5
S Bilder Für Schachfiguren Spiele- und Multimedia-Programmierung 14
beatles Minesweeper - keine Bilder Spiele- und Multimedia-Programmierung 3
P [Spiel]Welche Bilder sind gleich Spiele- und Multimedia-Programmierung 2
O Bilder senden TV über DLNA? Spiele- und Multimedia-Programmierung 0
T Bilder Elegant darstellen... Spiele- und Multimedia-Programmierung 7
T Bilder einbinden, bzw. ändern Spiele- und Multimedia-Programmierung 5
M Bilder effizient speichern/serialisieren Spiele- und Multimedia-Programmierung 10
M Bilder in Java Spiele- und Multimedia-Programmierung 7
D Slick Lib - Bilder einlesen funktioniert nicht Spiele- und Multimedia-Programmierung 2
B Bilder in GUI ändern ohne repaint() Spiele- und Multimedia-Programmierung 6
T Spielautomat bilder vergleichen Spiele- und Multimedia-Programmierung 34
A Bilder werden nicht geladen Spiele- und Multimedia-Programmierung 6
S Datenbank gesucht für Bilder(gif-dateien) Spiele- und Multimedia-Programmierung 5
A Bilder (auf JPanels) auf komplette Zellengröße (GridBagLayout) skalieren Spiele- und Multimedia-Programmierung 2
I Bilder aus Quaxli's Tutorial Spiele- und Multimedia-Programmierung 3
A 2 Bilder übereinander legen Spiele- und Multimedia-Programmierung 15
J 2D-Bilder in Java3D Spiele- und Multimedia-Programmierung 4
A Bilder(BMP) speichern Spiele- und Multimedia-Programmierung 2
S Bilder zuscheiden - Werte von php übergeben Spiele- und Multimedia-Programmierung 7
D Bilder besser interpolieren Spiele- und Multimedia-Programmierung 4
F Dynamische Bilder erzeugen? Spiele- und Multimedia-Programmierung 7
R Bilder aus animierter .gif extrahieren? Spiele- und Multimedia-Programmierung 4
C jpg.Bilder teilen/bearbeiten für Puzzle Spiele- und Multimedia-Programmierung 7
A Bilder bewegen Spiele- und Multimedia-Programmierung 2
M Bilder verzerren [Rechteck -> Trapez] Spiele- und Multimedia-Programmierung 4
K Bilder drehen Spiele- und Multimedia-Programmierung 5
H Bilder speichern 2 - Methode richten? Spiele- und Multimedia-Programmierung 2
H Bilder speichern Spiele- und Multimedia-Programmierung 3
A Bilder flackern Spiele- und Multimedia-Programmierung 5
T Gekachelte Bilder darstellen Spiele- und Multimedia-Programmierung 2
turing JOGL Cubes performant Spiele- und Multimedia-Programmierung 17
U Jpeg performant skalieren Spiele- und Multimedia-Programmierung 14

Ähnliche Java Themen


Oben