首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vips -如何实现边缘羽化效果

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

Stack Overflow用户
提问于 2019-03-09 02:03:38
回答 2查看 211关注 0票数 1

我正在使用vips库来操作一些图像,特别是它的Lua绑定,lua-vips,并且我试图找到一种在图像边缘做羽毛效果的方法。

这是我第一次尝试使用库来完成这类任务,我一直在查看这个可用的list of functions,但仍然不知道如何使用它。它不是一个复杂的形状,只是一个基本的矩形图像,它的顶部和底部边缘应该与背景平滑地混合在一起(另一个我目前使用vips_composite()的图像)。

假设存在一个"feather_edges“方法,它将类似于:

代码语言:javascript
复制
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')

但是,指定图像的哪些部分应该被羽化还是很好的。你有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-09 20:50:09

您需要将alpha从顶部图像中拉出,用黑色边框遮罩边缘,模糊alpha以羽化边缘,重新附加,然后合成。

类似于:

代码语言:javascript
复制
#!/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])
票数 1
EN

Stack Overflow用户

发布于 2019-03-12 04:31:13

正如jcupitt所说,我们需要从图像中提取alpha带,模糊它,再次连接它,并将其与背景合成,但使用该函数时,在前景图像周围留下了一个细小的黑色边框。

为了克服这个问题,我们需要复制图像,根据sigma参数调整它的大小,从缩小的副本中提取alpha带,模糊它,并用它替换原始图像的alpha带。像这样,原始图像的边界将被alpha的透明部分完全覆盖。

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55068652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档