Example #1
0
    def cairo_paint_from_source(self, set_source_fn, source, x: int, y: int,
                                iw: int, ih: int, width: int, height: int,
                                options):
        """ must be called from UI thread """
        backing = self._backing
        log("cairo_paint_surface%s backing=%s, paint box line width=%i",
            (set_source_fn, source, x, y, iw, ih, width, height, options),
            backing, self.paint_box_line_width)
        if not backing:
            return
        gc = Context(backing)
        if self.paint_box_line_width:
            gc.save()

        gc.rectangle(x, y, width, height)
        gc.clip()

        gc.set_operator(OPERATOR_CLEAR)
        gc.rectangle(x, y, width, height)
        gc.fill()

        gc.set_operator(OPERATOR_SOURCE)
        gc.translate(x, y)
        if iw != width or ih != height:
            gc.scale(width / iw, height / ih)
        gc.rectangle(0, 0, width, height)
        set_source_fn(gc, source, 0, 0)
        gc.paint()

        if self.paint_box_line_width:
            gc.restore()
            encoding = options.get("encoding")
            self.cairo_paint_box(gc, encoding, x, y, width, height)
Example #2
0
    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()
Example #3
0
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()
Example #4
0
    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()
Example #5
0
    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()
Example #6
0
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None):

    from cairo import SVGSurface, Context
    from .ddd import spatial_sort_2d as sort

    if not scale_factor:
        scale_factor = size

    s = SVGSurface(fn, size, size)
    c = Context(s)

    c.set_line_width(0.1)

    paths = sort(paths)

    for path in paths:
        path *= scale_factor

        c.new_path()
        c.move_to(*path[0, :])
        for p in path[1:]:
            c.line_to(*p)
        c.stroke()

    c.save()
Example #7
0
 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
Example #8
0
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
Example #9
0
File: layout.py Project: imclab/4up
def setup_doc(name):
    '''
    '''
    doc = PDFSurface(name, sheet_width*ptpin, sheet_height*ptpin)
    ctx = Context(doc)
    ctx.scale(ptpin, ptpin)
    
    set_font_face_from_file(ctx, 'DejaVuSerifCondensed.ttf')
    
    return doc, ctx
Example #10
0
def textwidth(text: str, fontSize: int, font: str):
    fn = abspath(gettempdir() + "/" + next(_get_candidate_names()))
    width = len(text) * fontSize
    with SVGSurface(fn, 1280, 720) as surface:
        cr = Context(surface)
        cr.select_font_face(font, FONT_SLANT_NORMAL, FONT_WEIGHT_BOLD)
        cr.set_font_size(fontSize)
        width = cr.text_extents(text)[2]
    remove(fn)
    return round(width, 1)
Example #11
0
 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
Example #12
0
    def get_context_for_image(self, zoom):
        """Creates a temporary cairo context for the image surface

        :param zoom: The current scaling factor
        :return: Cairo context to draw on
        """
        cairo_context = Context(self.__image)
        c = CairoContext(cairo_context)
        c.scale(zoom * self.multiplicator, zoom * self.multiplicator)
        return c
