John Hunter wrote:

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()
Put your image data in a pixbuf then you can draw portions of it to a drawable using render_to_drawable(), etc.

John
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to