# PIMP my Application



## The_S (8. Dez 2006)

Hi,

ich habe (erstmal) 2 Fragen zum Thema Performance:

1. Wie bekomme ich am schnellsten die RGB-Werte eines BufferedImages für jeden Pixel? Gibt es da ne schnellere Möglichkeit als das komplette Bild in zwei verschachtelten Schleifen zu durchlaufen und jeden Pixel mit


```
color = new Color(image.getRGB(x, y));
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
alpha = color.getAlpha();
```

zu speichern? Am Ende benötige ich ein int-Array dass alle rgb Werte repräsentiert (also so solls am Ende aussehen


```
int[] ar = {redpixel1, greenpixel1, bluepixel1, redpixel2, greenpixel2, bluepixel2, redpixel3, ...};
```

) und eines, dass den alpha-Kanal darstellt (z. B.


```
int[] alpha = {alphapixel1, alphapixel2, alphapixel3, alphapixel4, ...};
```

). Unter Umständen wäre ich auch bereit (wenns schneller geht) die Daten in irgendeiner anderen Form abzuspeichern.

2. Wie kann ich am schnellsten das letzte Bit eines max. 8 Bit langen Integers nach meinem belieben ändern? Ich denke mal, es wird nicht die schnellste Variante sein, wenn ich den int in einen Binär-String umwandle, dort dann mittels substring und length() das letzte Zeichen wegschneide und entweder "1" oder "0" dranhänge . Was mir sonst noch einfallen würde, wäre überprüfen, ob es eine gerade oder eine ungerade zahl ist. Falls gerade und das letzte bit muss eine 1 sein => zahl + 1, falls ungerade und das letzte Bit muss 0 sein => zahl - 1, ansonsten unverändert lassen.

Jenachdem wie eure Antworten ausfallen bzw. was mir sonst noch so einfällt werde ich bestimmt noch mehr Fragen  .

Danke!


----------



## SlaterB (8. Dez 2006)

1.)
image.getRGB(x, y)
liefert doch irgendwas sinnvolles, vielleicht einen Zahlenwert,
mit ein wenig Mathematik kannst du da direkt die einzelnen Bestandteile ausrechnen,
jedes mal ein Color-Objekt zu erzeugen ist unnötig 
(schaue vielleicht in den Quellcode von Color)

2.)
mit Bitoperationen arbeiten, Bitmasken usw,
das erste Bit != 0 suchen, sich dessen Position merken

kommen da auch negatige Integer in Frage?


----------



## Roar (8. Dez 2006)

zu 2.: oder einfach +1/-1 :roll:


----------



## The_S (8. Dez 2006)

Danke für deine Antwort  .

1.) OK, mal schauen ob ich daraus irgendwie meine Daten extrahieren kann.

2.) Nein, die Integer sind immer zwischen 0 und 255 (das sind die Werte aus dem BufferedImage). Mit Bit-Operatoren hab ich noch nie was gemacht, aber irgendwann ist immer das 1. mal  .

Falls noch irgendwer Vorschläge hat, bin für alles offen  .


----------



## The_S (8. Dez 2006)

Roar hat gesagt.:
			
		

> zu 2.: oder einfach +1/-1 :roll:



? Versteh ich nicht. Es geht nicht darum das letzte Bit umzukehren, sondern es durch ein anderes zu erstzen (unabhängig ob das letzte Bit 1 oder 0 ist).


----------



## Roar (8. Dez 2006)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Mit Bit-Operatoren hab ich noch nie was gemacht, aber irgendwann ist immer das 1. mal  .



jaja wieder typisch noob auszubildenden die können eh nix :bloed: :lol:

edit: ja, die ein zwei if abfragen um das +1 musst dir aber schon selber schreiben :roll:


----------



## The_S (8. Dez 2006)

Roar hat gesagt.:
			
		

> edit: ja, die ein zwei if abfragen um das +1 musst dir aber schon selber schreiben :roll:



Aber das sollte doch imho das sein, was ich als alternative gleich im Eröffnungpost gesagt habe oder missverstehe ich dich jetzt?



			
				Roar hat gesagt.:
			
		

