def getMatrix(x: int, y: int, surf: cairo.ImageSurface): sx = surf.get_width() / 8.5 / 25.4 sy = surf.get_height() / 11 / 25.4 x0 = (origin[0] + deltaX * x) * sx y0 = (origin[1] + deltaY * y) * sy return cairo.Matrix(x0=x0, y0=y0, xx=sx, yy=sy)
def _cairo_surface_write_to_bmp(img: cairo.ImageSurface) -> bytes: data = bytes(img.get_data()) return ( b"BM" + struct.pack( "<ihhiiiihhiiiiii", 54 + len(data), # size of BMP file 0, # unused 0, # unused 54, # pixel array offset 40, # DIB header img.get_width(), # width img.get_height(), # height 1, # planes 32, # BPP 0, # no compression len(data), # size of the raw bitmap data 2835, # 72DPI H 2835, # 72DPI V 0, # palette 0, # all colors are important ) + data )
def convert_svg2png(infile, outfile, w, h): """ Converts svg files to png using Cairosvg or Inkscape @file_path : String; the svg file absolute path @dest_path : String; the png file absolute path """ if use_inkscape: p = Popen(["inkscape", "-z", "-f", infile, "-e", outfile, "-w", str(w), "-h", str(h)], stdout=PIPE, stderr=PIPE) output, err = p.communicate() else: handle = Rsvg.Handle() svg = handle.new_from_file(infile) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, w, h) ctx = Context(img) ctx.scale(w / dim.width, h / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(outfile, 'wb') as fout: fout.write(png_io.getvalue()) svg.close() png_io.close() img.finish()
def make_image_surface(bitmap, copy=True): if (type(bitmap) == FT_Bitmap): # bare FT_Bitmap content = bitmap else: # wrapped Bitmap instance content = bitmap._FT_Bitmap "creates a Cairo ImageSurface containing (a copy of) the Bitmap pixels." if content.pixel_mode == FT_PIXEL_MODE_MONO: cairo_format = FORMAT_A1 elif content.pixel_mode == FT_PIXEL_MODE_GRAY: cairo_format = FORMAT_A8 else: raise NotImplementedError("unsupported bitmap format %d" % content.pixel_mode) src_pitch = content.pitch dst_pitch = ImageSurface.format_stride_for_width(cairo_format, content.width) if not copy and dst_pitch == src_pitch and content.buffer != None: pixels = content.buffer else: pixels = to_array(content, content.pixel_mode, dst_pitch) result = ImageSurface.create_for_data(pixels, cairo_format, content.width, content.rows, dst_pitch) return result
def create_surface(self): bw, bh = self.size old_backing = self._backing #should we honour self.depth here? self._backing = None if bw==0 or bh==0: #this can happen during cleanup return None backing = ImageSurface(FORMAT_ARGB32, bw, bh) self._backing = backing cr = Context(backing) if self._alpha_enabled: cr.set_operator(OPERATOR_CLEAR) cr.set_source_rgba(1, 1, 1, 0) else: cr.set_operator(OPERATOR_SOURCE) cr.set_source_rgba(1, 1, 1, 1) cr.rectangle(0, 0, bw, bh) cr.fill() if COPY_OLD_BACKING and old_backing is not None: oldw, oldh = old_backing.get_width(), old_backing.get_height() sx, sy, dx, dy, w, h = self.gravity_copy_coords(oldw, oldh, bw, bh) cr.translate(dx-sx, dy-sy) cr.rectangle(sx, sy, w, h) cr.clip() cr.set_operator(OPERATOR_SOURCE) cr.set_source_surface(old_backing, 0, 0) cr.paint() backing.flush() return cr
def renegerate_overlay_buffer(self): image = ImageSurface(cairo.FORMAT_ARGB32, self.video_width, self.video_height) context = Context(image) text = "Foo bar 123" font = pango.FontDescription('sans normal 22') text_offset = [6, 6] textOverflowed = False if text: pcContext = pangocairo.CairoContext(context) pangoLayout = pcContext.create_layout() font = pango.FontDescription('sans normal 22') pangoLayout.set_font_description(font) context.move_to(text_offset[0]+2, text_offset[1]+2) pangoLayout.set_markup('<span foreground="black" >%s</span>' % text) pcContext.show_layout(pangoLayout) context.move_to(text_offset[0], text_offset[1]) pangoLayout.set_markup('<span foreground="white" >%s</span>' % text) pcContext.show_layout(pangoLayout) textWidth, textHeight = pangoLayout.get_pixel_size() self.overlay_buffer = image.get_data() print "overlay_buffer size: %d" % len(self.overlay_buffer)
def convert_to_png(input_file, output_file, width=None, height=None): """Convert svg to png.""" if width and height: handle = Rsvg.Handle() svg = handle.new_from_file(input_file) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, width, height) ctx = Context(img) ctx.scale(width / dim.width, height / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(output_file, 'wb') as fout: fout.write(png_io.getvalue()) fout.close() svg.close() png_io.close() img.finish() else: with open(input_file, "r") as content_file: svg = content_file.read() content_file.close() fout = open(output_file, "wb") svg2png(bytestring=bytes(svg, "UTF-8"), write_to=fout) fout.close()
def writeAsPNG(root, filename): from cairo import ImageSurface, Context, FORMAT_ARGB32 from rsvg import Handle img = ImageSurface(FORMAT_ARGB32, float(root.attrib["width"]),float(root.attrib["height"])) #test ctx = Context(img) handle = Handle(None, tostring(root)) handle.render_cairo(ctx) img.write_to_png(filename) return filename
class Canvas: def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height def fit(self, left, top, right, bottom): xoff = left yoff = top xscale = self.width / float(right - left) yscale = self.height / float(bottom - top) if abs(xscale) > abs(yscale): xscale *= abs(yscale) / abs(xscale) elif abs(xscale) < abs(yscale): yscale *= abs(xscale) / abs(yscale) self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale) def dot(self, x, y, size=4, fill=(.5, .5, .5)): x, y = self.xform(x, y) self.ctx.arc(x, y, size/2., 0, 2*pi) self.ctx.set_source_rgb(*fill) self.ctx.fill() def line(self, points, stroke=(.5, .5, .5), width=1): self.ctx.move_to(*self.xform(*points[0])) for (x, y) in points[1:]: self.ctx.line_to(*self.xform(x, y)) self.ctx.set_source_rgb(*stroke) self.ctx.set_line_cap(LINE_CAP_ROUND) self.ctx.set_line_width(width) self.ctx.stroke() def save(self, filename): self.img.write_to_png(filename)
class Canvas: def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height def fit(self, left, top, right, bottom): xoff = left yoff = top xscale = self.width / float(right - left) yscale = self.height / float(bottom - top) if abs(xscale) > abs(yscale): xscale *= abs(yscale) / abs(xscale) elif abs(xscale) < abs(yscale): yscale *= abs(xscale) / abs(yscale) self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale) def dot(self, x, y, size=4, fill=(.5, .5, .5)): x, y = self.xform(x, y) self.ctx.arc(x, y, size / 2., 0, 2 * pi) self.ctx.set_source_rgb(*fill) self.ctx.fill() def line(self, points, stroke=(.5, .5, .5), width=1): self.ctx.move_to(*self.xform(*points[0])) for (x, y) in points[1:]: self.ctx.line_to(*self.xform(x, y)) self.ctx.set_source_rgb(*stroke) self.ctx.set_line_cap(LINE_CAP_ROUND) self.ctx.set_line_width(width) self.ctx.stroke() def save(self, filename): self.img.write_to_png(filename)
def _surface_to_array(surface: cairo.ImageSurface) -> np.ndarray: """convert surface to array""" # NOTE! The format of the array is PREMULTIPLIED ALPHA, not RGBA! res = np.ndarray( (surface.get_height(), surface.get_width(), 4), # do height and width work here??? dtype=np.uint8, buffer=surface.get_data()) res = res[:, :, [2, 1, 0, 3]] # swap RGB order like OpenCV return res
def _tonumpy(surface: cairo.ImageSurface): np_image = np.ndarray( shape=(surface.get_height(), surface.get_width(), 4), dtype=np.uint8, buffer=surface.get_data(), strides=(surface.get_width() * 4, 4, 1) ) np_image = np_image[:, :, :-1] np_image = np_image[:, :, ::-1] np_image = np_image.copy() return np_image
def __init__(self, width: int, height: Optional[int] = None, *, normalise: bool = True): if height is None: height = width self._width = width self._height = height self._surface = ImageSurface(FORMAT_ARGB32, width, height) self._context = Context(self._surface) self._normalise = normalise if self._normalise: self.scale(self._width, self._height)
def draw_frame(self, target: cairo.ImageSurface): ctx = cairo.Context(target) ctx.set_source_rgba(0.92, 0.72, 1, 0.3) w, h = target.get_width(), target.get_height() projection = np.dot(numgl.perspective(90, w / h, 0.1, 5), self.camera()) clip = pygl.transform(projection, self.positions) screen = pygl.get_screen(clip, (w, h)) for x, y, _ in screen: ctx.move_to(x, y) ctx.arc(x, y, 1, 0, TAU) ctx.fill()
def get_cached_image(self, width, height, zoom, parameters=None, clear=False): """Get ImageSurface object, if possible, cached The method checks whether the image was already rendered. This is done by comparing the passed size and parameters with those of the last image. If they are equal, the cached image is returned. Otherwise, a new ImageSurface with the specified dimensions is created and returned. :param width: The width of the image :param height: The height of the image :param zoom: The current scale/zoom factor :param parameters: The parameters used for the image :param clear: If True, the cache is emptied, thus the image won't be retrieved from cache :returns: The flag is True when the image is retrieved from the cache, otherwise False; The cached image surface or a blank one with the desired size; The zoom parameter when the image was stored :rtype: bool, ImageSurface, float """ if not parameters: parameters = {} if self.__compare_parameters(width, height, zoom, parameters) and not clear: return True, self.__image, self.__zoom # Restrict image surface size to prevent excessive use of memory self.__limiting_multiplicator = 1 area = width * zoom * self.__zoom_multiplicator * height * zoom * self.__zoom_multiplicator if area > MAX_ALLOWED_AREA: self.__limiting_multiplicator = sqrt(MAX_ALLOWED_AREA / area) image = ImageSurface(self.__format, int(ceil(width * zoom * self.multiplicator)), int(ceil(height * zoom * self.multiplicator))) self.__set_cached_image(image, width, height, zoom, parameters) return False, self.__image, zoom
def draw_pieces(self): if not self.num_pieces: # Nothing to draw. return if (self.resized() or self.pieces != self.prev_pieces or self.pieces_overlay is None): # Need to recreate the cache drawing self.pieces_overlay = ImageSurface(FORMAT_ARGB32, self.width, self.height) ctx = Context(self.pieces_overlay) if self.pieces: pieces = self.pieces elif self.num_pieces: # Completed torrents do not send any pieces so create list using 'completed' state. pieces = [COLOR_STATES.index('completed')] * self.num_pieces start_pos = 0 piece_width = self.width / len(pieces) pieces_colors = [[ color / 65535 for color in self.gtkui_config['pieces_color_%s' % state] ] for state in COLOR_STATES] for state in pieces: ctx.set_source_rgb(*pieces_colors[state]) ctx.rectangle(start_pos, 0, piece_width, self.height) ctx.fill() start_pos += piece_width self.cr.set_source_surface(self.pieces_overlay) self.cr.paint()
def write_text(self): if not self.text: # Nothing useful to draw, return now! return if self.resized( ) or self.text != self.prev_text or self.text_overlay is None: # Need to recreate the cache drawing self.text_overlay = ImageSurface(FORMAT_ARGB32, self.width, self.height) ctx = Context(self.text_overlay) pg = CairoContext(ctx) pl = pg.create_layout() pl.set_font_description(self.text_font) pl.set_width(-1) # No text wrapping pl.set_text(self.text) plsize = pl.get_size() text_width = plsize[0] // SCALE text_height = plsize[1] // SCALE area_width_without_text = self.width - text_width area_height_without_text = self.height - text_height ctx.move_to(area_width_without_text // 2, area_height_without_text // 2) ctx.set_source_rgb(1, 1, 1) pg.update_layout(pl) pg.show_layout(pl) self.cr.set_source_surface(self.text_overlay) self.cr.paint()
def nasty_rgb_via_png_paint(self, cairo_format, has_alpha : bool, img_data, x : int, y : int, width : int, height : int, rowstride : int, rgb_format): log.warn("nasty_rgb_via_png_paint%s", (cairo_format, has_alpha, len(img_data), x, y, width, height, rowstride, rgb_format)) #PIL fallback from PIL import Image if has_alpha: oformat = "RGBA" else: oformat = "RGB" #use frombytes rather than frombuffer to be compatible with python3 new-style buffers #this is slower, but since this codepath is already dreadfully slow, we don't care bdata = memoryview_to_bytes(img_data) src_format = rgb_format.replace("X", "A") try: img = Image.frombytes(oformat, (width,height), bdata, "raw", src_format, rowstride, 1) except ValueError as e: log("PIL Image frombytes:", exc_info=True) raise Exception("failed to parse raw %s data as %s to %s: %s" % ( rgb_format, src_format, oformat, e)) from None #This is insane, the code below should work, but it doesn't: # img_data = bytearray(img.tostring('raw', oformat, 0, 1)) # pixbuf = new_from_data(img_data, COLORSPACE_RGB, True, 8, width, height, rowstride) # success = self.cairo_paint_pixbuf(pixbuf, x, y) #So we still rountrip via PNG: from io import BytesIO png = BytesIO() img.save(png, format="PNG") reader = BytesIO(png.getvalue()) png.close() img = ImageSurface.create_from_png(reader) self.cairo_paint_surface(img, x, y, width, height, {}) return True
def motionblur(target: cairo.ImageSurface, t: float, draw: Callable, look_ahead: float, n: int): w = target.get_width() h = target.get_width() frames = [] for tt in np.linspace(0, look_ahead, n): frame = np.zeros((w * h * 4,), dtype=np.uint8) surface = cairo.ImageSurface.create_for_data(memoryview(frame), cairo.Format.RGB24, w, h) draw(surface, t + tt) #frames.append(degamma(frame)) frames.append(frame) avg = np.average(np.stack(frames), axis=0).astype(np.uint8) #avg = gamma(np.average(np.stack(frames), axis=0)).astype(np.uint8) data = target.get_data() for i in range(len(data)): data[i] = avg[i]
def __init__(self, w=10, h=10, path=''): self._w, self._h = w, h surface = ImageSurface.create_from_png(path) self._imgpat = SurfacePattern(surface) self._imgpat.set_filter(FILTER_BEST) scaler = Matrix() scaler.scale(surface.get_width() / w, surface.get_height() / h) self._imgpat.set_matrix(scaler)
def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height
def create_cairo_font_face_for_file(filename, faceindex=0, loadoptions=0): """ http://cairographics.org/freetypepython """ CAIRO_STATUS_SUCCESS = 0 FT_Err_Ok = 0 # find shared objects _freetype_so = ctypes.CDLL('libfreetype.so.6') _cairo_so = ctypes.CDLL('libcairo.so.2') _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p _cairo_so.cairo_ft_font_face_create_for_ft_face.argtypes = [ ctypes.c_void_p, ctypes.c_int ] _cairo_so.cairo_set_font_face.argtypes = [ctypes.c_void_p, ctypes.c_void_p] _cairo_so.cairo_font_face_status.argtypes = [ctypes.c_void_p] _cairo_so.cairo_status.argtypes = [ctypes.c_void_p] # initialize freetype _ft_lib = ctypes.c_void_p() if FT_Err_Ok != _freetype_so.FT_Init_FreeType(ctypes.byref(_ft_lib)): raise "Error initialising FreeType library." class PycairoContext(ctypes.Structure): _fields_ = [("PyObject_HEAD", ctypes.c_byte * object.__basicsize__), ("ctx", ctypes.c_void_p), ("base", ctypes.c_void_p)] _surface = ImageSurface(FORMAT_A8, 0, 0) # create freetype face ft_face = ctypes.c_void_p() cairo_ctx = Context(_surface) cairo_t = PycairoContext.from_address(id(cairo_ctx)).ctx _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p if FT_Err_Ok != _freetype_so.FT_New_Face(_ft_lib, filename, faceindex, ctypes.byref(ft_face)): raise Exception("Error creating FreeType font face for " + filename) # create cairo font face for freetype face cr_face = _cairo_so.cairo_ft_font_face_create_for_ft_face( ft_face, loadoptions) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_font_face_status(cr_face): raise Exception("Error creating cairo font face for " + filename) _cairo_so.cairo_set_font_face(cairo_t, cr_face) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_status(cairo_t): raise Exception("Error creating cairo font face for " + filename) face = cairo_ctx.get_font_face() return face
def __missing__(self, zoom): zoomfac = (1 + 2 * self._r) * zoom self[zoom] = SVGC = ImageSurface(FORMAT_ARGB32, ceil(zoomfac * self._h), ceil(zoomfac * self._k)) sccr = Context(SVGC) sccr.scale(zoom, zoom) sccr.translate(self._uh, self._uk) self._paint_function(sccr) return SVGC
def draw_triangle(target: cairo.ImageSurface, triangle, attributes, texture: Texture): # drop z coordinate p0, p1, p2 = [p[:2] for p in triangle] # compute area area = edge(p0, p1, p2) if area == 0: return width, height = resolution(target) xmin = int(max(min(p0[0], p1[0], p2[0]), 0)) xmax = int(min(max(p0[0], p1[0], p2[0]), width)) ymin = int(max(min(p0[1], p1[1], p2[1]), 0)) ymax = int(min(max(p0[1], p1[1], p2[1]), height)) x, y = np.meshgrid(range(xmin, xmax), range(ymin, ymax), indexing='xy') p = np.vstack([x.ravel(), y.ravel()]).T # Barycentric coordinates are calculated as the areas of the three sub-triangles divided # by the area of the whole triangle. barycentric = np.vstack( [edge(p1, p2, p), edge(p2, p0, p), edge(p0, p1, p)]).T / area # Find all indices of rows where all columns are positive is_inside = np.all(barycentric >= 0, axis=-1) # Compute indices of all points inside triangle stride = np.array([4, target.get_stride()]) indices = np.dot(p[is_inside], stride) # Interpolate vertex attributes attrs = np.dot(barycentric[is_inside], attributes) # Fill pixels data = target.get_data() for index, (u, v) in zip(indices, attrs): r, g, b = texture(u, v) data[index + 0] = r data[index + 1] = g data[index + 2] = b
def _make_image_surface(bitmap, copy=True): """Convert FreeType bitmap to Cairo ImageSurface. Special thanks to Hintak and his example code: https://github.com/rougier/freetype-py/blob/master/examples/bitmap_to_surface.py TODO (M Foley) understand this better and see if a more elegant solution exists.""" content = bitmap._FT_Bitmap cairo_format = FORMAT_A8 src_pitch = content.pitch dst_pitch = ImageSurface.format_stride_for_width(cairo_format, content.width) pixels = _to_array(content, content.pixel_mode, dst_pitch) result = ImageSurface.create_for_data(pixels, cairo_format, content.width, content.rows, dst_pitch) return result
def draw(self, target: cairo.ImageSurface): saved = self.positions, self.t n = 4 lookahead = 0.2 dt = lookahead / n targets = [] for _ in range(n): image = cairo.ImageSurface(cairo.Format.RGB24, target.get_width(), target.get_height()) self.draw_frame(image) targets.append(image) self.step(dt) data = target.get_data() for i in range(len(data)): data[i] = int(sum(img.get_data()[i] for img in targets) / n) self.positions, self.t = saved
def convert_to_png(input_file, output_file, width=None, height=None): """Convert svg to png.""" if width and height: handle = Rsvg.Handle() svg = handle.new_from_file(input_file) dim = svg.get_dimensions() img = ImageSurface( FORMAT_ARGB32, width, height) ctx = Context(img) ctx.scale(width / dim.width, height / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(output_file, 'wb') as fout: fout.write(png_io.getvalue()) fout.close() svg.close() png_io.close() img.finish() else: with open(input_file, "r") as content_file: svg = content_file.read() content_file.close() fout = open(output_file, "wb") svg2png(bytestring=bytes(svg, "UTF-8"), write_to=fout) fout.close()
def convert_svg2png(infile, outfile, w, h): """ Converts svg files to png using Cairosvg or Inkscape @file_path : String; the svg file absolute path @dest_path : String; the png file absolute path """ if use_inkscape: cmd = Popen(["inkscape", "-z", "-f", infile, "-e", outfile, "-w", str(w), "-h", str(h)], stdout=PIPE, stderr=PIPE) cmd.communicate() else: handle = Rsvg.Handle() svg = handle.new_from_file(infile) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, w, h) ctx = Context(img) ctx.scale(w / dim.width, h / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(outfile, 'wb') as fout: fout.write(png_io.getvalue()) svg.close() png_io.close() img.finish()
def __init__ (self, imagePaths): gtk.DrawingArea.__init__(self) self.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK) self.connect("expose-event", self.draw) self.connect("button_press_event", self.buttonPress) self.surfaces = [ImageSurface.create_from_png(path) for path in imagePaths] self.current = 0 width, height = self.surfaces[0].get_width(), self.surfaces[0].get_height() self.size = gtk.gdk.Rectangle(0, 0, width, height) self.set_size_request(width, height)
def _scale_down(self, handle, ratio): xsize, ysize = self.size if ratio >= 1.0: # Convert surface = ImageSurface(FORMAT_ARGB32, xsize, ysize) ctx = Context(surface) else: # Scale xsize, ysize = int(xsize * ratio), int(ysize * ratio) surface = ImageSurface(FORMAT_ARGB32, xsize, ysize) ctx = Context(surface) ctx.scale(ratio, ratio) # Render handle.render_cairo(ctx) # Transform to a PIL image for further manipulation size = (xsize, ysize) im = frombuffer('RGBA', size, surface.get_data(), 'raw', 'BGRA', 0, 1) surface.finish() return im, xsize, ysize
def __init__ (self, imagePaths): GObject.GObject.__init__(self) self.set_events(Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK) self.connect("draw", self.draw) self.connect("button_press_event", self.buttonPress) self.surfaces = [ImageSurface.create_from_png(path) for path in imagePaths] self.current = 0 width, height = self.surfaces[0].get_width(), self.surfaces[0].get_height() self.size = (0, 0, width, height) self.set_size_request(width, height)
def load_image_at_size(name, width, height): """Loads an image file at the specified size. Does NOT handle exceptions!""" from gi.repository import GdkPixbuf, Gdk from cairo import ImageSurface, FORMAT_ARGB32, Context pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(name, width, height) surface = ImageSurface(FORMAT_ARGB32, width, height) ctx = Context(surface) Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0) ctx.paint() return surface
def make_image_surface(bitmap, copy=True): if (type(bitmap) == FT_Bitmap): # bare FT_Bitmap content = bitmap else: # wrapped Bitmap instance content = bitmap._FT_Bitmap "creates a Cairo ImageSurface containing (a copy of) the Bitmap pixels." if (False and (byteorder == 'little') and (content.pixel_mode == FT_PIXEL_MODE_MONO)): try: libtiff = CDLL("not") except: library = get_handle() dest = c_void_p() error = FT_Bitmap_Init(dest) if error: raise FT_Exception(error) error = FT_Bitmap_Convert(library, byref(content), dest, 1) if error: raise FT_Exception(error) content = dest if content.pixel_mode == FT_PIXEL_MODE_MONO: cairo_format = FORMAT_A1 elif content.pixel_mode == FT_PIXEL_MODE_GRAY: cairo_format = FORMAT_A8 else: raise NotImplementedError("unsupported bitmap format %d" % content.pixel_mode) src_pitch = content.pitch dst_pitch = ImageSurface.format_stride_for_width(cairo_format, content.width) if not copy and dst_pitch == src_pitch and content.buffer != None: pixels = content.buffer else: pixels = to_array(content, content.pixel_mode, dst_pitch) result = ImageSurface.create_for_data(pixels, cairo_format, content.width, content.rows, dst_pitch) return result
def plugmap(w, s, e, n): west = open_df.long.min() south = open_df.lat.min() east = open_df.long.max() north = open_df.lat.max() zoom = 5 # tiles = list(mercantile.tiles(west, south, east, north, zoom)) print(tiles) tile_size = (256, 256) # создаем пустое изображение в которое как мозайку будем вставлять тайлы # для начала просто попробуем отобразить все четыре тайла в строчку map_image = ImageSurface(FORMAT_ARGB32, tile_size[0] * len(tiles), tile_size[1]) # создаем контекст для рисования ctx = Context(map_image) for idx, t in enumerate(tiles): server = random.choice(['a', 'b', 'c' ]) # у OSM три сервера, распределяем нагрузку url = 'http://{server}.tile.openstreetmap.org/{zoom}/{x}/{y}.png'.format( server=server, zoom=t.z, x=t.x, y=t.y) # запрашиваем изображение response = urllib.request.urlopen(url) # создаем cairo изображние img = ImageSurface.create_from_png(io.BytesIO(response.read())) # рисуем изображение, с правильным сдвигом по оси x ctx.set_source_surface(img, idx * tile_size[0], 0) ctx.paint() # сохраняем собраное изображение в файл with open("map.png", "wb") as f: map_image.write_to_png(f)
def get_mmap_image(mmap): """ Render a Map to an ImageSurface. """ handle, filename = mkstemp(suffix=".png") try: close(handle) mmap.draw(fatbits_ok=True).save(filename) img = ImageSurface.create_from_png(filename) finally: unlink(filename) return img
def get_mmap_image(mmap): """ Render a Map to an ImageSurface. """ handle, filename = mkstemp(suffix='.png') try: close(handle) mmap.draw(fatbits_ok=True).save(filename) img = ImageSurface.create_from_png(filename) finally: unlink(filename) return img
def draw_progress_overlay(self): if not self.text: # Nothing useful to draw, return now! return if (self.resized() or self.fraction != self.prev_fraction or self.progress_overlay is None): # Need to recreate the cache drawing self.progress_overlay = ImageSurface(FORMAT_ARGB32, self.width, self.height) ctx = Context(self.progress_overlay) ctx.set_source_rgba(0.1, 0.1, 0.1, 0.3) # Transparent ctx.rectangle(0, 0, self.width * self.fraction, self.height) ctx.fill() self.cr.set_source_surface(self.progress_overlay) self.cr.paint()
def __init__(self, image_paths): GObject.GObject.__init__(self) self.set_events(Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK) self.connect("draw", self.draw) self.connect("button_press_event", self.buttonPress) self.surfaces = [ImageSurface.create_from_png(path) for path in image_paths] self.current = 0 width, height = self.surfaces[0].get_width(), self.surfaces[ 0].get_height() self.size = (0, 0, width, height) self.set_size_request(width, height)
def __init__(self): Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL) self.set_size_request(W, H) self.connect("delete_event", Gtk.main_quit) self.set_decorated(True) self.set_app_paintable(True) self.drawing_area = Gtk.DrawingArea() self.drawing_area.connect("draw", self.widget_draw) self.add(self.drawing_area) self.show_all() self.backing = ImageSurface(FORMAT_ARGB32, W, H) rgb_data = b"\120" * W * H * 4 self.paint_rgb(rgb_data, W, H) img = Image.open("./fs/share/icons/xpra.png") w, h = img.size self.paint_image(img, 0, 0, w, h)
def resize(img,widget): def progress(): name=img.split("/")[-1] im1=Image.open(tmp+name+"scaled.png") x=cx.get_text() im2=im1.crop((int(x),0,int(x)+240,400)) im2.save(tmp+name+"resized.jpg") widget.set_from_file(tmp+name+"resized.jpg") control() w.destroy() def move_rectangle(): x=im.get_pointer()[0] cr=im.window.cairo_create() cr.set_source_surface(sf) cr.paint() cr.set_source_rgba(0,0,0,1) cr.rectangle(x,0,240,400) cr.stroke() cx.set_text(str(x)) im1=Image.open(img) a,b,c,d=im1.getbbox() x=(400*c)/d y=400 im2=im1.resize((x,y),Image.ANTIALIAS) name=img.split("/")[-1] im2.save(tmp+name+"scaled.png") w=gtk.Window() w.set_size_request(x,y+30) w.set_resizable(False) w.set_title("Ritaglio Immagine..") vb=gtk.VBox() w.add(vb) im=gtk.DrawingArea() im.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.BUTTON1_MOTION_MASK) vb.add(im) im.connect("motion-notify-event", lambda *w: move_rectangle()) im.connect("expose-event", lambda *w: move_rectangle()) butt=gtk.Button("Ok") butt.set_size_request(80,30) vb.add(butt) vb.set_child_packing(butt,expand=False,fill=False, padding=0,pack_type=gtk.PACK_END) butt.connect("clicked",lambda *w: progress()) w.show_all() sf=ImageSurface.create_from_png(tmp+name+"scaled.png")
def get_qrcode_image(print_href): """ Render a QR code to an ImageSurface. """ scheme, host, path, p, query, f = urlparse(print_href) print_path = scheme + '://' + host + path print_id = parse_qs(query).get('id', [''])[0] q = {'print': print_id} u = urljoin(print_path, 'code.php') + '?' + urlencode(q) handle, filename = mkstemp(suffix='.png') try: write(handle, urlopen(u).read()) close(handle) img = ImageSurface.create_from_png(filename) finally: unlink(filename) return img
def get_qrcode_image(print_href): """ Render a QR code to an ImageSurface. """ scheme, host, path, p, query, f = urlparse(print_href) print_path = scheme + "://" + host + path print_id = parse_qs(query).get("id", [""])[0] q = {"print": print_id} u = urljoin(print_path, "code.php") + "?" + urlencode(q) handle, filename = mkstemp(suffix=".png") try: write(handle, urlopen(u).read()) close(handle) img = ImageSurface.create_from_png(filename) finally: unlink(filename) return img
def get_map_image(bbox, width, height, marker, target_dpi=150): """ Get a cairo ImageSurface for a given bounding box, plus the (x, y) point of a marker. Try to match a target DPI. Width and height are given in millimeters! """ template = 'http://a.tile.cloudmade.com/1a914755a77758e49e19a26e799268b7/22677/256/{Z}/{X}/{Y}.png' provider = TemplatedMercatorProvider(template) locA, locB = Location(bbox[0], bbox[1]), Location(bbox[2], bbox[3]) aspect = float(width) / float(height) mmaps = [mapByExtentZoomAspect(provider, locA, locB, zoom, aspect) for zoom in range(10, 19)] inches_wide = width * ptpmm * inppt resolutions = [(mmap.dimensions.x / inches_wide, mmap) for mmap in mmaps] differences = [(abs(dpi - target_dpi), mmap) for (dpi, mmap) in resolutions] diff, mmap = sorted(differences)[0] if (mmap.dimensions.x * mmap.dimensions.y) > (4000 * 4000): raise ValueError('Requested map is too large: %d x %d' % (mmap.dimensions.x, mmap.dimensions.y)) image_path = get_map_cache_path(mmap) if not exists(image_path): print 'no', image_path mmap.draw().save(image_path) img = ImageSurface.create_from_png(image_path) point = mmap.locationPoint(marker) x = width * point.x / mmap.dimensions.x y = height * point.y / mmap.dimensions.y return img, (x, y)
# Normal(8-bit) Rendering face.load_char('S', FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL ) else: # Mono(1-bit) Rendering face.load_char('S', FT_LOAD_RENDER | FT_LOAD_TARGET_MONO ) bitmap = face.glyph.bitmap width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows pitch = face.glyph.bitmap.pitch glyph_surface = make_image_surface(face.glyph.bitmap) surface = ImageSurface(FORMAT_ARGB32, 800, 600) ctx = Context(surface) ctx.rectangle(0,0,800,600) ctx.set_line_width(0) ctx.set_source_rgb (0.5 , 0.5, 0.5) ctx.fill() # scale = 480.0 / rows ctx.set_source_surface(glyph_surface, 0, 0) pattern = ctx.get_source() SurfacePattern.set_filter(pattern, FILTER_BEST) scalematrix = Matrix() scalematrix.scale(1.0/scale,1.0/scale) scalematrix.translate(-(400.0 - width *scale /2.0 ), -60) pattern.set_matrix(scalematrix) ctx.set_source_rgb (0 , 0, 1)
if __name__ == '__main__': from PIL import Image face = Face('./Vera.ttf') face.set_char_size( 4*48*64 ) flags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP face.load_char('S', flags ) slot = face.glyph glyph = slot.get_glyph() stroker = Stroker( ) stroker.set(64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 ) glyph.stroke( stroker , True ) blyph = glyph.to_bitmap(FT_RENDER_MODE_NORMAL, Vector(0,0), True ) bitmap = blyph.bitmap width, rows, pitch = bitmap.width, bitmap.rows, bitmap.pitch surface = ImageSurface(FORMAT_ARGB32, 600, 800) ctx = Context(surface) Z = make_image_surface(bitmap) ctx.set_source_surface(Z, 0, 0) scale = 640.0 / rows patternZ = ctx.get_source() SurfacePattern.set_filter(patternZ, FILTER_BEST) scalematrix = Matrix() scalematrix.scale(1.0/scale,1.0/scale) scalematrix.translate(-(300.0 - width *scale /2.0 ), -80) patternZ.set_matrix(scalematrix) ctx.set_source_rgb (0 , 0, 1) ctx.mask(patternZ) ctx.fill() surface.flush() surface.write_to_png("glyph-outline-cairo.png")
def make_label(text, filename, size=12, angle=0): ''' Parameters: ----------- text : string Text to be displayed filename : string Path to a font size : int Font size in 1/64th points angle : float Text angle in degrees ''' face = Face(filename) face.set_char_size( size*64 ) # FT_Angle is a 16.16 fixed-point value expressed in degrees. angle = FT_Angle(angle * 65536) matrix = FT_Matrix( FT_Cos( angle ), - FT_Sin( angle ), FT_Sin( angle ) , FT_Cos( angle ) ) flags = FT_LOAD_RENDER pen = FT_Vector(0,0) FT_Set_Transform( face._FT_Face, byref(matrix), byref(pen) ) previous = 0 xmin, xmax = 0, 0 ymin, ymax = 0, 0 for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x0 = (pen.x >> 6) + left x1 = x0 + width y0 = (pen.y >> 6) - (rows - top) y1 = y0 + rows xmin, xmax = min(xmin, x0), max(xmax, x1) ymin, ymax = min(ymin, y0), max(ymax, y1) pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L = ImageSurface(FORMAT_A8, xmax-xmin, ymax-ymin) previous = 0 pen.x, pen.y = 0, 0 ctx = Context(L) for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x = (pen.x >> 6) - xmin + left y = - (pen.y >> 6) + ymax - top if (width > 0): glyph_surface = make_image_surface(face.glyph.bitmap) ctx.set_source_surface(glyph_surface, x, y) ctx.paint() pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L.flush() return L
slot = face.glyph # First pass to compute bbox width, height, baseline = 0, 0, 0 previous = 0 for i,c in enumerate(text): face.load_char(c) bitmap = slot.bitmap height = max(height, bitmap.rows + max(0,-(slot.bitmap_top-bitmap.rows))) baseline = max(baseline, max(0,-(slot.bitmap_top-bitmap.rows))) kerning = face.get_kerning(previous, c) width += (slot.advance.x >> 6) + (kerning.x >> 6) previous = c Z = ImageSurface(FORMAT_A8, width, height) ctx = Context(Z) # Second pass for actual rendering x, y = 0, 0 previous = 0 for c in text: face.load_char(c) bitmap = slot.bitmap top = slot.bitmap_top left = slot.bitmap_left w,h = bitmap.width, bitmap.rows y = height-baseline-top kerning = face.get_kerning(previous, c) x += (kerning.x >> 6) # cairo does not like zero-width bitmap from the space character!
def add_print_page(ctx, mmap, href, well_bounds_pt, points_FG, hm2pt_ratio): """ """ print 'Adding print page:', href well_xmin_pt, well_ymin_pt, well_xmax_pt, well_ymax_pt = well_bounds_pt well_width_pt, well_height_pt = well_xmax_pt - well_xmin_pt, well_ymax_pt - well_ymin_pt # # Offset drawing area to top-left of map area # ctx.translate(well_xmin_pt, well_ymin_pt) # # Build up map area # draw_box(ctx, 0, 0, well_width_pt, well_height_pt) ctx.set_source_rgb(.9, .9, .9) ctx.fill() img = get_mmap_image(mmap) place_image(ctx, img, 0, 0, well_width_pt, well_height_pt) # # Calculate positions of registration points # ctx.save() ctx.translate(well_width_pt, well_height_pt) ctx.scale(1/hm2pt_ratio, 1/hm2pt_ratio) reg_points = (point_A, point_B, point_C, point_D, point_E) + points_FG device_points = [ctx.user_to_device(pt.x, pt.y) for pt in reg_points] ctx.restore() # # Draw QR code area # ctx.save() ctx.translate(well_width_pt, well_height_pt) draw_box(ctx, 0, 0, -90, -90) ctx.set_source_rgb(1, 1, 1) ctx.fill() place_image(ctx, get_qrcode_image(href), -83, -83, 83, 83) ctx.restore() # # Draw registration points # for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, .12 * ptpin) ctx.set_source_rgb(0, 0, 0) ctx.set_line_width(.5) ctx.set_dash([1.5, 3]) ctx.stroke() for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, .12 * ptpin) ctx.set_source_rgb(1, 1, 1) ctx.fill() for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, .06 * ptpin) ctx.set_source_rgb(0, 0, 0) ctx.fill() # # Draw top-left icon # icon = pathjoin(dirname(__file__), '../site/lib/print/icon.png') img = ImageSurface.create_from_png(icon) place_image(ctx, img, 0, -29.13, 19.2, 25.6) try: font = create_cairo_font_face_for_file('fonts/LiberationSans-Bold.ttf') except: # no text for us. pass else: # draw some text. ctx.set_font_face(font) ctx.set_font_size(24) ctx.move_to(0 + 19.2 + 8, -29.13 + 25.6 - 1) ctx.show_text('Walking Papers') try: font = create_cairo_font_face_for_file('fonts/LiberationSans-Regular.ttf') except: # no text for us. pass else: ctx.set_font_face(font) ctx.set_font_size(8) lines = ['OSM data ©2011 CC-BY-SA Openstreetmap.org contributors.', 'Help improve OpenStreetMap by drawing on this map, then visit', href or ''] text_width = max([ctx.text_extents(line)[2] for line in lines]) ctx.move_to(well_width_pt - text_width, -25) ctx.show_text(lines[0]) ctx.move_to(well_width_pt - text_width, -15) ctx.show_text(lines[1]) ctx.move_to(well_width_pt - text_width, -5) ctx.show_text(lines[2]) ctx.show_page()
glyph_surface = make_image_surface(face.glyph.bitmap) ctx.set_source_surface(glyph_surface, x, y) ctx.paint() pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L.flush() return L if __name__ == '__main__': from PIL import Image n_words = 200 H, W, dpi = 600, 800, 72.0 I = ImageSurface(FORMAT_A8, W, H) ctxI = Context(I) ctxI.rectangle(0,0,800,600) ctxI.set_source_rgba (0.9, 0.9, 0.9, 0) ctxI.fill() S = random.normal(0,1,n_words) S = (S-S.min())/(S.max()-S.min()) S = sort(1-sqrt(S))[::-1] sizes = (12 + S*48).astype(int).tolist() def spiral(): eccentricity = 1.5 radius = 8 step = 0.1 t = 0 while True:
face = freetype.Face("/System/Library/Fonts/Apple Color Emoji.ttc") # Not all char sizes are valid for emoji fonts; # Google's NotoColorEmoji only accept size 109 to get 136x128 bitmaps face.set_char_size( 160*64 ) face.load_char('😀', freetype.FT_LOAD_COLOR) bitmap = face.glyph.bitmap width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows # The line below depends on this assumption. Check. if ( face.glyph.bitmap.pitch != width * 4 ): raise RuntimeError('pitch != width * 4 for color bitmap: Please report this.') bitmap = np.array(bitmap.buffer, dtype=np.uint8).reshape((bitmap.rows,bitmap.width,4)) I = ImageSurface(FORMAT_ARGB32, width, rows) try: ndI = np.ndarray(shape=(rows,width), buffer=I.get_data(), dtype=np.uint32, order='C', strides=[I.get_stride(), 4]) except NotImplementedError: raise SystemExit("For python 3.x, you need pycairo >= 1.11+ (from https://github.com/pygobject/pycairo)") # Although both are 32-bit, cairo is host-order while # freetype is small endian. ndI[:,:] = bitmap[:,:,3] * 2**24 + bitmap[:,:,2] * 2**16 + bitmap[:,:,1] * 2**8 + bitmap[:,:,0] I.mark_dirty() surface = ImageSurface(FORMAT_ARGB32, 2*width, rows) ctx = Context(surface)
image = Image.open(image_row['full_img']) except Exception, e: logging.error("failed to open %s because '%s'" % (image_row['full_img'], e)) logging.info("returning a blank image for %s" % image_row['full_img']) image = Image.new('RGBA', (500, 375)) width, height = image.size aspect = float(width) / float(height) handle, png_path = mkstemp(dir='.', suffix='.png') image.save(png_path) try: image = ImageSurface.create_from_png(png_path) except Exception, e: logging.error("failed to create image surface for %s because '%s'" % (image_row['full_img'], e)) image = Image.new('RGBA', (500, 375)) width, height = image.size aspect = float(width) / float(height) handle, png_path = mkstemp(dir='.', suffix='.png') image.save(png_path) image = ImageSurface.create_from_png(png_path) remove(png_path) close(handle)
def _paint_panel(self, key, width, height, panel_h): self.db.IUD("update web_stat_panels set HEIGHT = %s where ID = %s" % (panel_h, key)) self.db.commit() color_x_line = (0.7, 0.7, 0.7) color_x_line_2 = (0.9, 0.9, 0.9) color_y_line = (0.9, 0.9, 0.9) color_y_line_date = (0.7, 0.7, 0.7) color_border = (0.5, 0.5, 0.5) left = 40 right = 10 bottom = 15 var_ids = "0" series = [0, 0, 0, 0] typ = 0 for row in self.db.select( "select SERIES_1, SERIES_2, SERIES_3, SERIES_4, TYP " " from web_stat_panels " " where ID = " + str(key) ): series = row var_ids = "%s, %s, %s, %s" % row[0:4] typ = row[4] width, height = int(width), int(height) if width <= 0: width = 300 if height <= 0: height = 150 interval = self.param("range") delta_x = 1 if interval == "-6 hour": delta_x = 6 * 3600 elif interval == "-12 hour": delta_x = 12 * 3600 elif interval == "-1 day": delta_x = 24 * 3600 elif interval == "-3 day": delta_x = 3 * 24 * 3600 elif interval == "-7 day": delta_x = 7 * 24 * 3600 elif interval == "-14 day": delta_x = 14 * 24 * 3600 elif interval == "-30 day": delta_x = 30 * 24 * 3600 elif interval == "-90 day": delta_x = 3 * 30 * 24 * 3600 elif interval == "-180 day": delta_x = 6 * 30 * 24 * 3600 elif interval == "-360 day": delta_x = 12 * 30 * 24 * 3600 min_x = int(self.param("start")) - delta_x // 2 max_x = min_x + delta_x min_x_q = min_x - delta_x # // 100 max_x_q = max_x + delta_x # // 100 max_y = -9999 min_y = 9999 # Делаем полную выборку данных. Выкидываем подозрительные точки и # собираем статистику. prev_vals = [-9999] * 4 chart_data = [[], [], [], []] zoom_step = delta_x / (width * 5) if zoom_step < 1 or typ != 0: zoom_step = 1 x_min_max_values = [] mi_x = max_x_q ma_x = min_x_q tt = -100 for row in self.db.select( "select UNIX_TIMESTAMP(CHANGE_DATE) D, MIN(VALUE) + (MAX(VALUE) - MIN(VALUE)) VALUE, VARIABLE_ID " " from core_variable_changes " " where VARIABLE_ID in (%s) " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " " group by 3, ROUND(UNIX_TIMESTAMP(CHANGE_DATE) / %s)" " order by 3, 1 " % (var_ids, min_x_q, max_x_q, zoom_step) ): ind = series.index(row[2]) chart_data[ind] += [row] if row[0] > min_x and row[0] < max_x: max_y = max(max_y, row[1]) min_y = min(min_y, row[1]) if tt == -100: tt = row[2] if tt != row[2]: v = [tt, mi_x, ma_x] x_min_max_values += [v] mi_x = max_x_q ma_x = min_x_q tt = row[2] if row[0] < mi_x: mi_x = row[0] if row[0] > ma_x: ma_x = row[0] if tt != -1: v = [tt, mi_x, ma_x] x_min_max_values += [v] # print(x_min_max_values) # print(series) """ for row in self.db.select("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "order by CHANGE_DATE " % (min_x_q, max_x_q)): """ """ try: self.db.IUD("set @rn := 0") sql = ("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "order by CHANGE_DATE " % (min_x_q, max_x_q)) for c in self.db.select("select count(*) c " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " % (min_x_q, max_x_q)): cou = c[0] ccc = 1000 * 4 if cou > ccc: sql = ("select UNIX_TIMESTAMP(CHANGE_DATE) D, VALUE, VARIABLE_ID, ID, @rn := @rn + 1 rownum " " from core_variable_changes " " where VARIABLE_ID in (" + var_ids + ") " " and CHANGE_DATE >= FROM_UNIXTIME(%s) " " and CHANGE_DATE <= FROM_UNIXTIME(%s) " "having mod(rownum, %s) = 0 " "order by VARIABLE_ID, CHANGE_DATE " % (min_x_q, max_x_q, math.ceil(cou / ccc))) for row in self.db.select(sql): ind = series.index(row[2]) prev_vals[ind] = row[1] if abs(prev_vals[ind] - row[1]) < 10: chart_data[ind] += [row] if row[0] > min_x and row[0] < max_x: max_y = max(max_y, row[1]) min_y = min(min_y, row[1]) prev_vals[ind] = row[1] except: pass """ if min_y is None or max_y is None or min_y == 9999 or max_y == -9999 or min_y == max_y: max_y = 1 min_y = 0 min_y = math.floor(min_y) max_y = math.ceil(max_y) if typ == 2: if min_y < 0 and max_y < 0: max_y = 0 elif min_y > 0 and max_y > 0: min_y = 0 # Определяем цвета colors = [[1, 0, 0], [0, 0.65, 0.31], [0, 0, 1], [1, 0, 1]] off_y = (max_y - min_y) / 10 min_y -= off_y max_y += off_y try: kx = (max_x - min_x) / (width - left - right) ky = (max_y - min_y) / (height - bottom) if ky == 0: ky = 1 except: kx, ky = 1, 1 img = ImageSurface(FORMAT_ARGB32, width, height) ctx = Context(img) width -= right ctx.set_line_width(1) # Рисуем сетку ctx.set_font_size(12) try: b_w, b_h = ctx.text_extents("00-00-0000")[2:4] # Метки на оси Y count = math.ceil(max_y) - math.ceil(min_y) space_count = math.ceil(count / ((height - bottom) / (b_h * 1.5))) sc = 0 for i in range(math.ceil(min_y), math.ceil(max_y)): if sc == 0: y = height - bottom + (min_y - i) / ky ctx.set_source_rgb(*(color_x_line)) ctx.move_to(left, y) ctx.line_to(width, y) ctx.stroke() ctx.set_source_rgb(0, 0, 0) num = str(i) tw, th = ctx.text_extents(num)[2:4] ctx.move_to(left - 5 - tw, y + th // 2) ctx.show_text(num) sc = space_count sc -= 1 # Метки на оси Х x_step = 3600 if interval == "-6 hour" or interval == "-12 hour" or interval == "-1 day": # Дополнительно метки часов x_step = 3600 for i in range(math.ceil(min_x / x_step), math.ceil(max_x / x_step)): x = (i * x_step - min_x) / kx + left ctx.set_source_rgb(*(color_x_line_2)) ctx.move_to(x, 0) ctx.line_to(x, height - bottom) ctx.stroke() num = datetime.datetime.fromtimestamp(i * x_step).strftime("%H") tw, th = ctx.text_extents(num)[2:4] ctx.move_to(x + 2, height - bottom - 3) ctx.set_source_rgb(*(color_x_line)) ctx.show_text(num) x_step = 3600 * 24 space_count = 1 count = math.ceil(max_x / x_step) - math.ceil(min_x / x_step) try: if (width / count) < b_w: space_count = 2 except: pass sc = 0 tz = 3600 * 2 tx_prev = -100 for i in range(math.ceil(min_x / x_step), math.ceil(max_x / x_step) + 1): if sc == 0: d_i = datetime.datetime.fromtimestamp(i * x_step) x = (i * x_step - min_x - tz) / kx + left ctx.set_source_rgb(0, 0, 0) num = d_i.strftime("%d-%m-%Y %H") x -= (int(d_i.strftime("%H")) * 3600 - tz) / kx tw, th = ctx.text_extents(num)[2:4] tx = x - tw // 2 ctx.move_to(tx, height - bottom + th + 5) if tx - tx_prev > tw: ctx.show_text(num) tx_prev = tx ctx.set_source_rgb(*(color_y_line_date)) else: ctx.set_source_rgb(*(color_y_line)) if x >= left and x < width: ctx.move_to(x, 0) ctx.line_to(x, height - bottom) ctx.stroke() sc = space_count sc -= 1 except Exception as e: pass # Рисуем верхний и правый бордер ctx.set_source_rgb(*color_border) ctx.move_to(left, 0) ctx.line_to(width, 0) ctx.line_to(width, height - bottom) ctx.stroke() # Рисуем сами графики ctx.rectangle(left, 0, width - left, height) ctx.clip() is_first = True currVarID = -1 prevX = -1 if typ == 0: # Линейная for ind in range(4): """ if len(chart_data[ind]) > 0: for i in range(len(chart_data[ind]) - 1): chart_data[ind][i] = list(chart_data[ind][i]) r1 = chart_data[ind][i] r2 = chart_data[ind][i + 1] chart_data[ind][i][0] += (r2[0] - r1[0]) / 2 chart_data[ind][i][1] += (r2[1] - r1[1]) / 2 """ ctx.set_source_rgb(*colors[ind]) is_first = True for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky if is_first: ctx.move_to(x, y) else: if row[0] - prevX > 10000: ctx.move_to(x, y) else: ctx.line_to(x, y) prevX = row[0] is_first = False ctx.stroke() elif typ == 1: # Точечная for ind in range(4): if chart_data[ind]: ctx.set_source_rgb(*colors[ind]) for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky ctx.rectangle(x - 3, y - 3, 6, 6) ctx.fill() elif typ == 2: # Столбчатая cy = height - bottom - (-min_y) / ky for ind in range(4): for row in chart_data[ind]: if currVarID != row[2]: ctx.fill() for i in range(4): if series[i] == row[2]: ctx.set_source_rgb(*colors[i]) x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky ctx.rectangle(x - 5, y, 10, cy - y) currVarID = row[2] ctx.fill() else: # Линейчастая # one_vals = self._get_one_val(series, min_x_q, max_x_q) one_vals = self._get_one_val(series, x_min_max_values, min_x_q, max_x_q) for ind in range(4): if series[ind]: is_now = True for r in one_vals[ind]: if r[4] == 1: chart_data[ind].insert(0, r) else: chart_data[ind] += [r] is_now = False if is_now: if len(chart_data[ind]) > 0: r = list(chart_data[ind][len(chart_data[ind]) - 1]) r[0] = datetime.datetime.now().timestamp() chart_data[ind] += [r] color = colors[ind] color_fill = color.copy() color_fill += [0.3] is_first = True y0 = height - bottom + min_y / ky for row in chart_data[ind]: x = (row[0] - min_x) / kx + left y = height - bottom - (row[1] - min_y) / ky if is_first: is_first = False else: ctx.set_source_rgb(*color) ctx.move_to(prevX, prevY) ctx.line_to(x, prevY) ctx.line_to(x, y) ctx.stroke() ctx.set_source_rgba(*color_fill) rx, ry, rw, rh = prevX, y0, x - prevX, prevY - y0 ctx.rectangle(rx, ry, rw, rh) ctx.fill() prevX, prevY = x, y # Рисуем оси ctx.set_source_rgb(0, 0, 0) ctx.move_to(left, 0) ctx.line_to(left, height - bottom) ctx.line_to(width, height - bottom) ctx.stroke() # --------------------------- del ctx byt = BytesIO() img.write_to_png(byt) byt.seek(0) return byt.read()
# Replacement for Path enums: STOP, MOVETO, LINETO, CURVE3, CURVE4 = 0, 1, 2, 3, 4 face = Face('./Vera.ttf') face.set_char_size( 48*64 ) face.load_char('S') slot = face.glyph outline = slot.outline points = numpy.array(outline.points, dtype=[('x',float), ('y',float)]) x, y = points['x'], points['y'] cbox = outline.get_cbox() surface = ImageSurface(FORMAT_ARGB32, (cbox.xMax - cbox.xMin)//4 + 20, (cbox.yMax - cbox.yMin)//4 + 20) ctx = Context(surface) ctx.scale(0.25,0.25) ctx.translate(-cbox.xMin + 40,-cbox.yMin + 40) ctx.transform(Matrix(1,0,0,-1)) ctx.translate(0, -(cbox.yMax + cbox.yMin)) # difference! Curve_Tag = [FT_Curve_Tag(tag) for tag in outline.tags] start, end = 0, 0 VERTS, CODES = [], [] # Iterate over each contour ctx.set_source_rgb(0.5,0.5,0.5) for i in range(len(outline.contours)):
from PIL import Image from numpy import ndarray, ubyte, uint32 face = Face('./Vera.ttf') face.set_char_size( 48*64 ) face.load_char('S', FT_LOAD_RENDER | FT_LOAD_TARGET_LCD ) bitmap = face.glyph.bitmap width = face.glyph.bitmap.width//3 rows = face.glyph.bitmap.rows pitch = face.glyph.bitmap.pitch copybuffer = (c_ubyte * (pitch * rows))() memmove(pointer(copybuffer), bitmap._FT_Bitmap.buffer, pitch * rows) I = ImageSurface(FORMAT_ARGB32, width, rows) ndR = ndarray(shape=(rows,width), buffer=copybuffer, dtype=ubyte, order='C', offset=0, strides=[pitch, 3]) ndG = ndarray(shape=(rows,width), buffer=copybuffer, dtype=ubyte, order='C', offset=1, strides=[pitch, 3]) ndB = ndarray(shape=(rows,width), buffer=copybuffer, dtype=ubyte, order='C', offset=2, strides=[pitch, 3]) try: ndI = ndarray(shape=(rows,width), buffer=I.get_data(), dtype=uint32, order='C',
def add_print_page(ctx, mmap, href, well_bounds_pt, points_FG, hm2pt_ratio, layout, text, mark, fuzzy, indexees): """ """ print "Adding print page:", href well_xmin_pt, well_ymin_pt, well_xmax_pt, well_ymax_pt = well_bounds_pt well_width_pt, well_height_pt = well_xmax_pt - well_xmin_pt, well_ymax_pt - well_ymin_pt well_aspect_ratio = well_width_pt / well_height_pt # # Offset drawing area to top-left of map area # ctx.translate(well_xmin_pt, well_ymin_pt) # # Build up map area # img = get_mmap_image(mmap) if layout == "half-page" and well_aspect_ratio > 1: map_width_pt, map_height_pt = well_width_pt / 2, well_height_pt add_page_text(ctx, text, map_width_pt + 24, 24, map_width_pt - 48, map_height_pt - 48) elif layout == "half-page" and well_aspect_ratio < 1: map_width_pt, map_height_pt = well_width_pt, well_height_pt / 2 add_page_text(ctx, text, 32, map_height_pt + 16, map_width_pt - 64, map_height_pt - 32) else: map_width_pt, map_height_pt = well_width_pt, well_height_pt place_image(ctx, img, 0, 0, map_width_pt, map_height_pt) # # Draw a dot if need be # if fuzzy is not None: loc = Location(fuzzy[1], fuzzy[0]) pt = mmap.locationPoint(loc) x = map_width_pt * float(pt.x) / mmap.dimensions.x y = map_height_pt * float(pt.y) / mmap.dimensions.y draw_circle(ctx, x, y, 20) ctx.set_source_rgb(0, 0, 0) ctx.set_line_width(2) ctx.set_dash([2, 6]) ctx.stroke() # # X marks the spot, if needed # if mark is not None: loc = Location(mark[1], mark[0]) pt = mmap.locationPoint(loc) x = map_width_pt * float(pt.x) / mmap.dimensions.x y = map_height_pt * float(pt.y) / mmap.dimensions.y draw_cross(ctx, x, y, 8, 6) ctx.set_source_rgb(1, 1, 1) ctx.fill() draw_cross(ctx, x, y, 8, 4) ctx.set_source_rgb(0, 0, 0) ctx.fill() # # Perhaps some boxes? # page_numbers = [] for page in indexees: north, west, south, east = page["bounds"] ul = mmap.locationPoint(Location(north, west)) lr = mmap.locationPoint(Location(south, east)) x1 = map_width_pt * float(ul.x) / mmap.dimensions.x x2 = map_width_pt * float(lr.x) / mmap.dimensions.x y1 = map_height_pt * float(ul.y) / mmap.dimensions.y y2 = map_height_pt * float(lr.y) / mmap.dimensions.y draw_box(ctx, x1, y1, x2 - x1, y2 - y1) ctx.set_source_rgb(0, 0, 0) ctx.set_line_width(1) ctx.set_dash([]) ctx.stroke() page_numbers.append((x1, y1, x2, y2, page["number"])) # # Calculate positions of registration points # ctx.save() ctx.translate(well_width_pt, well_height_pt) ctx.scale(1 / hm2pt_ratio, 1 / hm2pt_ratio) reg_points = (point_A, point_B, point_C, point_D, point_E) + points_FG device_points = [ctx.user_to_device(pt.x, pt.y) for pt in reg_points] ctx.restore() # # Draw QR code area # ctx.save() ctx.translate(well_width_pt, well_height_pt) draw_box(ctx, 0, 0, -90, -90) ctx.set_source_rgb(1, 1, 1) ctx.fill() place_image(ctx, get_qrcode_image(href), -83, -83, 83, 83) ctx.restore() # # Draw registration points # for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, 0.12 * ptpin) ctx.set_source_rgb(0, 0, 0) ctx.set_line_width(0.5) ctx.set_dash([1.5, 3]) ctx.stroke() for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, 0.12 * ptpin) ctx.set_source_rgb(1, 1, 1) ctx.fill() for (x, y) in device_points: x, y = ctx.device_to_user(x, y) draw_circle(ctx, x, y, 0.06 * ptpin) ctx.set_source_rgb(0, 0, 0) ctx.fill() # # Draw top-left icon # icon = pathjoin(dirname(__file__), "images/logo.png") img = ImageSurface.create_from_png(icon) place_image(ctx, img, 0, -36, 129.1, 36) try: font_file = realpath("fonts/Helvetica.ttf") if font_file not in cached_fonts: cached_fonts[font_file] = create_cairo_font_face_for_file(font_file) font = cached_fonts[font_file] except: # no text for us. pass else: ctx.set_font_face(font) ctx.set_font_size(12) line = href text_width = ctx.text_extents(line)[2] ctx.move_to(well_width_pt - text_width, -6) ctx.show_text(line) add_scale_bar(ctx, mmap, map_height_pt) ctx.set_font_face(font) ctx.set_font_size(18) for (x1, y1, x2, y2, number) in page_numbers: number_w, number_h = ctx.text_extents(number)[2:4] offset_x, offset_y = (x1 + x2 - number_w) / 2, (y1 + y2 + number_h) / 2 draw_box(ctx, offset_x - 4, offset_y - number_h - 4, number_w + 8, number_h + 8) ctx.set_source_rgb(1, 1, 1) ctx.fill() ctx.set_source_rgb(0, 0, 0) ctx.move_to(offset_x, offset_y) ctx.show_text(number) ctx.show_page()
def generateOverlay(text, font, showFlumotion, showCC, showXiph, width, height): """Generate an transparent image with text + logotypes rendered on top of it suitable for mixing into a video stream @param text: text to put in the top left corner @type text: str @param font: font description used to render the text @type: str @param showFlumotion: if we should show the flumotion logo @type showFlumotion: bool @param showCC: if we should show the Creative Common logo @type showCC: bool @param showXiph: if we should show the xiph logo @type showXiph: bool @param width: width of the image to generate @type width: int @param height: height of the image to generate @type height: int @returns: raw image and if images or if text overflowed @rtype: 3 sized tuple of string and 2 booleans """ from cairo import ImageSurface from cairo import Context image = ImageSurface(cairo.FORMAT_ARGB32, width, height) context = Context(image) subImages = [] if showXiph: subImages.append(os.path.join(configure.imagedir, '36x36', 'xiph.png')) if showCC: subImages.append(os.path.join(configure.imagedir, '36x36', 'cc.png')) if showFlumotion: subImages.append(os.path.join(configure.imagedir, '36x36', 'fluendo.png')) imagesOverflowed = False offsetX = BORDER for subPath in subImages: sub = ImageSurface.create_from_png(subPath) subX = sub.get_width() subY = sub.get_height() offsetY = height - subY - BORDER context.set_source_surface(sub, offsetX, offsetY) context.paint() if (offsetX + subX) > width: imagesOverflowed = True offsetX += subX + BORDER textOverflowed = False if text: pcContext = pangocairo.CairoContext(context) pangoLayout = pcContext.create_layout() if font is not None: font = pango.FontDescription(font) if not font.get_family() or \ not font.get_family().lower() in [family.get_name().lower() for family in pangoLayout.get_context().list_families()]: font.set_family(FONT) if font.get_size() == 0: font.set_size(FONT_SIZE) else: font = pango.FontDescription('%s %s' % (FONT, FONT_PROPS)) pangoLayout.set_font_description(font) context.move_to(TEXT_XOFFSET+2, TEXT_YOFFSET+2) pangoLayout.set_markup('<span foreground="black" >%s</span>' % text) pcContext.show_layout(pangoLayout) context.move_to(TEXT_XOFFSET, TEXT_YOFFSET) pangoLayout.set_markup('<span foreground="white" >%s</span>' % text) pcContext.show_layout(pangoLayout) textWidth, textHeight = pangoLayout.get_pixel_size() if textWidth > width: textOverflowed = True if cairo.version < '1.2.6': buf = image.get_data_as_rgba() else: buf = image.get_data() return buf, imagesOverflowed, textOverflowed