Pygame和blitting:白色=灰色?

Ron*_*son 5 python pygame imaging image

我正在使用pygame(1.9.0rc3,虽然这也发生在1.8.1中)来创建热图.为了构建热图,我使用了一个小的24位11x11px点PNG图像,白色背景和非常低不透明度的灰色点在边缘处完全停止:

点图像http://img442.imageshack.us/img442/465/dot.png

点周围的区域是完美的白色,#fffff,应该是.但是,当我使用pygame使用BLEND_MULT将图像多次blit到新表面时,会出现一个灰色方块,好像点背景不是完美的白色,这没有意义.

以下代码以及包含的图像可以重现这一点:

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')
Run Code Online (Sandbox Code Playgroud)

运行代码时,您将看到以下图像:

混合后产生的图像http://img263.imageshack.us/img263/4568/result.png

有这种情况发生的原因吗?我该如何解决这个问题?

bal*_*pha 6

在尝试之后,我唯一能看到的就是你100%正确.乘以255会导致每次减1.最后,我下载了pygame源代码,答案就在那里,在surface.h:

#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
    dR = (dR && sR) ? (dR * sR) >> 8 : 0;          \
    dG = (dG && sG) ? (dG * sG) >> 8 : 0;          \
    dB = (dB && sB) ? (dB * sB) >> 8 : 0;
Run Code Online (Sandbox Code Playgroud)

Pygame实现了多次混合

new_val = old_dest * old_source / 256
Run Code Online (Sandbox Code Playgroud)

而不是,这将是正确的方式,如

new_val = old_dest * old_source / 255
Run Code Online (Sandbox Code Playgroud)

这可能是出于优化目的而进行的 - 比分割要快得多.由于该比率255 / 256非常接近于1,所以唯一的区别是"一个一个":您得到的值是预期值减一 - 除非您预期为零,在这种情况下结果是正确的.

所以,你有这些可能性:

  1. 忽略它,因为对于大多数目的而言,一个接一个并不重要.
  2. 添加1到所有结果值.最接近预期结果,除了你失去零.
  3. 如果整体正确性不重要,但你需要255 * 255 == 255(你知道我的意思),ORing 1而不是添加足够的东西,并且更快.

请注意,如果您不选择答案1,出于性能原因,您可能必须编写C扩展而不是直接使用Python.