我试图在一个二维numpy数组中绘制重叠的透明圆。
img = np.zeros((256, 256), dtype=np.uint8)
surface = cairo.ImageSurface.create_for_data(
img, cairo.FORMAT_A8, 256, 256
)
ctx = cairo.Context(surface)
ctx.arc(128, 128, 22, 0, 2 * math.pi)
ctx.set_source_rgba(1, 1, 1, 1)
ctx.fill()
ctx.arc(128, 102, 22, 0, 2 * math.pi)
ctx.set_source_rgba(0, 0, 0, 0.5)
ctx.fill()
但结果却是这样的:
为什么会发生这种情况?我只是想画出相互叠加的透明灰度圆,但它似乎没有检测到颜色,它只使用alpha值。
img = np.zeros((256, 256), dtype=np.uint8)
surface = cairo.ImageSurface.create_for_data(
img, cairo.FORMAT_A8, 256, 256
)
ctx = cairo.Context(surface)
此时,表面是完全透明的,它被保存为一个完全黑色的PNG。
ctx.arc(128, 128, 22, 0, 2 * math.pi)
ctx.set_source_rgba(1, 1, 1, 1)
ctx.fill()
现在你用 "完全不透明 "填充一个圆圈(颜色组件被忽略)。这最终会变成一个白色的圆圈
ctx.arc(128, 102, 22, 0, 2 * math.pi)
ctx.set_source_rgba(0, 0, 0, 0.5)
ctx.fill()
这里你用 "半透明 "画第二个圆。最后变成了黑色。另一个圆圈已经画好的部分是在 "完全不透明 "上画 "半透明",最后变成 "完全不透明",所以保存为PNG时是白色的。
输出的结果应该是这样的。
所以,你不希望第二个圆圈被画在第一个圆圈的外面。为此,您需要 ctx.clip()
.
下面是一些Lua代码...
local cairo = require("lgi").cairo
local surface = cairo.ImageSurface.create(cairo.Format.A8, 256, 256)
local ctx = cairo.Context(surface)
ctx:arc(128, 128, 22, 0, 2 * math.pi)
ctx:set_source_rgba(1, 1, 1, 1)
-- Fill the circle, but do not clear the current path
ctx:fill_preserve()
-- Use the circle as a clip
ctx:clip()
ctx:arc(128, 102, 22, 0, 2 * math.pi)
ctx:set_source_rgba(0, 0, 0, 0.5)
-- Replace the default operator OVER with SOURCE:
-- Instead of drawing "ontop", just copy the source to the target
ctx:set_operator(cairo.Operator.SOURCE)
ctx:fill()
surface:write_to_png("out.png")
...产生了这样的输出(我使用了和你的代码相同的坐标,不知道你怎么会最终输出XY翻转的图像)。