我如何计算 Firemonkey 中 TBitmap 的主色?
How can I calculate the dominant color of a TBitmap in Firemonkey?
在 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 毫秒才能获得全高清图像。加速可以是限制颜色 space 或不采用每个像素而是使用一组具有代表性的像素。
在 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 毫秒才能获得全高清图像。加速可以是限制颜色 space 或不采用每个像素而是使用一组具有代表性的像素。