Lua VIP-如何实现边缘羽毛效果

Lua VIP-如何实现边缘羽毛效果,lua,vips,Lua,Vips,我使用vips库来处理一些图像,特别是它的Lua绑定,Lua vips,我试图找到一种方法来在图像的边缘上产生羽毛效果 这是我第一次尝试一个库来完成这类任务,我一直在寻找可用的库,但仍然不知道如何使用它。这不是复杂的形状,只是一个基本的矩形图像,其上下边缘应该与背景平滑融合(我目前正在使用的另一个图像) 假设存在“feather_Edge”方法,它将类似于: local bg = vips.Image.new_from_file("foo.png") local img = vips.Image

我使用vips库来处理一些图像,特别是它的Lua绑定,Lua vips,我试图找到一种方法来在图像的边缘上产生羽毛效果

这是我第一次尝试一个库来完成这类任务,我一直在寻找可用的库,但仍然不知道如何使用它。这不是复杂的形状,只是一个基本的矩形图像,其上下边缘应该与背景平滑融合(我目前正在使用的另一个图像)

假设存在“feather_Edge”方法,它将类似于:

local bg = vips.Image.new_from_file("foo.png")
local img = vips.Image.new_from_file("bar.png") --smaller than `bg`
img = img:feather_edges(6) --imagine a 6px feather
bg:composite(img, 'over')
#!/usr/bin/luajit

vips = require 'vips'

function feather_edges(image, sigma)
    -- split to alpha + image data 
    local alpha = image:extract_band(image:bands() - 1)
    local image = image:extract_band(0, {n = image:bands() - 1})

    -- we need to place a black border on the alpha we can then feather into,
    -- and scale this border with 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)

    -- and reattach
    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])

但仍然可以指定图像的哪些部分应该被羽化。有什么办法吗?

您需要从顶部图像中提取alpha,用黑色边框遮住边缘,模糊alpha使边缘变细,重新附着,然后合成

比如:

local bg = vips.Image.new_from_file("foo.png")
local img = vips.Image.new_from_file("bar.png") --smaller than `bg`
img = img:feather_edges(6) --imagine a 6px feather
bg:composite(img, 'over')
#!/usr/bin/luajit

vips = require 'vips'

function feather_edges(image, sigma)
    -- split to alpha + image data 
    local alpha = image:extract_band(image:bands() - 1)
    local image = image:extract_band(0, {n = image:bands() - 1})

    -- we need to place a black border on the alpha we can then feather into,
    -- and scale this border with 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)

    -- and reattach
    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])

正如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

这几乎是我所需要的。一个问题是黑色边框变得可见。但是你给了我很好的建议,因为我不知道如何在特定的波段工作。我设法对你的功能做了一个小的调整,它解决了这个问题!我应该将其作为我自己问题的答案发布还是编辑我的帖子?嗨,PiFace,我会将其作为你自己问题的答案发布,然后接受。我更新了黑边界问题的解决方案。很好!但是与其缩小alpha,不如遮掩边缘?它会更快,并且适用于具有复杂形状的图像(因为不会丢失图像和alpha之间的对齐)。我用另一个选项更新了我的答案。你也可以删除
copy
——所有libvips操作都是非破坏性的,并返回新图像,而不是修改它们的参数。哦,我明白了,这是真的,复制是不必要的。我没有考虑裁剪而不是调整大小:顺便问一句,这对什么样的复杂形状有用?我通常用它来测试复杂形状的遮罩