【问题标题】:Delphi blur Effect using VCL使用 VCL 的 Delphi 模糊效果
【发布时间】:2018-02-23 08:49:09
【问题描述】:

我正在实现自定义面板模糊效果。我想模拟玻璃效果。 我在搜索中找到了the following code

function blur(source:TBitmap):TBitmap;
var
  x, y, x3:integer;
  tline, mline, bline:PByteArray;

begin

  for y := 1 to source.Height - 2 do
  begin
      tline := source.ScanLine[y-1];
      mline := source.ScanLine[y];
      bline := source.ScanLine[y+1];
      for x := 1 to source.Width - 2 do
      begin
        x3 := x*3;

          mline^[x3] :=
            (mline^[x3 - 3] + mline^[x3 + 3] +
             tline^[x3 - 3] + tline^[x3 + 3] + tline^[x3] +
             mline^[x3 - 3] + mline^[x3 + 3] + mline^[x3]) div 8;

          mline^[x3 + 1] :=
            (mline^[x3 - 2] + mline^[x*3 + 4] +
             tline^[x3 - 2] + tline^[x*3 + 4] + tline^[x3+1] +
             mline^[x3 - 2] + mline^[x*3 + 4] + mline^[x3+1]) div 8;

          mline^[x3 + 2] :=
            (mline^[x3 - 1] + mline^[x3 + 5] +
            tline^[x3 - 1] + tline^[x3 + 5] + tline^[x3+2] +
            mline^[x3 - 1] + mline^[x3 + 5] + mline^[x3+2]) div 8;
      end;
  end;
  result := source;
end;

上面的函数可以正常工作,但由于我不是作者,对图像处理一无所知,我会在这个函数中添加设置模糊级别的可能性。

我还找到了following code,它可以工作并且可以配置,但是应用起来很慢。

我发现“配置”模糊的临时解决方案是根据您想要的模糊程度调整函数以递归方式运行。见下面的代码sn-p:

function blur(source:TBitmap; nTimes: Integer = 1): TBitmap;
var
  x, y, x3, I : integer;
  tline, mline, bline: PByteArray;
begin
  if nTimes = 0 then Exit(source);

  for I := 0 to nTimes do...

问题是:如何制作可配置且高效的模糊效果或者谁能帮我改进上述功能?

【问题讨论】:

  • 这很有趣,但如果您错过了重点,这是一个问答网站。你知道什么代表一个问题,不是吗?
  • @TomBrunberg 一千个道歉。我太兴奋了,我忘记了主要的。我非常重视这个网站,我尽一切努力满足一个好问题的要求。我已经编辑了这个问题,如果可能的话,希望你能帮助我。
  • 当然有很多关于这个主题的文章。你一定做过一些研究。
  • 您面前有代码。你不明白它在做什么?使其可调整是相当微不足道的。这不是一个问题,这是一个工作请求——你要求的是可交付成果。这不是这里的工作方式。
  • @AnselmoMS 您上面的代码实现了box blur 的类型。您可以在这个问题中阅读模糊算法:How is Gaussian Blur Implemented?

标签: image delphi blur effect graphic


【解决方案1】:

此功能无法正常工作,可能是由于复制粘贴中的错误。

模糊是一种卷积。要获得模糊图像中像素的值,您必须计算某个附近的源像素的加权和。

Dest[y,x] = Sum(dy=-size/2..size/2, dx=-size/2..size/2) (Src[y+dy, x+dx] * Weight[dy, dx])

在你的情况下,系数(权重)是

  1/8  1/8  1/8      
  1/8  0    1/8   or 1/8 * (1,1,1,1,0,1,1,1,1)
  1/8  1/8  1/8

这不是高斯模糊 - 它的 3x3 内核系数是 1/16 * (1, 2, 1, 2, 4, 2, 1, 2, 1)。请注意,中心像素涉及的系数最大。

此外,代码不会利用较低的扫描线 - 每个总和的第三行应使用 bline

一般来说,你可以计算和使用任意大小的高斯核(公式取决于sigma,到处都有描述),但是直接使用大尺寸的滤波器很慢。对同一图像多次应用小高斯滤波器相当于应用一些更大的滤波器。

对于较大的内核大小,有一种快速(但更复杂)的方法 - 通过 FFT(快速傅里叶变换)进行快速卷积。

【讨论】:

  • 如果我理解正确,我的临时解决方案是最有效的吗?
  • 不是最有效但相当可靠(取决于所需的速度和模糊程度)。快速卷积对于大内核尺寸更有效,但需要拆分为 r,g,b 分量..
  • “这个函数不能正常工作,可能是因为复制粘贴的错误。”它是指我问题中的完整函数代码吗?
  • 是的。它不是高斯模糊。它不是对称模糊——我已经写过bline——我怀疑模糊图像会在每次迭代时爬上来
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多