def pick_color(self, x, y, size=3): """Picks the rendered colour at a particular point. :param int x: X coord of pixel to pick (widget/device coords) :param int y: Y coord of pixel to pick (widget/device coords) :param int size: Size of the sampling square. :returns: The colour sampled. :rtype: lib.color.UIColor This method operates by rendering part of the document using the current settings, then averaging the colour values of the pixels within the sampling square. """ # TODO: the ability to turn *off* this kind of "sample merged". # Ref: https://github.com/mypaint/mypaint/issues/333 # Make a square surface for the sample. size = max(1, int(size)) surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size) cr = cairo.Context(surf) cr.set_source_rgb(0, 0, 0) cr.paint() # Ensure the rendering of the area around (x, y) writes into the # sample square. r = int(size/2) cr.translate(-int(x)+r, -int(y)+r) # Paint checkerboard if we won't be rendering an opaque background model = self.doc render_is_opaque = model and model.layer_stack.get_render_is_opaque() if (not render_is_opaque) and self._draw_real_alpha_checks: cr.set_source(self._real_alpha_check_pattern) cr.paint() if not model: return lib.color.RGBColor(0, 1, 1) # Render just what we need. transformation, surface, sparse, mipmap_level, clip_rect = \ self._render_prepare(cr) self._render_execute( cr, transformation, surface, sparse, mipmap_level, clip_rect, filter = None, ) surf.flush() # Extract a pixbuf, then an average color. #surf.write_to_png("/tmp/grab.png") pixbuf = gdk.pixbuf_get_from_surface(surf, 0, 0, size, size) color = lib.color.UIColor.new_from_pixbuf_average(pixbuf) return color
def image_surface_to_pixbuf(surf): if gtk2compat.USE_GTK3: w = surf.get_width() h = surf.get_height() return gdk.pixbuf_get_from_surface(surf, 0, 0, w, h) # GTK2. # Ugly PNG-based fudge to work around cairo.ImageSurface.get_data() # returning packed BGRA or ARGB pixels depending on endianness. png_dp = StringIO() surf.write_to_png(png_dp) pixbuf_loader = gdk.PixbufLoader() pixbuf_loader.write(png_dp.getvalue()) pixbuf_loader.close() return pixbuf_loader.get_pixbuf()