有没有一种快速的方法来计算 Firemonkey 位图中的主色(最常见的颜色)?
或者在使用调色板时,FMX 中是否有一个选项可以减少颜色的数量,例如在 Vcl.Imaging.GIFImg 中?
有没有一种快速的方法来计算 Firemonkey 位图中的主色(最常见的颜色)?
或者在使用调色板时,FMX 中是否有一个选项可以减少颜色的数量,例如在 Vcl.Imaging.GIFImg 中?
我已经实现了自己的解决方案,它没有针对计算快速结果进行优化。
function GetDominanteColor(Bmp: TBitmap): TAlphaColor;
var
BMPData: TBitmapData;
x, y: integer;
Col: TAlphaColor;
Count: cardinal;
Histogram: TDictionary<TAlphaColor, cardinal>;
begin
result := TAlphaColors.Null;
if Bmp.Width * Bmp.Height > 0 then
if Bmp.Map(TMapAccess.Read, BMPData) then
begin
Histogram := TDictionary<TAlphaColor, cardinal>.Create;
try
// build histogram
for x := 0 to Bmp.Width - 1 do
for y := 0 to Bmp.Height - 1 do
begin
Col := BMPData.GetPixel(x, y);
if Histogram.TryGetValue(Col, Count) then
Histogram.Items[Col] := Count + 1
else
Histogram.Add(Col, 1);
end;
// search color with highest score
Count := 0;
for Col in Histogram.Keys do
begin
if Histogram.Items[Col] > Count then
begin
Count := Histogram.Items[Col];
result := Col;
end;
end;
{$IFDEF DEBUG}
FMX.Types.Log.d('Dominante color %s from %d colors',
[IntToHex(result, 8), x]);
{$ENDIF}
finally
Histogram.Free;
end;
BMP.Unmap(BMPData);
end;
end;
在旧 CPU (i5-3360@2.8GHz) 上,此功能需要长达 200 毫秒才能获得全高清图像。加速可以是限制色彩空间或不采用每个像素,而是使用一组具有代表性的像素。