【问题标题】:No transparency support for gray scale image in pycairopycairo 中不支持灰度图像的透明度
【发布时间】:2020-05-23 07:05:40
【问题描述】:

我正在尝试将重叠的透明圆圈绘制到 2d 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 值。

【问题讨论】:

  • 在创建表面时使用 cairo.FORMAT_ARGB32 而不是 cairo.FORMAT_A8 会发生什么?
  • 另外 ctx.set_source_rgba() 使用 [0, 1] 范围内的所有浮点数,而不是 256。
  • @hetepeperfan 哎呀,我的意思是 1、1、1。编辑了问题。另外,如果我输入 argb32 和 dtype = uint32。我得到了 2 个不透明的白色圆圈,而另一个圆圈甚至不是黑色的! imgur.com/a/Mwz8lwo
  • 经过进一步检查,黑色圆圈似乎有2.15e+0.9的值。而白圈值为4.29e+09。白色圆圈似乎画在上面。因为没有重叠的值。

标签: python cairo pycairo


【解决方案1】:
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")

...产生此输出(我使用的坐标与您的代码使用的坐标相同,不知道您如何最终输出带有 X/Y 翻转的图像):

【讨论】:

  • 谢谢,但是如何处理 x 数量的圆圈以这种方式绘制?这种方式似乎只适用于 2 个圆圈。
  • 嗯...您想要的x 圈子的结果是什么?我不太确定您的目标是什么,也不明白为什么您希望您的代码“正常工作”。为什么在第一个圆圈之外绘制第二个圆圈“什么都不做”?
  • 那是因为我想用灰度颜色和透明度来绘制。黑色背景上的半透明黑色圆圈不应该是可见的,但在白色圆圈上应该是可见的。我想将许多透明圆圈重叠在一起,所有这些透明圆圈都应该有颜色,比如黑白或灰色。
  • A8 表面只有一个 Alpha 通道。颜色对那里的绘图没有影响。如果你想要颜色和透明度,你需要一个ARGB32 表面。您看到的黑色/灰色/白色只是 Alpha 通道的表示,可以保存到文件中。
猜你喜欢
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 2012-11-23
  • 2013-01-22
  • 1970-01-01
  • 2014-08-22
  • 2021-10-08
  • 2015-08-07
相关资源
最近更新 更多