Hallo, ich will mal noch meine Version ins Spiel bringen.
Die Funktion GetAverageColor1 wäre die exakte Berechnung. Wenn das Ergebnis nicht 100% exakt sein muss, kann die Funktion GetAverageColor2 verwendet werden.
Delphi-Quellcode:
Type
TRgb = packed record
b:Byte;
g:Byte;
r:Byte;
d:Byte;
end;
TRgbLine = array[0..MaxInt div 4 - 1] of TRgb;
PRgbLine = ^ TRgbLine;
function GetAverageColor1(bmp:TBitmap):TRgb;
var
r,g,b:Integer;
RgbLine: PRgbLine;
p:Integer;
PixelCount: Integer;
begin
PixelCount := bmp.Width * bmp.Height;
r := 0;
g := 0;
b := 0;
rgbline := bmp.ScanLine[bmp.Height - 1];
for p := 0 to PixelCount -1 do
begin
r := r + RgbLine[p].r;
g := g + RgbLine[p].g;
b := b + RgbLine[p].b;
end;
Result.r := r div PixelCount;
Result.g := g div PixelCount;
Result.b := b div PixelCount;
end;
function GetAverageColor2(bmp:TBitmap;DivFaktor:Integer):TRgb;
var
r,g,b:Integer;
RgbLine: PRgbLine;
p:Integer;
PixelCount: Integer;
i:Integer;
begin
PixelCount := bmp.Width * bmp.Height;
r := 0;
g := 0;
b := 0;
rgbline := bmp.ScanLine[bmp.Height - 1];
for i := 1 to PixelCount div DivFaktor do
begin
p := Random(PixelCount);
r := r + RgbLine[p].r;
g := g + RgbLine[p].g;
b := b + RgbLine[p].b;
end;
Result.r := r div (PixelCount div DivFaktor);
Result.g := g div (PixelCount div DivFaktor);
Result.b := b div (PixelCount div DivFaktor);
end;
Ich habe absichtlich auf bereits vorhandene Strukturen (TRgbQuad) die bereits definiert sind verzichtet. Auch auf notwendige try .. finally .. end Strukturen habe ich zur Vereinfachung verzichtet. Der Code läßt sich natürlich noch optimieren, mir geht es hier in erster Linie um das Prinzip.
Die Funktion GetAverageColor2 ist bei einem DivFaktor = 1000 um den Faktor 60 schneller als die Funktion GetAverageColor1.
Das Prinzip beruht grundsätzlich auf die Tatsache, dass man nicht jeden Pixel auswerten muss. Ich habe das Ganze mit 10 verschiedenen Bildern durchrechnen lassen. In der folgenden Tabelle ist die erste Spalte das exakte Ergebnis. Die 2. Spalte bei einen DivFaktor = 1000 und die 3. Spalte bei einem DivFaktor von 10000.
Code:
R G B R G B R G B
131 102 86 130 102 86 135 105 89
101 89 79 102 89 79 101 89 78
113 118 82 114 119 83 113 118 83
78 81 61 79 82 62 75 76 59
133 119 99 132 118 99 133 119 98
129 141 155 129 141 154 130 142 154
135 145 157 135 145 157 136 145 157
127 123 122 127 123 123 125 121 120
151 146 138 151 146 138 149 144 136
124 117 106 124 117 106 122 115 105