We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Drawing Anti-Aliased Graphics Under Tkinter/Windows

Fredrik Lundh | October 2005 | Originally posted to online.effbot.org

I just posted a new aggdraw alpha, which borrows some Windows-specific display code from PIL. You can now create a DIB-compatible drawing surface, draw to it as usual, and blit it directly to screen, without having to convert it to a PIL image memory, a PhotoImage object, or whatever image object your GUI toolkit is using.

Here’s an outline:

import aggdraw

dib = aggdraw.Dib("RGB", (800, 600))

... draw into the dib, as usual ...

dib.expose(handle) # in 1.2a1
dib.expose(hwnd=handle) # in 1.2a2

(Note: the 1.2a1 release takes a single positional argument, but the upcoming 1.2a2 requires a keyword argument.)

The handle in this example is a Windows HWND for the window you want to draw into; under Tkinter, you can use the winfo_id() method to get this. The Dib object implements all the usual Draw methods; the only difference between a Draw instance and a Dib instance is that the latter uses a shared memory buffer, and knows how to copy itself to a window.

Here’s a somewhat larger example, using Tkinter:

import aggdraw
import random
import Tkinter

root = Tkinter.Tk()

size = 400, 300

# create a Dib surface
draw = aggdraw.Dib("RGB", size)

# draw something
x0 = random.randint(0, size[0])
y0 = random.randint(0, size[1])
for i in range(500):
    x1 = random.randint(0, size[0])
    y1 = random.randint(0, size[1])
    draw.line((x0, y0, x1, y1), aggdraw.Pen("black"))
    x0 = x1; y0 = y1

# display the image
frame = Tkinter.Frame(root, width=size[0], height=size[1], bg="")
frame.bind("<Expose>", lambda e: draw.expose(hwnd=e.widget.winfo_id()))
frame.pack()

frame.mainloop()

In this example, the <Expose> binding makes sure that the widget is properly redrawn, when needed. The bg=”“ setting tells Tkinter not to draw any background into this window. If you’re using the WCK instead, put the expose code in the repair hook.

To display aggdraw images under Tkinter on other platforms, you can use PIL’s ImageTk.PhotoImage object, or the WCK toolkit. See An AggDraw-based WCK View for an example on how to use the latter.