Reputation: 879
I made a Python program that draws a black rectangle with a white circle inside it when I click on a button. I use Gtk.DrawingArea
and cairo.ImageSurface
. The code is the following.
class App:
def __init__(self, width, height):
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
# Builder
self.builder = Gtk.Builder()
self.builder.add_from_file('ventana.glade')
go = self.builder.get_object
# Widgets
self.window = go('window')
self.drawingarea = go('drawingarea')
self.button = go('button')
signals = {
'gtk_main_quit' : Gtk.main_quit,
'draw' : self.draw
}
self.builder.connect_signals(signals)
self.window.show_all()
def draw(self, widget):
context = self.drawingarea.get_window().cairo_create()
context.set_source_surface(self.surface)
context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
context.rectangle(0, 0, self.surface.get_width(), self.surface.get_height())
context.fill()
context.translate(10, 10)
context.arc(0, 0, 10, 0, 2 * pi)
context.set_source_rgba(1.0, 1.0, 1.0, 1.0)
context.fill()
I get the following window.
It works fine, but I need to get the RGB values of the pixels of that picture, so I tried doing map(ord, self.surface.get_data())
, but I get a list of zeros.
How can I get a list with the RGB of the pixels?
And I have another problem: when I minimize the window or change to another window, the drawing erases. Is it possible to avoid this?
Upvotes: 3
Views: 1768
Reputation: 6527
You don't need to use a map, the MemoryView object has a tobytes()
function. This will convert to a ByteArray, which can easily be converted to a list of ints:
# Set up pycairo
my_surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 10, 10)
ctx = cairo.Context(my_surface)
ctx.set_source_rgb(0.8, 0.8, 0.8)
ctx.paint()
# Draw a small red rectangle
ctx.rectangle(1, 1, 5, 5)
ctx.set_source_rgb(1, 0, 0)
ctx.fill()
# Convert pixels to MemoryView object, then bytestring or list of ints
pixel_data_mv = my_surface.get_data() # MemoryView object
pixels_as_bytes = pixel_data_mv.tobytes() # ByteArray
pixels_as_list = list(pixels_as_bytes)
# Iterate through memoryview object
print(f"pixel_data_mv[{len(pixel_data_mv)}]:")
for one_data_bit in pixel_data_mv:
print(f"{str(one_data_bit)}", end=', ')
print("")
# Print as ByteArray and list of ints
print(f"pixels_as_bytes[{len(pixels_as_bytes)}]:\n{pixels_as_bytes}")
print(f"pixels_as_list[{len(pixels_as_list)}]:\n{pixels_as_list}")
This will show both the ByteArray and list of ints:
pixels_as_bytes[400]:
b'\xcc\xcc\xcc\xff\xcc\xcc\xcc\xff\xcc\xcc\xcc\xff\xcc ...
pixels_as_list[400]:
[204, 204, 204, 255, 204, 204, 204, 255, 204, 204, 204, 255
Note that the pixels are "exploded" into four bytes, R/G/B/A.
Upvotes: 1
Reputation: 1195
i don't know about getting your color but about the drawing, connect your window with 'configure-event' (event being state of window changed) and then call drawingarea.queue_draw ()
Upvotes: 0