delphi,图片只保留最多颜色部分,判断一张图片里面哪个颜色最多(TBitMap)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi,图片只保留最多颜色部分,判断一张图片里面哪个颜色最多(TBitMap)相关的知识,希望对你有一定的参考价值。

有一个思路,扫描整张图像,把每个像素的颜色值取出TColor,放到一个类似集合(key,value)中用于计数,如果集合存在像素(key),就取出value,+1后放回集合中,否则存入key,1。
完成后再判断哪个颜色最多。
类似java的map的结构。
最后再扫描一次图片,除去其它颜色。
要求写出 集合 代码,如果能实现功能,用其它思路也可以。

参考技术A 记得好像有这个控件,另外API估计实现不了你的这个想法,必须用第三方控件比较简单。记得好像是个ami开头的控件 参考技术B 图像编程并不是全部需要自己做,一般用windows的API库,另外有很多其它库,因为具体没做过,只能提供思路了本回答被提问者和网友采纳 参考技术C 逐点扫描,可能比较慢的哦。bmp

Delphi 在另一张图片上绘制 png 文件的一部分

【中文标题】Delphi 在另一张图片上绘制 png 文件的一部分【英文标题】:Delphi drawing part of png file on another image 【发布时间】:2021-05-17 03:26:39 【问题描述】:

我正在使用此函数在特定位置的 TImage 上绘制 png:

procedure TForm1.PlacePNG(nam: string; px, py: Integer);
var
  vPic: TPicture;
  vSrc: TGraphic;
begin
  vPic := TPicture.Create;
  try
    vPic.LoadFromFile(Nam);
    vSrc := vPic.Graphic;
    Image1.Canvas.Draw(px, py, vSrc);
  finally
    vPic.Free;
  end;
end;

我的问题:使用 png 文件的 部分 做到这一点的最佳方法是什么,同时又不会失去其透明度?

【问题讨论】:

【参考方案1】:

这是一个有趣的问题!

当然,绘制整个 PNG 很简单:

procedure TForm1.FormCreate(Sender: TObject);
var
  bg, fg: TPngImage;
begin

  bg := TPngImage.Create;
  try
    bg.LoadFromFile('K:\bg.png');
    fg := TPngImage.Create;
    try
      fg.LoadFromFile('K:\fg.png');
      Image1.Picture.Graphic := bg;
      Image2.Picture.Graphic := fg;
      fg.Draw(bg.Canvas, Rect(0, 0, fg.Width, fg.Height));
      Image3.Picture.Graphic := bg;
    finally
      fg.Free;
    end;
  finally
    bg.Free;
  end;

end;

要仅绘制一部分,一个可能的解决方案是获取图像为 32-bpp RGBA 位图,然后使用 Windows API,具体而言,AlphaBlend 函数:

procedure TForm1.FormCreate(Sender: TObject);
var
  bg, fg: TPngImage;
  bgbm, fgbm: TBitmap;
  BlendFunction: TBlendFunction;
begin

  // Load background PNG
  bg := TPngImage.Create;
  try

    bg.LoadFromFile('K:\bg.png');

    // Load foreground PNG
    fg := TPngImage.Create;
    try

      fg.LoadFromFile('K:\fg.png');

      // Preview background and foreground
      Image1.Picture.Graphic := bg;
      Image2.Picture.Graphic := fg;

      // Create background BMP
      bgbm := TBitmap.Create;
      try

        bgbm.Assign(bg);

        // Create foreground BMP
        fgbm := TBitmap.Create;
        try

          fgbm.Assign(fg);

          // Blend PART OF foreground BMP onto background BMP
          BlendFunction.BlendOp := AC_SRC_OVER;
          BlendFunction.BlendFlags := 0;
          BlendFunction.SourceConstantAlpha := 255;
          BlendFunction.AlphaFormat := AC_SRC_ALPHA;
          if not Winapi.Windows.AlphaBlend(
            bgbm.Canvas.Handle,
            100,
            100,
            200,
            200,
            fgbm.Canvas.Handle,
            200,
            200,
            200,
            200,
            BlendFunction
          ) then
            RaiseLastOSError;

          // Preview result
          Image3.Picture.Graphic := bgbm;

        finally
          fgbm.Free;
        end;

      finally
        bgbm.Free;
      end;

    finally
      fg.Free;
    end;

  finally
    bg.Free;
  end;

end;

【讨论】:

它对我不起作用。系统错误。代码:87。参数不正确。 @OferLeshem:你确定你将 PNG 转换为位图吗?如果您尝试将AlphaBlendMyPng.Canvas.Handle 一起使用,您将收到该错误消息。 我目前没有安装 Delphi 来测试这个,但是 TCanvas.CopyRect() 在这种情况下可以工作吗? @RemyLebeau:不,这不适用于 Alpha 通道。在内部,它使用StretchBlt @AndreasRejbrand 我用 D7 将它调整为 PngImage 2.0's TPngObject(使用 ZLib 1.2.8),还得到了 $00000087,甚至确保两个矩形都在范围内并且不重叠。我猜我的TBitmap 版本太旧了,不支持/期待 RGBA。

以上是关于delphi,图片只保留最多颜色部分,判断一张图片里面哪个颜色最多(TBitMap)的主要内容,如果未能解决你的问题,请参考以下文章

判断一张图片的颜色数和亮度值

用java能分辨出一张图片的不同部位颜色吗

opencv之颜色过滤只留下图片中的红色区域

图片常见格式

有一张png格式的图片,在delphi中如何把该图片分成三份显示?

请问delphi 7 如何读取JPG图片的像素颜色值?