[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Smooth scaling using WMF drawings



Ben,

Since no one else has responded to this yet, I'll give it a try,
although it's a bit of a long shot.

If you're interested in working with vector graphics and you have some
C/C++ experience, you may want to consider integrating a 2D vector
graphics library with SDL/Pygame.  One such vector graphics library,
the Anti-Grain Geometry project (http://www.antigrain.com), is a
collection of algorithms that blit the rendering result to a
framebuffer, which can have any of a variety of pixel formats.  It's
not very difficult to "hook up" this rendering pipeline to SDL by
pointing it to the "pixels" property of a SDL_Surface structure and
telling it what pixel format the buffer uses.  The end result is that
there's no conversion or copying of pixel information from one library
to another: the 2D vector pipeline simply rasterizes its output
directly to your screen (or any other SDL/Pygame surface you provide),
which is extremely efficient.

Thanks to Pygame's C API, it shouldn't be hard to write a Python
extension module that works with Pygame to do all this.  It could even
be a cool new extension to Pygame itself.

AGG has built-in functionality for rendering SVG files, which it
supposedly does very quickly.  Another library called Cairo
(http://cairographics.org) may be a good alternative.  Both are
works-in-progress; AGG uses a (IMHO) fairly complicated C++ API that
relies on extensive use of templates, and isn't terribly
well-documented, unfortunately, while Cairo seems to have a very
straightforward C API.  I've only used AGG, so I can't really comment
much on Cairo, except to say that it looks like it has promise:
apparently both Mozilla and the GTK+ toolkit are planning to move to
its rendering engine in the near future (see
http://www.mozillazine.org/talkback.html?article=6498).

I hope this is of some help.

- Atul

On 4/29/05, Ben Friman <ben@xxxxxxxxxxxxxxx> wrote:
> Here's something for the weekend:
> 
> I am planning an application in which all window contents will scale automatically to
> the window size. I don't want to see the pixellation effects which you get with scaling
> bitmaps, so I had a look at what can be done with .WMF drawings. Here's the result,
> using PIL with Pygame.
> 
> If anyone can see a more efficient way of doing it, please let me know, as eventually I
> will be displaying up to 100 .WMF images in a window!  I did read that
> image.frombuffer() is more efficient than image.fromstring(), but in Pygame 1.6 it
> seems there is no "frombuffer" function. Is that right?
> 
> Here's the code:
> """
> 
> wmf_show.py  ----- brf Apr 2005   ---------
> 
> Just to find out how to use/display a WMF file in Pygame. It works. Of course,
> it is a CONVERTED image that we are looking at. To scale smoothly, you need to
> re-convert at each resolution, which is what this demo does.
> 
> """
> 
> import pygame, Image, WmfPlugin
> from pygame.locals import *
> import win32api
> 
> # ------------------------------------------------------------------------------------
> def main():
> 
>     pygame.init()
> 
>     SM_CXSCREEN = 0
>     SM_CYSCREEN = 1
>     x = win32api.GetSystemMetrics(SM_CXSCREEN)
>     y = win32api.GetSystemMetrics(SM_CYSCREEN)
>     width = x -50
>     height = y -80
>     print RESIZABLE
>     screen = pygame.display.set_mode((width,height),RESIZABLE,32)
>     pygame.display.set_caption\
>         ("WMF Show - Resize the window to control drawing size")
> 
>     scale = 250
>     resized = 0
> 
>     # Get loopin'
>     for counter in range(10**5):
> 
>         # Have we received an event to close the window?
>         for e in pygame.event.get():
>             if e.type in (QUIT,KEYDOWN):  return
> 
>             if e.type == VIDEORESIZE:
> 
>                scale = 250 * e.size[0] / width
>                screen = pygame.display.set_mode(e.size,RESIZABLE,32)
>                resized = 1
> 
>         # For some reason, (e.g. the wmf is rendered behind the scenes) I need to
>         # re-open file each time as even copying the im1 surface freezes the size.
> 
>         # I found this wmf image in
>         # http://www.worldofmusic.com.au/downloads_view.asp?id=24
>         im1 = Image.open("logo.wmf")
> 
>         if resized:
>            im1.size = im1.size[0] * scale / 100, im1.size[1] * scale / 100
>         else:
>            # Back & forth scaling in a way that uses bigger increments when
>            # the image is bigger.
>            sc = abs(counter%200-(100)) + 10
>            sc = max((sc * sc/10) * scale/200,10)
>            im1.size = im1.size[0] * sc / 500, im1.size[1] * sc / 500
> 
>         buf = im1.tostring("raw","RGB",0,0)
> 
>         # rotating background colours, well, why not?
>         image = pygame.image.fromstring(buf,im1.size,"RGB",0)
>         fcolour = abs(counter % 511 - 255), abs((counter / 2) % 511 - 255), \
>                  abs((counter / 3) % 511 - 255)
>         screen.fill(fcolour)
> 
>         # Centering
>         ctr = screen.get_rect().center
>         rsize = image.get_rect().center
> 
>         offset = ctr[0] - rsize[0], ctr[1] - rsize[1]
>         screen.blit(image,offset)
>         pygame.display.flip()
> 
> #
> if __name__ == '__main__': main()
> 
> # I thank you.
> --
> Regards
> Ben Friman
> t 0870 041 0935
> w www.learntotype.com
> 
>