0

有没有一种快速的方法来计算 Firemonkey 位图中的主色(最常见的颜色)?

或者在使用调色板时,FMX 中是否有一个选项可以减少颜色的数量,例如在 Vcl.Imaging.GIFImg 中?

4

1 回答 1

0

我已经实现了自己的解决方案,它没有针对计算快速结果进行优化。

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 毫秒才能获得全高清图像。加速可以是限制色彩空间或不采用每个像素,而是使用一组具有代表性的像素。

于 2019-07-30T09:49:39.943 回答