def extract_polygon_data(romset_dir, cinematic):
    global polygon_data, pdata_offset
    global cinematic_entries
    global cinematic_counter
    global video2_entries
    global game_level

    if cinematic:
        try:
            polygon_data = open(f"{romset_dir}/cinematic.rom", "rb").read()
        except:
            print("FIXME! Did not find a cinematic.rom file...")
            return
        entries = cinematic_entries
        level_path = f"{output_dir}/level_{game_level}"
        dirpath = f"{level_path}/cinematic/"
        makedir(level_path)
    else:
        try:
            polygon_data = open(f"{romset_dir}/video2.rom", "rb").read()
        except:
            print("FIXME! Did not find a video2.rom file...")
            return

        entries = video2_entries
        dirpath = f"{output_dir}/common_video/"
        game_level = 0

    makedir(dirpath)

    for addr in entries.keys():
        entry = entries[addr]
        s = SVGSurface(f"{dirpath}/{entry['label']}.svg", 320, 200)
        c = Context(s)
        zoom = entry["zoom"]
        x = entry["x"]
        y = entry["y"]

        if not isinstance(zoom, int):
            zoom = 0x40  #HACK!

        if not isinstance(x, int):
            x = 160  #HACK!

        if not isinstance(y, int):
            y = 100  #HACK!

        #print ("\ndecoding polygons at {}: {}".format(hex(addr), entry))
        pdata_offset = addr
        readAndDrawPolygon(c, COLOR_BLACK, zoom, x, y)
        s.finish()

    # reset structures:
    cinematic_entries = {}
    cinematic_counter = 0
    def extract_polygon_data(self, game_level, entries, cinematic):
        if cinematic:
            self.game_level = game_level
        else:
            self.game_level = 0

        try:
            self.palette_data = open(f"{self.romset_dir}/palettes.rom", "rb").read()
        except:
            print("ERROR! Did not find a palettes.rom file...")
            return

        if cinematic:
            try:
                self.polygon_data = open(f"{self.romset_dir}/cinematic.rom", "rb").read()
            except:
                print("ERROR! Did not find a cinematic.rom file...")
                return
            level_path = f"{self.output_dir}/level_{game_level}"
            dirpath = f"{level_path}/cinematic/"
            makedir(level_path)
        else:
            try:
                self.polygon_data = open(f"{self.romset_dir}/video2.rom", "rb").read()
            except:
                print("ERROR! Did not find a video2.rom file...")
                return
    
            dirpath = f"{self.output_dir}/common_video/"

        makedir(dirpath)

        for addr in entries.keys():
            entry = entries[addr]
            s = SVGSurface(f"{dirpath}/{entry['label']}.svg", 320, 200)
            ctx = Context(s)
            zoom = entry["zoom"]
            x = entry["x"]
            y = entry["y"]
            palette_number = entry["palette_number"]

            if not isinstance(zoom, int):
                zoom = 0x40 #HACK!

            if not isinstance(x, int):
                x = 160 #HACK!

            if not isinstance(y, int):
                y = 100 #HACK!

            #print ("\ndecoding polygons at {}: {}".format(hex(addr), entry))
            self.readAndDrawPolygon(addr, ctx, palette_number, COLOR_BLACK, zoom, x, y)
            s.finish()
Example #15
0
    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
Example #16
0
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
Example #17
0
 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)
Example #18
0
    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()
Example #19
0
    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
Example #20
0
    def func(image, objects, *args, **kwargs):
        # Allow sending in a single object in every function.
        if not (isinstance(objects, list) or isinstance(objects, tuple)):
            objects = [objects]

        # Calculate the appropriate scaling for the markers.
        area = image.shape[1] * image.shape[0]
        for ref_area, scale in MARKER_SCALES:
            if area >= ref_area:
                break

        # TODO: Ideally, we would like to avoid having to create a copy of the
        # array just to add paddings to support the cairo format, but there's
        # no way to use a cairo surface with 24bpp.

        # TODO: Take into account endianness of the machine, as it's possible
        # it has to be concatenated in the other order in some machines.

        # We need to add an extra `alpha` layer, as cairo only supports 32 bits
        # per pixel formats, and our numpy array uses 24. This means creating
        # one copy before modifying and a second copy afterwards.
        with_alpha = np.concatenate([
            image[..., ::-1], 255 * np.ones(
                (image.shape[0], image.shape[1], 1), dtype=np.uint8)
        ],
                                    axis=2)

        surface = ImageSurface.create_for_data(with_alpha, cairo.Format.RGB24,
                                               image.shape[1], image.shape[0])

        ctx = Context(surface)

        # Set up the font. If not available, will default to a Sans Serif
        # font available in the system, so no need to have fallbacks.
        ctx.select_font_face("DejaVuSans-Bold", cairo.FONT_SLANT_NORMAL,
                             cairo.FONT_WEIGHT_NORMAL)
        ctx.set_font_size(int(16 * scale))

        vis_func(ctx, objects, scale=scale, *args, **kwargs)

        # Return the newly-drawn image, excluding the extra alpha channel
        # added.
        image = with_alpha[..., :-1][..., ::-1]

        return image
Example #21
0
def export_svg(fn, paths, w, h, line_width=0.1):

    from cairo import SVGSurface, Context

    s = SVGSurface(fn, w, h)
    c = Context(s)

    c.set_line_width(line_width)

    for path in paths:

        c.new_path()
        c.move_to(*path[0, :])
        for p in path[1:]:
            c.line_to(*p)
        c.stroke()

    c.save()
