How do I draw images to the context

Even with the existence of the image and bitmap objects mentioned at the beginning of this chapter, you will still need to use device context methods to draw images or copy from one device context to another, a process called a blit. One common use for this feature is to draw part of an image to the context. Historically, this was used to allow a program to deploy all of its peripheral images in one file, and use a partial blit to draw only the part that corresponded to a particular image or toolbar icon.

There are three device context methods used to draw images to the context, whether from another device context or from a preexisting image.

Probably the most important method, and definitely the most complex one, is Blit():

Blit(xdest, ydest, width, height, source, xsrc, ysrc, logicalFunc=wx.COPY, useMask=False, xsrcMask=-1, ysrcMask=-1)

Copying part of an image

The purpose of Blit() is to copy pixels rapidly from one device context to another. It's typically used when you want to copy part of one image to part of another image or to quickly copy pixel data to the screen. We've already seen that Blit() is used to manage buffered device contexts, for example. It is a very powerful and flexible method, with a number of parameters. Generally, it involves setting a rectangle on the destination context to be copied to, setting a rectangle on the source to copy from, and then a few parameters for the copy itself. The destination for a blit is the wx.DC instance whose Blit() method is being invoked. The xdest and ydest parameters are the location of the top left corner of the rectangle in the destination context where the data copy will begin. The width and height parameters set the size of the rectangle to be copied. The source is the other wx.DC where the pixels are coming from. This can be any other subclass of wx.DC. The xsrc and ysrc parameters denote the position on the source device context where the copying should start—obviously this will not necessarily be the same as xdest and ydest. However, the width and height parameters are shared between the source and destination—the two rectangles must be the same size.

The logicalFunc is the algorithm used to merge the old pixels and the new— the default behavior is to overwrite, but various kinds of XORish behavior can be defined. In table 12.6, we'll show a complete list of logical functions. If the use-Mask parameter is True, the blit is performed with a mask governing which pixels are actually copied. In this case, the selected source area must be a bitmap with an associated mask or alpha channel. If specified, the xsrcMask and ysrcMask parameters govern where on the mask the copy starts. If they aren't specified, then xsrc and ysrc are used. There is also a BlitPointSize() version of the method which replaces all three point pairs with wx.Point instances, and the width and height with a wx.Size.

Drawing a bitmap

Assuming you want to draw a complete image onto your device context, there are a couple of simpler methods you can use. To draw a bitmap, you have Draw-Bitmap(bitmap, x, y, useMask=False). The bitmap parameter is a wx.Bitmap object, which is drawn to the device context at the point (x, y). The useMask parameter is a Boolean. If it is False, the image is drawn normally. If True, and if the bitmap has a mask or alpha channel associated with it, then the mask is used to determine which parts of the bitmap are transparent. If the bitmap is monochromatic, the current text foreground and background colors are used for the bitmap, otherwise, the bitmap's own color scheme is used. Figure 12.3 displays that functionality.

Loading Images

H V^HH

m SSRtf -zj

Figure 12.3 Drawing a face to the screen multiple times

Figure 12.3 Drawing a face to the screen multiple times

Listing 12.3 displays a simple example of using a device context to display a bitmap, as used to create figure 12.3.

Listing 12.3 Creating a device context and drawing a bitmap import wx import random random.seed()

class RandomImagePlacementWindow(wx.Window):

self.photo = image.ConvertToBitmap() <1— Getting the bitmap self.positions = [(10,10)] <— Creating random locations for x in range(50):

x = random.randint(0, 1000) y = random.randint(0, 1000) self.positions.append( (x,y) )

self.Bind(wx.EVT_PAINT, self.OnPaint)

def OnPaint(self, evt): dc = wx.PaintDC(self) brush = wx.Brush("sky blue") dc.SetBackground(brush)

dcClear() Clearing the DC with the background brush for x,y in self.positions: <J Drawing the bitmap dc.DrawBitmap(self.photo, x, y, True)

class TestFrame(wx.Frame):

wx.Frame._init_(self, None, title="Loading Images", size=(640,480)) img = wx.Image("masked-portrait.png") win = RandomImagePlacementWindow(self, img)

app = wx.PySimpleApp() frm = TestFrame() frm.Show() app.MainLoop()

You may also draw a wx.Icon with DrawIcon(icon, x, y), which places the wx.Icon object at the point (x, y) in the device context. Any other image that you want to draw to the device context must first be converted to either a wx.Bitmap or a wx.Icon.

Was this article helpful?

0 0

Post a comment