[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pygame] Simpler scaling method with surfarray
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi everyone,
I've been playing with the surfarray module and, after perusing the Numeric
docs, I have found another method to scale up an image besides the one on the
surfarray tutorial, faster and simpler:
if imgarray.shape[0] >= imgarray.shape[1]:
scaleup = N.repeat(N.repeat(imgarray, 4, 1), 4, 0)
else:
scaleup = N.repeat(N.repeat(imgarray, 4, 0), 4, 1)
The function 'repeat' repeats the rows/columns of the given array (first
parameter) in the given axis (third parameter) the given number of times
(second parameter). What the code above does is repeat the image columns four
times and then repeat the rows four times.
By some reason, the snippet above executes faster if the smaller axis is
repeated before the larger. Doing it in the reverse order will slow down the
method considerably. For example, scaling the default surfarray image 2x, but
with reversed axis order, makes the N.repeat method 1% _slower_ than the
method on the surfarray intro!
The real merit of this other way is that it is trivial to extend it to other
scaling factors. Making things the original way, by increment slicing, is
possible, and somewhat simple, but optimizing it (like done on the sample
file included, benchmark.py) is not.
| Old method | New method | Savings |
--------------+--------------+--------------+-----------+
2x scaling | 6.3 s | 4.7 s | 25.8% |
3x scaling | 13.9 s | 8.2 s | 41.3% |
4x scaling | 23.3 s | 12.5 s | 46.4% |
It'd be worth including this somewhere -- maybe in the surfarray intro, maybe
in the PCR. What do you think?
- --
Fábio Dias
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iEYEARECAAYFAjwOol8ACgkQalOQFrvzGQrvbwCgk/YJp+/Zar4IFfUN+v/CPXbZ
59kAn1izmtAYjGH/0rH0fl2UYVlzb1K8
=aSzT
-----END PGP SIGNATURE-----
import os
import time
try:
import pygame
import pygame.image
import Numeric as N
import pygame.surfarray as surfarray
from pygame.locals import *
except ImportError:
raise ImportError, 'Error Importing Pygame/surfarray/image or Numeric'
pygame.init()
print 'Press the mouse button to advance image.'
print 'Press the "s" key to save the current image.'
def surfdemo_show(array_img, name):
"displays a surface, waits for user to continue"
screen = pygame.display.set_mode(array_img.shape[:2], 0, 32)
surfarray.blit_array(screen, array_img)
pygame.display.flip()
pygame.display.set_caption(name)
while 1:
e = pygame.event.poll()
if e.type == MOUSEBUTTONDOWN: break
elif e.type == KEYDOWN and e.key == K_s:
pygame.image.save(screen, name+'.bmp')
elif e.type == QUIT: raise SystemExit
#imgarray
imagename = os.path.join('data', 'arraydemo.bmp')
imgsurface = pygame.image.load(imagename)
imgarray = surfarray.array2d(imgsurface)
start1 = time.time()
for i in range(100):
size = N.array(imgarray.shape)*4
scaleup = N.zeros(size)
scaleup[::4,::4] = scaleup[2::4,::4] = imgarray
scaleup[1::2,::4] = scaleup[::2,::4]
scaleup[:,2::4] = scaleup[:,::4]
scaleup[:,1::2] = scaleup[:,::2]
end1 = time.time()
print 'Old method: %3.1f s' % (end1 - start1)
surfdemo_show(scaleup, 'scaleup')
start2 = time.time()
for i in range(100):
if imgarray.shape[0] >= imgarray.shape[1]:
scaleup = N.repeat(N.repeat(imgarray, 4, 1), 4, 0)
else:
scaleup = N.repeat(N.repeat(imgarray, 4, 0), 4, 1)
end2 = time.time()
print 'New method: %3.1f s' % (end2 - start2)
print 'Savings: %3.1f%%' % ((1 - (end2 - start2)/float(end1 - start1)) * 100)
surfdemo_show(scaleup, 'scaleup')