> jaja wieder typisch noob auszubildenden die können eh nix :bloed: :lol:



Die "noob Auszubildenden" bekommen dafür Geld, was du in deiner Freizeit machst. Da zieh ich es doch vor n noob Azubi zu sein ^^


----------



## Roar (8. Dez 2006)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Die "noob Auszubildenden" bekommen dafür Geld, was du in deiner Freizeit machst.



tja ich auch :bae:


```
private static int setzeLetztesBitFürAzubis(int zahl, boolean flag) {
		if (zahl % 2 == 0 && flag) {
			return zahl + 1;
		} else if(zahl % 2 != 0 && !flag) {
			return zahl - 1;
		}
		return zahl;
	}

	private static int setzeLetztesBitFürDiplInfs(int zahl, boolean flag) {
		zahl >>= 1;
		zahl <<= 1;
		if (flag) {
			zahl |= 1;
		}
		return zahl;
	}
```


----------



## The_S (8. Dez 2006)

Roar hat gesagt.:
			
		

> ```
> private static int setzeLetztesBitFürAzubis(int zahl, boolean flag) {
> ```



Mensch, wenn de scho damit Geld verdienst, sollteste wenigstens wissen, dass ma in Methoden keine Umlaute verwendet  .



			
				Roar hat gesagt.:
			
		

> ```
> private static int setzeLetztesBitFürDiplInfs(int zahl, boolean flag) {
> zahl >>= 1;
> zahl <<= 1;
> ...



Hättest du dennoch die Gütigkeit mir diesen Schnippsel zu erklären? Insbesondere die Operatoren

<<=
>>=
|=

danke  .


----------



## SlaterB (8. Dez 2006)

lern lesen und schreiben, ähh Java!

du musst dir doch eh ein Kapitel zu Bitoperationen durchlesen wenn du damit arbeiten willst:
http://www.galileocomputing.de/open...sel02_007.htm#Rxx747java02007040000AE1F04E102


----------



## Roar (8. Dez 2006)

ich kann in methoden soviele umlaute benutzen wie ich will schileßlich verwendet die vm ja auch unicode :bae:

zahl >>= 1 verschiebt erst alle bits um 1 pos nach rechts und
<<= dann wieder um eine nach links, damit kann ich mir sicher sein, dass das letzte bit 0 ist.
zahl |= 1 setzt dann das letzte bit auf 1 weil oder verknüpfung halt


----------



## The_S (8. Dez 2006)

@SlaterB

werd mir den link gleich mal anschauen

@Roar

danke, habs verstanden


----------



## The_S (8. Dez 2006)

Bevor ich jetzt ewig rumsuch und probier und am Ende gibts dass dann doch net, frag ich lieber nomma  .

Kann ich auch irgendwie rausbekommen welchen Wert ein Bit an einer beliebigen Stelle in einem int hat?

Und kann ich ein 8-Bit Byte anhand von einzelnen Bits zusammenbauen? Ich habe z. b. ein int array mit 8 Bytes drin. Jetzt möchte ich ein einziges Byte aus den jeweils letzten Bit der 8 Bytes in dem Array erstellen.

Danke!

Achja, die Color-Funktionen schauen so aus:


```
rgb = image.getRGB(i, j);
				bytes[k] = (rgb >> 16) & 0xFF;
				bytes[k + 1] =(rgb >> 8) & 0xFF;
				bytes[k + 2] = (rgb >> 0) & 0xFF;
				alpha[l] = (rgb >> 24) & 0xff;
