Das effizienteste Pixel der Java-Welt

Status
Nicht offen für weitere Antworten.

Ark

Top Contributor
Ich habe z. B. 10000 (nur für einen kleinen Test ^^) Objekte, die alle gleichzeitig auf dem Bildschirm dargestellt werden möchten. Um dies zu erreichen, sollen bis zu drei darzustellende Informationen ausgewählt werden, die jeweils durch verschiedene Rot-, Grün- und Blauanteile eines Pixels aufgezeigt werden. Ein Pixel repräsentiert so die gewünschten drei Informationen eines einzelnen Objekts. (Ja, das ergibt Sinn, da vor allem die Gesamtentwicklung interessant zu beobachten sein wird.)

Nun ist es so, dass sich diese Informationen wahnsinnig schnell ändern, von daher denke ich, sollte ein VolatileImage zur Anwendung kommen. Wie ich mit so einem VolatileImage arbeiten kann, meine ich inzwischen rausgekriegt zu haben.

Das Problem: Es scheint keine Methode zu geben, mit der ich ganz gezielt einen der drei Farbkanäle (Rot, Grün, Blau) eines ganz bestimmten Pixels ändern kann.

Meine bisherigen Ideen dazu sind folgende:

Variante 1: Ich zeichne Linien von 1 Pixel Länge. Dazu müsste ich aber jedes mal neue Color-Objekte erstellen, um den imaginären Stift des Graphics2D-Objektes „umzufärben“. Das ist offensichtlich nicht sehr performant.

Variante 2: Ich benutze ein BufferedImage und greife via setSample(int,int,int,int) des dazugehörigen WriteableRasters direkt auf einen Farbkanal zu. Jetzt müsste ich allerdings jedes Mal das BufferedImage, welches ich zudem überflüssigerweise im Arbeitsspeicher halten muss, auf das VolatileImage zeichnen. Frage: Geht das nicht noch schneller, wo es denn schon Arbeitsspeicher frisst? ???:L

Mit anderen Worten: Ich will (via Java) so schnell und so platzsparend wie möglich auf einen ganz bestimmten Farbkanal eines ganz bestimmten Pixels effektiv schreibend zugreifen.

(Hat Letzteres jemand überhaupt verstanden? ^^')

Kann mir da jemand einen Rat geben?

MfG
Ark
 
Ich würde mir 10k JPanels machen und deren Background jeweils auf die entsprechenden Farben setzen.

Oder (andere Idee): Jedes Objekt speichert seine drei Werte nur, und du rufst die dann ständig (oben anfangen und sobald unten fertig wieder oben anfangen) von Außen ab und malst die per setRGB(x,y, rgb) verpackt in einen int (ohne Color-Objekt(!)) auf ein BufferedImage. Nach jedem Durchlauf zeichnest du dieses.#

[edit]
Eine interessane Fragestellung! Was soll das ganze denn werden?
[/edit]
 
Was das werden soll? Das ist natürlich streng geheim. 😉

Aber vielen Dank für diese Antwort; Variante 2 scheint wohl doch die dafür optimale Lösung zu sein.

Ich frage mich, ob meine Fragestellung nicht FAQ-Wert haben könnte … 😉

MfG
Ark
 
Kennt sich hier jemand mit SWT aus? *duck*

Wie kann ich da so schnell wie möglich einen Pixel auf dem Bildschirm ändern?
 
Ich würde ein BufferedImage nehmen und die Pixel einzeln im Pixelarray ändern. Also etwa so:

Code:
BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] pixels = ((DataBufferInt) output.getRaster().getDataBuffer()).getData();
....
pixels[position]=(red<<16)+(green<<8)+blue;
....

Dann das BufferedImage irgendwohin malen. Ein Umweg über ein VolatileImage macht keinen Sinn mehr an dieser Stelle.
 
@EgonOlsen: :applaus: Mächtig gewaltig, Egon! 😀 :applaus: 😉

Vielen Dank, auf die Idee mit dem DataBufferInt usw. muss man erst einmal kommen. Tausend Dank für Deinen Rat! =)

MfG
Ark
 
daa, hab ich auch noch ne frage ^^

das mit dem bufferedimage is jut,
jedoch würde ich es nicht in einem array speichern, sondern:

ein zweites buffererdimage erstellen, und dort von dem ersten die geänderten pixel rein schreiben:

buff1.getRGB(i,j)
--pixel verändern--
buff2.setRGB(i, j, neuespixel);

macht dies ein unterschied?
bzw. welche methode wäre schneller?

dank euch 🙂
 
Schneller als direkt im Array bekommst du es nicht hin. setRGB(...) zieht eine ganze Reihe von Aufrufen nach sich, die alle ihre Zeit kosten. Ist ok, um mal ein einzelnes Pixel zu ändern. Aber für Massenänderungen würde ich es nicht empfehlen.
 
Egon hat Recht; schneller als über ein Array wird es nicht gehen. Jeder Methodenaufruf sollte aus Performancegründen vermieden werden. 😉

Wenn Du aber noch etwas da rausholen willst: Verwende den Operator | statt + und verwende in der entsprechenden paint-Methode die drawImage-Methode, bei der Du die Maße des Graphics.getClipBounds()-Rectangles einsetzen kannst.

MfG
Ark
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben