vips - 如何实现边缘羽化效果
vips - How to achieve edge feather effect
我正在使用 vips 库来处理一些图像,特别是它的 Lua 绑定,lua-vips,我正试图找到一种方法来对图像的边缘。
这是我第一次尝试使用库来完成此类任务,我一直在 list of functions available, but still no idea on how to it. It's not complex shape, just a basic rectangular image whose top and bottom edges should blend smoothly with the background (another image that I'm currently using vips_composite() 上查看它)。
假设存在一个 "feather_edges" 方法,它将类似于:
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')
但是指定图像的哪些部分应该被羽化还是很好的。有什么想法吗?
您需要从顶部图像中拉出 alpha,用黑色边框遮住边缘,模糊 alpha 以羽化边缘,重新附加,然后合成。
类似于:
#!/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
我正在使用 vips 库来处理一些图像,特别是它的 Lua 绑定,lua-vips,我正试图找到一种方法来对图像的边缘。
这是我第一次尝试使用库来完成此类任务,我一直在 list of functions available, but still no idea on how to it. It's not complex shape, just a basic rectangular image whose top and bottom edges should blend smoothly with the background (another image that I'm currently using vips_composite() 上查看它)。
假设存在一个 "feather_edges" 方法,它将类似于:
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')
但是指定图像的哪些部分应该被羽化还是很好的。有什么想法吗?
您需要从顶部图像中拉出 alpha,用黑色边框遮住边缘,模糊 alpha 以羽化边缘,重新附加,然后合成。
类似于:
#!/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