Pygame 和 blitting:白底白字 = 灰色?
我正在使用 pygame(1.9.0rc3,尽管这也发生在 1.8.1 中)来创建热图。 为了构建热图,我使用一个小的 24 位 11x11px 点 PNG 图像,该图像具有白色背景和一个非常低不透明度的灰色点,该点正好停在边缘:
点图像 http://img442.imageshack.us/img442/465/dot.png
点周围的区域是完美的白色,#ffffff,正如它应该的那样。 然而,当我使用 pygame 使用 BLEND_MULT 将图像多次传输到新表面时,会出现一个灰色方块,就好像点背景不是完美的白色一样,这是没有意义的。
以下代码加上包含的图像可以重现此内容:
import os
import numpy
import pygame
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.display.init()
pygame.display.set_mode((1,1), 0, 32)
dot_image = pygame.image.load('dot.png').convert_alpha()
surf = pygame.Surface((100, 100), 0, 32)
surf.fill((255, 255, 255))
surf = surf.convert_alpha()
for i in range(50):
surf.blit(dot_image, (20, 40), None, pygame.BLEND_MULT)
for i in range(100):
surf.blit(dot_image, (60, 40), None, pygame.BLEND_MULT)
pygame.image.save(surf, 'result.png')
运行代码时,您将获得以下图像:
结果混合后的图像 http://img263.imageshack.us/img263/4568/result.png
发生这种情况有原因吗? 我该如何解决这个问题?
I'm using pygame (1.9.0rc3, though this also happens in 1.8.1) to create a heatmap. To build the heatmap, I use a small, 24-bit 11x11px dot PNG image with a white background and a very low-opacity grey dot that stops exactly at the edges:
Dot image http://img442.imageshack.us/img442/465/dot.png
The area around the dot is perfect white, #ffffff, as it should be. However, when I use pygame to blit the image multiple times to a new surface using BLEND_MULT, a grey square appears, as though the dot background wasn't perfect white, which doesn't make sense.
The following code, plus included images, can reproduce this:
import os
import numpy
import pygame
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.display.init()
pygame.display.set_mode((1,1), 0, 32)
dot_image = pygame.image.load('dot.png').convert_alpha()
surf = pygame.Surface((100, 100), 0, 32)
surf.fill((255, 255, 255))
surf = surf.convert_alpha()
for i in range(50):
surf.blit(dot_image, (20, 40), None, pygame.BLEND_MULT)
for i in range(100):
surf.blit(dot_image, (60, 40), None, pygame.BLEND_MULT)
pygame.image.save(surf, 'result.png')
When you run the code, you will get the following image:
Resulting image after blending http://img263.imageshack.us/img263/4568/result.png
Is there a reason this happens? How can I work around it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过尝试后,我唯一能看到的是你是100%正确的。 每次乘以 255 都会减 1。 最后,我下载了 pygame 源代码,答案就在那里,在
surface.h
中:Pygame 实现了乘法混合 as
和 not,这将是正确的方法,因为
这可能是完成的出于优化目的——位移比除法快得多。 由于比率
255 / 256
非常接近 1,因此唯一的区别是“相差一”:您得到的值是预期值减一 - 除非您预期为零,在这种情况下,结果是正确的。因此,您有以下可能性:
1
添加到所有结果值。 最接近预期结果,除了丢失零。255 * 255 == 255
(您知道我的意思),则 ORing1
而不是添加就足够了,并且速度更快。请注意,如果您不选择答案 1,出于性能原因,您可能必须编写 C 扩展,而不是直接使用 Python。
After trying around, the only thing I could see was that you're 100% right. Multiplication by 255 results in a subtraction of 1 -- every time. In the end, I downloaded the pygame source code, and the answer is right there, in
surface.h
:Pygame implements multiply blending as
and not, which would be the correct way, as
This is probably done for optimization purposes -- a bit shift is a lot faster than a division. As the ratio
255 / 256
is very close to one, the only difference this makes is an "off by one": The value you get is the expected value minus one -- except if you expected zero, in which case the result is correct.So, you have these possibilities:
1
to all result values. Closest to the expected result, except you lose the zero.255 * 255 == 255
(you know what I mean), ORing1
instead of adding suffices, and is faster.Note that if you don't choose answer 1, for performance reasons you'll probably have to write a C extension instead of using Python directly.
在做热图时也遇到了这个问题,在阅读了 balpha 的答案后,选择以“正确”(如果更慢)的方式修复它。 将
alphablit.c
中的各种更改为
This required patching multifunctions(尽管我也修补了
surface.h
)。 不确定这对性能有多大影响,但对于特定的(热图)应用程序,它会生成更漂亮的图像。Also encountered this problem doing heatmaps and after reading balpha's answer, chose to fix it the "right" (if slower) way. Change the various
to
This required patching multiply functions in
alphablit.c
(though I patchedsurface.h
as well). Not sure how much this impacts performance, but for the specific (heatmap) application, it produces much prettier images.