I have RGBA32 image data in a python buffer object, whose dimensions
are the same as those of my DrawingArea. I want to copy a rectangular
region defined by x,y,w,h of the buffer into the window, at the same
x,y location.
I tried variants of
widget.window.draw_rgb_32_image(
gc, x, y, w, h, gdk.RGB_DITHER_NORMAL,
mybuffer, stride)
where w,h are the rectangular region width and height and stride is
the canvas width * 4.
This places the copied image into the drawing area window at the right
location and size, but takes data from the 0,0 origin of the src data
mybuffer, rather than from the origin x,y which is what I want.
I know I can do this by copying the rectangular region in mybuffer
into a new buffer which is smaller. The code below illustrates the
problem. In the draw function, I have
if 0:
mybuffer = im.tostring()
stride = wwin*4
else:
# this is the desired behavior, but I want to avoid having to
# make a copy of the original buffer into a new buffer
mybuffer = im[x:x+w, y:y+h, :].tostring()
stride = w*4
to illustrate two cases. The first case takes the entire image to
create the buffer, and the second slices out the rectangular region of
interest. In my real application, this slice will require an extra
copy I am trying to avoid, so I am wondering if there is a way in
pygtk to say, "transfer this rectangular region out of a buffer into
the drawable at the same location".
Toggle "if 0" to "if 1" to test the two behaviors.
#!/usr/bin/env python
# this is meant to be used as a template file to practice drawing commands
import pygtk
pygtk.require('2.0')
import gtk
from gtk import gdk
import Numeric as nx
def draw(widget):
wwin, hwin = widget.window.get_size()
N = wwin*hwin*4
im = nx.arange(float(N))/N*255
im = im.astype(nx.UInt8)
im.shape = wwin,hwin,4
gc = widget.window.new_gc()
x,y,w,h = 200,200,150,100
if 0:
mybuffer = im.tostring()
stride = wwin*4
else:
# this is the desired behavior, but I want to avoid having to
# make a copy of the original buffer into a new buffer
mybuffer = im[x:x+w, y:y+h, :].tostring()
stride = w*4
widget.window.draw_rgb_32_image(
gc, x, y, w, h, gdk.RGB_DITHER_NONE,
mybuffer, stride)
def configure_event(widget, event):
print 'config'
draw(widget)
return True
def expose_event(widget, event):
print 'expose'
draw_region(widget)
return True
def realize(widget):
print 'realize'
draw(widget)
return True
win = gtk.Window()
win.show()
vbox = gtk.VBox()
vbox.show()
win.add(vbox)
da = gtk.DrawingArea()
da.set_size_request(640,480)
da.connect('configure_event', configure_event)
da.connect('expose_event', configure_event)
da.connect('realize', realize)
da.show()
vbox.pack_start(da, True, True)
button = gtk.Button('Quit')
button.show()
vbox.pack_start(button, False, False)
button.connect('clicked', gtk.mainquit)
gtk.main()