# # The Python Imaging Library. # $Id$ # # a Windows DIB display interface # # History: # 1996-05-20 fl Created # 1996-09-20 fl Fixed subregion exposure # 1997-09-21 fl Added draw primitive (for tzPrint) # 2003-05-21 fl Added experimental Window/ImageWindow classes # 2003-09-05 fl Added fromstring/tostring methods # # Copyright (c) Secret Labs AB 1997-2003. # Copyright (c) Fredrik Lundh 1996-2003. # # See the README file for information on usage and redistribution. # import Image ## # The ImageWin module contains support to create and display # images under Windows 95/98, NT, 2000 and later. class HDC: def __init__(self, dc): self.dc = dc def __int__(self): return self.dc class HWND: def __init__(self, wnd): self.wnd = wnd def __int__(self): return self.wnd ## # Create a Windows bitmap with the given mode and size. The mode can # be one of "1", "L", "P", or "RGB". # # If the display requires a palette, this constructor creates a # suitable palette and associates it with the image. For an "L" image, # 128 greylevels are allocated. For an "RGB" image, a 6x6x6 colour # cube is used, together with 20 greylevels. # # To make sure that palettes work properly under Windows, you must # call the palette method upon certain events from Windows. class Dib: ## # Create Windows bitmap. # # @param image Either a PIL image, or a mode string. If a # mode string is used, a size must also be given. The # mode can be one of "1", "L", "P", or "RGB". # @param size If the first argument is a mode string, this # defines the size of the image. def __init__(self, image, size=None): if hasattr(image, "mode") and hasattr(image, "size"): mode = image.mode size = image.size else: mode = image image = None if mode not in ["1", "L", "P", "RGB"]: mode = Image.getmodebase(mode) self.image = Image.core.display(mode, size) self.mode = mode self.size = size if image: self.paste(image) ## # Copy the bitmap contents to a device context. # # @param handle Device context (HDC), cast to a Python integer, # or a HDC or HWND instance. In PythonWin, you can use the # GetHandleAttrib method of the CDC class to get # a suitable handle. def expose(self, handle): if isinstance(handle, HWND): dc = self.image.getdc(handle) try: result = self.image.expose(dc) finally: self.image.releasedc(handle, dc) else: result = self.image.expose(handle) return result def draw(self, handle, dst, src=None): if not src: src = (0,0) + self.size if isinstance(handle, HWND): dc = self.image.getdc(handle) try: result = self.image.draw(dc, dst, src) finally: self.image.releasedc(handle, dc) else: result = self.image.draw(handle, dst, src) return result ## # Installs the palette associated with the image in the # given device context. #
# This method should be called upon QUERYNEWPALETTE # and PALETTECHANGED events from Windows. If this # method returns a non-zero value, one or more display # palette entries were changed, and the image should be # redrawn. # # @param handle Device context (HDC), cast to a Python integer, # or an HDC or HWND instance. # @return A true value if one or more entries were changed # (this indicates that the image should be redrawn). def query_palette(self, handle): if isinstance(handle, HWND): handle = self.image.getdc(handle) try: result = self.image.query_palette(handle) finally: self.image.releasedc(handle, handle) else: result = self.image.query_palette(handle) return result ## # Paste a PIL image into the bitmap image. # # @param im A PIL image. The size must match the target region. # If the mode does not match, the image is converted to the # mode of the bitmap image. # @param box A 4-tuple defining the left, upper, right, and # lower pixel coordinate. If None is given instead of a # tuple, all of the image is assumed. def paste(self, im, box=None): im.load() if self.mode != im.mode: im = im.convert(self.mode) if box: self.image.paste(im.im, box) else: self.image.paste(im.im) ## # Load display memory contents from string buffer. # # @param buffer A string buffer containing display data (usually # data returned from tostring) def fromstring(self, buffer): return self.image.fromstring(buffer) ## # Copy display memory contents to string buffer. # # @return A string buffer containing display data. def tostring(self): return self.image.tostring() ## # Create a Window with the given title size. class Window: def __init__(self, title="PIL", width=None, height=None): self.hwnd = Image.core.createwindow( title, self.__dispatcher, width or 0, height or 0 ) def __dispatcher(self, action, *args): return apply(getattr(self, "ui_handle_" + action), args) def ui_handle_clear(self, dc, x0, y0, x1, y1): pass def ui_handle_damage(self, x0, y0, x1, y1): pass def ui_handle_destroy(self): pass def ui_handle_repair(self, dc, x0, y0, x1, y1): pass def ui_handle_resize(self, width, height): pass def mainloop(self): Image.core.eventloop() ## # Create an image window which displays the given image. class ImageWindow(Window): def __init__(self, image, title="PIL"): if not isinstance(image, Dib): image = Dib(image) self.image = image width, height = image.size Window.__init__(self, title, width=width, height=height) def ui_handle_repair(self, dc, x0, y0, x1, y1): self.image.draw(dc, (x0, y0, x1, y1))