Example #22
0
 def paint_image(self, img, x, y, w, h):
     #roundtrip via png (yuk)
     from io import BytesIO
     png = BytesIO()
     img.save(png, format="PNG")
     reader = BytesIO(png.getvalue())
     png.close()
     img = ImageSurface.create_from_png(reader)
     gc = Context(self.backing)
     gc.rectangle(x, y, w, h)
     gc.clip()
     gc.set_operator(OPERATOR_CLEAR)
     gc.rectangle(x, y, w, h)
     gc.fill()
     gc.set_operator(OPERATOR_SOURCE)
     gc.translate(x, y)
     gc.rectangle(0, 0, w, h)
     gc.set_source_surface(img, x, y)
     gc.paint()
Example #23
0
    def __init__(self, filename, width, height):
        """
        """
        self.filename = filename
        self.size = width, height

        handle, dummy_file = mkstemp(prefix='cairoutils-', suffix='.pdf')
        close(handle)

        surface = PDFSurface(dummy_file, width, height)
        self.context = Context(surface)

        self.commands = []
        self.garbage = [dummy_file]
        self.page = []

        self.point = Point(0, 0)
        self.stack = [(1, 0, 0, 0, -1, height)]
        self.affine = Affine(*self.stack[0])
Example #24
0
def svg_to_png(filename, icondata, w=128, h=128):
    if not SVG_TO_PNG:
        return None
    Rsvg = load_Rsvg()
    log("svg_to_png%s Rsvg=%s", (filename, "%i bytes" % len(icondata), w, h),
        Rsvg)
    if not Rsvg:
        return None
    try:
        from cairo import ImageSurface, Context, FORMAT_ARGB32  #pylint: disable=no-name-in-module, import-outside-toplevel
        #'\sinkscape:[a-zA-Z]*=["a-zA-Z0-9]*'
        img = ImageSurface(FORMAT_ARGB32, w, h)
        ctx = Context(img)
        handle = Rsvg.Handle.new_from_data(icondata)
        dim = handle.get_dimensions()
        ctx.scale(w / dim.width, h / dim.height)
        handle.render_cairo(ctx)
        del handle
        img.flush()
        buf = BytesIO()
        img.write_to_png(buf)
        icondata = buf.getvalue()
        buf.close()
        img.finish()
        return icondata
    except Exception:
        log("svg_to_png%s", (icondata, w, h), exc_info=True)
        if re.findall(INKSCAPE_RE, icondata):
            #try again after stripping the bogus inkscape attributes
            #as some rsvg versions can't handle that (ie: Debian Bullseye)
            icondata = re.sub(INKSCAPE_RE, b"", icondata)
            return svg_to_png(filename, icondata, w, h)
        if icondata.find(INKSCAPE_BROKEN_SODIPODI_DTD) > 0:
            icondata = icondata.replace(INKSCAPE_BROKEN_SODIPODI_DTD,
                                        INKSCAPE_SODIPODI_DTD)
            return svg_to_png(filename, icondata, w, h)
        log.error("Error: failed to convert svg icon")
        if filename:
            log.error(" '%s':", filename)
        log.error(" %i bytes, %s", len(icondata), ellipsizer(icondata))
        return None
def main(args, **argv):

  from dddUtils.ioOBJ import load_2d as load
  from cairo import SVGSurface, Context
  from numpy import array
  from glob import glob

  prefix = args.prefix
  size = args.size
  scale = args.scale
  one = 1.0/size
  steps = args.steps
  stride = args.stride
  skip = args.skip

  out = prefix + '.svg'
  print('making file: {:s}'.format(out))

  s = SVGSurface(out, size, size)
  c = Context(s)

  c.set_line_width(0.1)
  c.set_source_rgba(*BLACK)


  for fn in sorted(glob(prefix + '*.2obj'))[skip:steps:stride]:

    print(fn)

    data = load(fn)

    vertices = data['vertices']
    vertices *= scale*size
    edges = data['edges']
    # make_random_line(c, vertices, edges)
    make_line(c, vertices, edges)

  c.save()

  return
def main(args, **argv):

    # from render.render import Render
    from dddUtils.ioOBJ import load_2d as load
    from cairo import SVGSurface, Context
    from numpy import array

    size = args.size
    scale = args.scale
    one = 1.0 / size

    data = load(args.fn)
    print(data)

    vertices = data['vertices']
    faces = data['faces']
    edges = data['edges']

    out = '.'.join(args.fn.split('.')[:-1]) + '.svg'
    print('making file: {:s}'.format(out))

    s = SVGSurface(out, size, size)
    c = Context(s)

    c.set_line_width(0.1)
    c.set_source_rgba(*BLACK)

    vertices -= get_mid(vertices)
    vertices *= scale
    vertices += array([[0.5, 0.5]])
    vertices *= size

    make_triangles(c, vertices, faces, edges)
    # make_random_length_strips(c, vertices, faces, edges)

    c.save()

    return
