Two (unrelated) anomalies in pygame.Surface.blit(), bugs or what ?
Tests in windows XP + sp2
Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on win32
pygame 1.8.1release ( installed from pygame-1.8.1release.win32-py2.4.msi )
1. The pygame documentation and help(pygame.Surface.blit) tells
Surface.blit(source, dest, area=None, special_flags = 0): return Rect
but
surf.blit(sf2,(0,0),special_flags = op)
crashes with traceback:
[...]
File "F:\newcode\_minitest\pygame blit\eblit.py", line 23, in blend
surf.blit(sf2,(0,0),special_flags = op) # crash
TypeError: blit() takes no keyword arguments
Replacing with:
surf.blit(sf2,(0,0),None,op)
there is no crash.
On the other side, dst1.blit(src1, (0,0)) is acceptable.
Looks like a bug or that the real signature is
Surface.blit(source, dest, *args ): return Rect ?
( eblit.py demoes this problem )
2. When blitting (with no blend flags) an opaque pixel ( alpha channel at 255 ) over any other pixel, seems natural that the resulting color be the src color. (opaque is opaque, right ?). In most cases pygame is off by one, by example:
. dst is filled with (x,0,0,128)
. src is filled with (0,z,0,255)
. dst.blit(src,(0,0)) will be filled with ( 0, z-1, 0, 255)
( minusblit.py demoes this )
--
claxo
# --> begin file eblit.py # Surface.blit signature seems to be wrong or there is a bug import sys, os, time import pygame from pygame.locals import * print'pygame version:',pygame.version.ver pygame.init() pygame.display.set_mode((300,300),0,32) screen = pygame.display.get_surface() pygame.display.update() # no alpha def sf(i): surf = pygame.Surface((32,32), SWSURFACE ,32) color = (i,i,i) surf.fill(color) return surf def blend( sf1, sf2, op): surf = sf1.copy() surf.blit(sf2,(0,0),special_flags = op) # crash #surf.blit(sf2,(0,0),None,op) # no crash return surf d={ 'ovr':0, 'add':BLEND_ADD, 'sub':BLEND_SUB, 'mult':BLEND_MULT, 'min':BLEND_MIN, 'max':BLEND_MAX } def show( i, j, op): global screen,d print i,j,op ## try: sf1 = sf(i) sf2 = sf(j) res = blend(sf1,sf2,d[op]) print 'sample:',res.get_at((0,0)) screen.blit( sf1,(10,10)) screen.blit( sf2,(10+32,10)) screen.blit( res, (10+32+32,10)) pygame.display.update() pygame.event.pump() ## except: ## print '* exception' show( 0,255, 'ovr') time.sleep(2) pygame.quit() ## File "F:\newcode\_minitest\pygame blit\eblit.py", line 23, in blend ## surf.blit(sf2,(0,0),special_flags = op) # crash ##TypeError: blit() takes no keyword arguments ##--- ##Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on win32 ##Type "help", "copyright", "credits" or "license" for more information. ##pygame 1.8.1release from pygame-1.8.1release.win32-py2.4.msi # <-- end file eblit.py
# --> file minusblit.py begins # opaque blits seems off by one import sys, os, time import pygame from pygame.locals import * print'pygame version:',pygame.version.ver pygame.init() pygame.display.set_mode((300,300),0,32) screen = pygame.display.get_surface() pygame.display.update() dst = pygame.Surface( (256,256), SRCALPHA ,32) for j in xrange(256): for i in xrange(256): dst.set_at((i,j),(i,0,0,j)) src = pygame.Surface( (256,256), SRCALPHA ,32) for j in xrange(256): for i in xrange(256): src.set_at((i,j),(0,i,0,255)) res = dst.copy() res.blit(src,(0,0)) cntEquals = 0 cntMinusOne = 0 for j in xrange(256): for i in xrange(256): res_sample = res.get_at((i,j)) assert( res_sample[3]==255 ) assert( res_sample[0]==0 ) res_sample1 = res_sample[1] src_sample1 = src.get_at((i,j))[1] if res_sample1==src_sample1: cntEquals += 1 elif res_sample1==(src_sample1-1): cntMinusOne += 1 print 'cntEquals:',cntEquals print 'cntMinusOne:',cntMinusOne print 'other:', 256*256-(cntEquals+cntMinusOne) pygame.quit() ##Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on win32 ##Type "help", "copyright", "credits" or "license" for more information. ##pygame 1.8.1release from pygame-1.8.1release.win32-py2.4.msi # <-- file minusblit.py ends