```


----------



## SlaterB (8. Dez 2006)

du brauchst die Bitmasken,
siehe z.B.
http://www.java-forum.org/de/viewtopic.php?t=40074

zum Zusammenbauen:
die Bits aus dem ersten Byte nehmen, um 24 nach links schieben,
die Bits aus dem zweiten Byte nehmen, um 16 nach links schieben,
usw,
alles zusammen = ein int

genau umgekehrt zum Auseinandernehmen


----------



## The_S (8. Dez 2006)

OK, danke. Das schau ich mir dann daheim mal an  .


----------



## The_S (9. Dez 2006)

So, dann wollen wir mal überprüfen ob ich das alles richtig verstanden habe  .

1. Hiermit:


```
cur = 0;
for (int j = 0; j < 8; j++) { 
   cur |= (bytes[j] & 1) << 7 - j;
}
```

Baue ich die Variable cur aus einem int-array zusammen. Das letzte Bit im 1. Array soll das 1. Bit in cur werden, das letzte Bit im 2. Array soll das 2. Bit in cur werden, das letzte Bit im 3. Array soll das 3. Bin in cur werden, ... Funktionieren tuts, is nur die Frage ob das auch schneller geht  .

2. Hiermit:


```
int cur = 'b';
for (byte j = 0; j < 8; j++) { 
   bytes[j] = setLastBit(bytes[j], ((cur & 1 << 7 - j) >> 7 - j) == 1); 
}
```

Verteile ich die Bits von einem Byte auf das jeweils letzte Bit eines Bytes eines int-arrays. Auch das funktioniert, aber ich bin mir sicher, dass das irgendwie schneller geht  .

Danke!


----------



## SlaterB (9. Dez 2006)

1.)
werden die Arrays mit 2.) erstellt?
was ist zuerst da, die Henne oder das Ei? 

also wenn durch 2.), dann dürften die anderen Bits in den Array-Elementen doch jeweils 0 sein,

dann ist das & 1 nicht nötig?
damit wirds minimal schneller,
allerdings sind meine Tests (das ganze 100 Mio. mal durchlaufen lassen) vielleicht nicht ganz das wahre,
z.B. ist 
cur |= ba[j] << j;
wiederum bisschen langsamer als
cur |= ba[j] << 7 - j;
..

------

cur |= (ba[j] << 7) >> j;
bringt keine Vorteile gegenüber 
cur |= (ba[j] & 1) << 7 - j;

------
ein beträchtlicher Teil der Zeit steckt allein im Array-Zugriff,
wenn man alle Bitoperatioen weglässt ist
cur = ba[j];
zwar durchaus schneller, aber langsamer als wenn man nur das Array weglässt:
cur |= (244 & 1) << 7 - j;


--------------

beim zweiten könntest du doch direkter arbeiten:

```
for (byte j = 0; j < 8; j++) {
	bytes[j] = (byte) ((cur & (1 << 7 - j)) >> 7 - j);
}
```
oder was spricht dagegen?

hier scheint mir eine spürbare Steigerung möglich, mit

```
int temp = cur;
for (byte j = 7; j >= 0; j--) {
	bytes[j] = (byte) (temp & 1);
	temp >>= 1;
}
```

ein ähnliches Verfahren ist bei 1.) denkbar, aber anscheinend nicht schneller


----------



## The_S (9. Dez 2006)

SlaterB hat gesagt.:
			
		

> 1.)
> werden die Arrays mit 2.) erstellt?



Ja, aber nachdem sie erstellt werden, werden sie in eine Datei gespeichert und daraus wieder gelesen  .



			
				SlaterB hat gesagt.:
			
		

> also wenn durch 2.), dann dürften die anderen Bits in den Array-Elementen doch jeweils 0 sein



?



			
				SlaterB hat gesagt.:
			
		

> beim zweiten könntest du doch direkter arbeiten:
> 
> ```
> for (byte j = 0; j < 8; j++) {
> ...



Ah, danke. Werds mal ausprobieren  .


----------



## SlaterB (9. Dez 2006)

wenn die Array-Elemente durch 2.) erstellt werden,
dann können sie doch nur 0 oder 1 sein,
dann ist das letzte Bit interessant, die 7 davor aber garantiert 0,

dann ist bei 
cur |= (bytes[j] & 1) << 7 - j; 
das
& 1 doch unnötig?

->
cur |= bytes[j] << 7 - j;


----------



## The_S (9. Dez 2006)

Äh, nein. Das array wird ausgelesen (Farbwerte von Bild) und somit befüllt. 2. Bearbeitet diese ints. Von daher kann das so ziemlich alles haben  .


----------