Example #27
0
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)
Example #28
0
    def _to_png(self,
                font,
                font_position=None,
                dst=None,
                limit=800,
                size=1500,
                tab_width=1500,
                padding_characters=""):
        """Use HB, FreeType and Cairo to produce a png for a table.

        Parameters
        ----------
        font: DFont
        font_position: str
            Label indicating which font has been used. 
        dst: str
            Path to output image. If no path is given, return in-memory 
        """
        # TODO (M Foley) better packaging for pycairo, freetype-py
        # and uharfbuzz.
        # Users should be able to pip install these bindings without needing
        # to install the correct libs.

        # A special mention to the individuals who maintain these packages. Using
        # these dependencies has sped up the process of creating diff images
        # significantly. It's an incredible age we live in.
        y_tab = int(1500 / 25)
        x_tab = int(tab_width / 64)
        width, height = 1024, 200

        cells_per_row = int((width - x_tab) / x_tab)
        # Compute height of image
        x, y, baseline = x_tab, 0, 0
        for idx, row in enumerate(self._data[:limit]):
            x += x_tab

            if idx % cells_per_row == 0:
                y += y_tab
                x = x_tab
        height += y
        height += 100

        # draw image
        Z = ImageSurface(FORMAT_ARGB32, width, height)
        ctx = Context(Z)
        ctx.rectangle(0, 0, width, height)
        ctx.set_source_rgb(1, 1, 1)
        ctx.fill()

        # label image
        ctx.set_font_size(30)
        ctx.set_source_rgb(0.5, 0.5, 0.5)
        ctx.move_to(x_tab, 50)
        ctx.show_text("{}: {}".format(self.table_name, len(self._data)))
        ctx.move_to(x_tab, 100)
        if font_position:
            ctx.show_text("Font Set: {}".format(font_position))
        if len(self._data) > limit:
            ctx.set_font_size(20)
            ctx.move_to(x_tab, 150)
            ctx.show_text(
                "Warning: {} different items. Only showing most serious {}".
                format(len(self._data), limit))

        hb.ot_font_set_funcs(font.hbfont)

        # Draw glyphs
        x, y, baseline = x_tab, 200, 0
        x_pos = x_tab
        y_pos = 200
        for idx, row in enumerate(self._data[:limit]):
            string = "{}{}{}".format(padding_characters, row['string'],
                                     padding_characters)
            buf = self._shape_string(font, string, row['features'])
            char_info = buf.glyph_infos
            char_pos = buf.glyph_positions
            for info, pos in zip(char_info, char_pos):
                gid = info.codepoint
                font.ftfont.load_glyph(gid, flags=6)
                bitmap = font.ftslot.bitmap

                if bitmap.width > 0:
                    ctx.set_source_rgb(0, 0, 0)
                    glyph_surface = _make_image_surface(
                        font.ftfont.glyph.bitmap, copy=False)
                    ctx.set_source_surface(
                        glyph_surface,
                        x_pos + font.ftslot.bitmap_left + (pos.x_offset / 64.),
                        y_pos - font.ftslot.bitmap_top - (pos.y_offset / 64.))
                    glyph_surface.flush()
                    ctx.paint()
                x_pos += (pos.x_advance) / 64.
                y_pos += (pos.y_advance) / 64.

            x_pos += x_tab - (x_pos % x_tab)
            if idx % cells_per_row == 0:
                # add label
                if font_position:
                    ctx.set_source_rgb(0.5, 0.5, 0.5)
                    ctx.set_font_size(10)
                    ctx.move_to(width - 20, y_pos)
                    ctx.rotate(1.5708)
                    ctx.show_text(font_position)
                    ctx.set_source_rgb(0, 0, 0)
                    ctx.rotate(-1.5708)
                # Start a new row
                y_pos += y_tab
                x_pos = x_tab
        Z.flush()
        if dst:
            Z.write_to_png(dst)
        else:
            img = StringIO()
            Z.write_to_png(img)
            return Image.open(img)
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
            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:
            t += step