# Das effizienteste Pixel der Java-Welt



## Ark (30. Dez 2006)

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


----------



## dieta (30. Dez 2006)

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]


----------



## Ark (30. Dez 2006)

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


----------



## Illuvatar (30. Dez 2006)

@Variante 2: Wenn schon BufferedImage, wofür dann überhaupt noch ein VolatileImage?


----------



## Ark (31. Dez 2006)

Kennt sich hier jemand mit SWT aus? *duck*

Wie kann ich da so schnell wie möglich einen Pixel auf dem Bildschirm ändern?


----------



## EgonOlsen (1. Jan 2007)

Ich würde ein BufferedImage nehmen und die Pixel einzeln im Pixelarray ändern. Also etwa so:


```
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.


----------



## Ark (2. Jan 2007)

@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


----------



## der_Gast (16. Jan 2007)

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


----------



## EgonOlsen (16. Jan 2007)

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.


----------



## Ark (22. Jan 2007)

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


----------



## EgonOlsen (22. Jan 2007)

Ark hat gesagt.:
			
		

> Wenn Du aber noch etwas da rausholen willst: Verwende den Operator | statt +....


Das sollte egal sein. Moderne CPUs können beides im Idealfall in einem Takt erledigen.


----------

