pycairo中不支持灰度图像的透明度

问题描述 投票:0回答:1

我试图在一个二维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()

输出结果应该是这样的enter image description here

但结果却是这样的:

enter image description here.

为什么会发生这种情况?我只是想画出相互叠加的透明灰度圆,但它似乎没有检测到颜色,它只使用alpha值。

python cairo pycairo
1个回答
0
投票
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翻转的图像)。

output of the program

© www.soinside.com 2019 - 2024. All rights reserved.