vips - 如何实现边缘羽化效果

我正在使用 vips 图像库,具体来说是它的 Lua 绑定库 lua-vips,我尝试找到一种方法来给图像的边缘添加羽化效果。

这是我第一次使用这种类型的库进行此类任务,我一直在查看可用的函数列表,但仍然没有对此有任何想法。这不是复杂的形状,只是一个基本的矩形图像,在此图像的顶部和底部应该与背景(我正在使用 vips_composite() 进行叠加的另一张图像)平滑地融合。

假设存在“feather_edges”方法,就像这样:

local bg = vips.Image.new_from_file("foo.png")
local img = vips.Image.new_from_file("bar.png") --比 `bg` 更小
img = img:feather_edges(6) --假设有一个 6px 的羽化效果
bg:composite(img, 'over')

但仍然不错,可以指定哪些部分应该被羽化。有没有什么想法如何做呢?

点赞
用户894763
用户894763

你需要从顶部图像中分离出 alpha 通道,用黑色边框遮盖边缘,模糊 alpha 以模糊边缘,然后重新连接,最后合成。

代码示例:

#!/usr/bin/luajit

vips = require 'vips'

function feather_edges(image, sigma)
    -- 将 alpha 和图像数据拆分开
    local alpha = image:extract_band(image:bands() - 1)
    local image = image:extract_band(0, {n = image:bands() - 1})

    -- 我们需要在 alpha 通道上放置黑色边框,然后对其进行模糊以实现柔化边缘,
    -- 并将该边框与 sigma 一起缩放
    local margin = sigma * 2
    alpha = alpha
        :crop(margin, margin,
            image:width() - 2 * margin, image:height() - 2 * margin)
        :embed(margin, margin, image:width(), image:height())
        :gaussblur(sigma)

    -- 重新连接 alpha 和图像数据
    return image:bandjoin(alpha)
end

bg = vips.Image.new_from_file(arg[1], {access = "sequential"})
fg = vips.Image.new_from_file(arg[2], {access = "sequential"})
fg = feather_edges(fg, 10)
out = bg:composite(fg, "over", {x = 100, y = 100})
out:write_to_file(arg[3])
2019-03-09 12:50:09
用户9781480
用户9781480

如jcupitt所说,我们需要从图像中提取 alpha 波段,对其进行模糊处理,再将其重新合并并与背景进行合成,但使用原始的函数会在前景图像周围留下一个细小的黑边框。

为了解决这个问题,我们需要复制图像,根据sigma参数调整其大小,从缩小的副本中提取 alpha 波段,对其进行模糊处理,并用它替换原始图像的 alpha 波段。这样,原始图像的边框将完全被 alpha 透明部分覆盖。

local function featherEdges(img, sigma)
    local copy = img:copy()
        :resize(1, { vscale = (img:height() - sigma * 2) / img:height() })
        :embed(0, sigma, img:width(), img:height())
    local alpha = copy
        :extract_band(copy:bands() - 1)
        :gaussblur(sigma)
    return img
        :extract_band(0, { n = img:bands() - 1 })
        :bandjoin(alpha)
end
2019-03-11 20:31:13