HI Michl
I understood your code, thanks again, In the first time I was facing this subject (Color quantizer) I wanted to do it by tracing the pixels, and I did not know an efficient way and now when you suggest me an efficient way, I was wondering if I can do other things that I want with this way.
I want weight of each color in the color map of your code, I mean that I need to know for each pixel color in the colormap (source colors), how many pixels in the source bitmap has this color, and I tried to do it in my way, it works correctly when the source bitmap is small, I mean the weight of each pixel color that it calculates is correct, I tested it with a bitmap with 4 colors and 16*16 pixels, you can see the result in the screenshot attached. but it is not efficient for big bitmaps at all, so I was wondering if you can suggest me a better way for this.
Any help appreciated prior
Regards
here is my test code:
procedure TForm1.SourceColorsWithWeights;
var
SourceColorsBmp: TBGRABitmap;
i, Cnt, SourceColorCount, aWidth, aHeight: DWord;
sss: QWord;
PPixel: PBGRAPixel;
Pixel: TBGRAPixel;
DPixel: DWord absolute Pixel;
PixelMap: array of boolean;
D2: DWord;
D2Pixel: TBGRAPixel absolute D2;
WeightMap: array of integer;
SavedColors: array of TBGRAPixel;
j: integer;
procedure SaveColor(AColor: TBGRAPixel);
begin
SavedColors[Length(SavedColors) - 1] := AColor;
SetLength(SavedColors, Length(SavedColors) + 1);
end;
begin
SourceBmp := TBGRABitmap.Create('Pics' + PathDelim + 'Picture.jpg');
if SourceBmp.Bitmap.RawImage.Description.AlphaShift = 24 then
begin
sss := GetTickCount64;
SetLength(PixelMap, 1 shl 24); // 2^24=256*256*256 for all the colors in RGB
PPixel := SourceBmp.Data;
SourceColorCount := 0;
SetLength(SavedColors, 1);
for i := 0 to Pred(SourceBmp.NbPixels) do
begin
Pixel := PPixel^;
if not PixelMap[DPixel xor $FF000000] then
begin
Inc(SourceColorCount);
SaveColor(Pixel);
end;
PixelMap[DPixel xor $FF000000] := True;
Inc(PPixel);
end;
WriteLn('Source Color Count Time: ', GetTickCount64 - sss);
//Gain weight of each pixel color in color map
PPixel := SourceBmp.Data;
SetLength(WeightMap, SourceColorCount);
for i := 0 to Length(WeightMap) - 1 do
begin
WeightMap[i] := 0;
end;
for i := 0 to Pred(SourceBmp.NbPixels) do
begin
Pixel := PPixel^;
for j := 0 to Length(SavedColors) - 1 do
begin
if (SavedColors[j] = Pixel) then
begin
Inc(WeightMap[j]);
end;
end;
Inc(PPixel);
end;
WriteLn('Total Color Weights Time: ', GetTickCount64 - sss);
for i := 0 to Length(WeightMap) - 1 do
begin
WriteLn('WeightMap [ ', i, ' ] : ', WeightMap[i]);
end;
end;
SourceBmp.Free;
end;