Exemple #1
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()
    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()
Exemple #3
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()
Exemple #4
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:
        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()
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #8
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
Exemple #9
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)
            [tags.pop() for x in range(len(segment) - 1)]
        VERTS.extend(verts)
        CODES.extend(codes)
        start = end+1

    ctx.new_path()
    ctx.set_source_rgba(1,1,0, 0.5)
    i = 0
    while (i < len(CODES)):
        if (CODES[i] == MOVETO):
            ctx.move_to(VERTS[i][0],VERTS[i][1])
            i += 1
        elif (CODES[i] == LINETO):
            ctx.line_to(VERTS[i][0],VERTS[i][1])
            i += 1
        elif (CODES[i] == CURVE3):
            ctx.curve_to(VERTS[i][0],VERTS[i][1],
                         VERTS[i+1][0],VERTS[i+1][1], # undocumented
                         VERTS[i+1][0],VERTS[i+1][1])
            i += 2
        elif (CODES[i] == CURVE4):
            ctx.curve_to(VERTS[i][0],VERTS[i][1],
                         VERTS[i+1][0],VERTS[i+1][1],
                         VERTS[i+2][0],VERTS[i+2][1])
            i += 3
    ctx.fill()

    surface.flush()
    surface.write_to_png("glyph-vector-cairo.png")
    Image.open("glyph-vector-cairo.png").show()
    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")
    Image.open("glyph-outline-cairo.png").show()
Exemple #12
0
class Canvas:
    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)

    @property
    def width(self) -> int:
        return self._width if not self._normalise else 1

    @property
    def height(self) -> int:
        return self._height if not self._normalise else 1

    # TODO depreciate
    @property
    def context(self) -> Context:  # pragma: no cover
        return self._context

    def save(self) -> None:
        self._context.save()

    def restore(self) -> None:
        self._context.restore()

    # Transformation
    def rotate(self, angle: float) -> None:
        self._context.rotate(angle)

    def translate(self, x: float, y: float) -> None:
        self._context.translate(x, y)

    def scale(self, width: int, height: int) -> None:
        self._context.scale(width, height)

    def set_line_width(self, width: float) -> None:
        self._context.set_line_width(width)

    # Colour functionality
    def set_colour(self, colour: Colour) -> None:
        self._context.set_source_rgba(colour.red, colour.blue, colour.green,
                                      colour.alpha)

    def set_grey(self, colour_value: float, alpha: float = 1) -> None:
        colour = Colour(*(colour_value, ) * 3, alpha)
        self.set_colour(colour)

    def set_black(self) -> None:
        self.set_colour(BLACK)

    def set_white(self) -> None:
        self.set_colour(WHITE)

    def set_background(self, colour: Colour) -> None:
        self._context.rectangle(0, 0, self.width, self.height)
        self.set_colour(colour)
        self._context.fill()

    def set_line_cap(self, line_cap: LineCap) -> None:
        self._context.set_line_cap(line_cap.value)

    def set_line_join(self, line_join: LineJoin) -> None:
        self._context.set_line_join(line_join.value)

    def set_fill_rule(self, file_rule: FillRule) -> None:
        self._context.set_fill_rule(file_rule.value)

    # Render methods
    def fill(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.fill()
        else:
            self._context.fill_preserve()

    def stroke(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.stroke()
        else:
            self._context.stroke_preserve()

    def clip(self) -> None:
        self._context.clip()

    def _draw_path(self, path: Iterable[Point], close_path: bool) -> None:
        self._context.new_sub_path()
        for p in path:
            self._context.line_to(*p)
        if close_path:
            self._context.close_path()

    def draw_path(self,
                  path: Iterable[PointType],
                  close_path: bool = False) -> None:
        points = (p if isinstance(p, Point) else Point(*p) for p in path)
        self._draw_path(points, close_path)

    def draw_polygon(self, polygon: Polygon) -> None:
        self._draw_path(polygon.points, close_path=True)

    def draw_circle(self,
                    circle: Circle,
                    fill: bool = False,
                    stroke: bool = True) -> None:
        self._context.new_sub_path()
        self._context.arc(*circle.centre, circle.radius, 0, 2 * pi)

    def write_to_png(self, file_name: str) -> None:
        self._surface.write_to_png(file_name)
                  offset=pitch,
                  strides=[pitch * 3, 1])
    ndB = ndarray(shape=(rows, width),
                  buffer=copybuffer,
                  dtype=ubyte,
                  order='C',
                  offset=2 * pitch,
                  strides=[pitch * 3, 1])
    ndI = ndarray(shape=(rows, width),
                  buffer=I.get_data(),
                  dtype=uint32,
                  order='C',
                  strides=[I.get_stride(), 4])
    # 255 * 2**24 = opaque
    ndI[:, :] = 255 * 2**24 + ndR[:, :] * 2**16 + ndG[:, :] * 2**8 + ndB[:, :]
    I.mark_dirty()

    ctx.set_source_surface(I, 0, 0)
    pattern = ctx.get_source()
    SurfacePattern.set_filter(pattern, FILTER_BEST)
    # Re-use the sane scale (LVD_V taller than LCD),
    # but adjust vertical position to line up mid-height of glyphs
    adjust = (rows - rows_old) * 240.0 / rows
    scalematrix.translate(-400, adjust)
    pattern.set_matrix(scalematrix)
    ctx.paint()
    #
    surface.flush()
    surface.write_to_png("glyph-lcd-cairo.png")
    Image.open("glyph-lcd-cairo.png").show()
Exemple #14
0
                  offset=0,
                  strides=[pitch*3, 1])
    ndG = ndarray(shape=(rows,width), buffer=copybuffer,
                  dtype=ubyte, order='C',
                  offset=pitch,
                  strides=[pitch*3, 1])
    ndB = ndarray(shape=(rows,width), buffer=copybuffer,
                  dtype=ubyte, order='C',
                  offset=2*pitch,
                  strides=[pitch*3, 1])
    ndI = ndarray(shape=(rows,width), buffer=I.get_data(),
                  dtype=uint32, order='C',
                  strides=[I.get_stride(), 4])
    # 255 * 2**24 = opaque
    ndI[:,:] = 255 * 2**24 + ndR[:,:] * 2**16 + ndG[:,:] * 2**8 + ndB[:,:]
    I.mark_dirty()

    ctx.set_source_surface(I, 0, 0)
    pattern = ctx.get_source()
    SurfacePattern.set_filter(pattern, FILTER_BEST)
    # Re-use the sane scale (LVD_V taller than LCD),
    # but adjust vertical position to line up mid-height of glyphs
    adjust = (rows - rows_old) * 240.0 /rows
    scalematrix.translate(-400, adjust)
    pattern.set_matrix(scalematrix)
    ctx.paint()
    #
    surface.flush()
    surface.write_to_png("glyph-lcd-cairo.png")
    Image.open("glyph-lcd-cairo.png").show()
Exemple #15
0
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]
# ndI[...] = (bitmap*(1,2**8,2**16,2**24)).sum(axis=-1)


I.mark_dirty()

surface = ImageSurface(FORMAT_ARGB32, 2*width, rows)
ctx = Context(surface)

ctx.set_source_surface(I, 0, 0)
ctx.paint()

ctx.set_source_surface(I, width/2, 0)
ctx.paint()

ctx.set_source_surface(I, width , 0)
ctx.paint()

surface.write_to_png("emoji-color-cairo.png")
Image.open("emoji-color-cairo.png").show()
                       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)
    ctx.mask(pattern)
    ctx.fill()
    surface.flush()
    surface.write_to_png("glyph-mono+alpha-cairo.png")
    Image.open("glyph-mono+alpha-cairo.png").show()
    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)

ctx.set_source_surface(I, 0, 0)
ctx.paint()

ctx.set_source_surface(I, width/2, 0)
ctx.paint()

ctx.set_source_surface(I, width , 0)
ctx.paint()

surface.write_to_png("emoji-color-cairo.png")
Image.open("emoji-color-cairo.png").show()
        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)
    ctx.mask(pattern)
    ctx.fill()
    surface.flush()
    surface.write_to_png("glyph-mono+alpha-cairo.png")
    Image.open("glyph-mono+alpha-cairo.png").show()
    ctx.set_source_rgb(1, 1, 0)
    ctx.mask(patternF)
    ctx.fill()

    scalematrix.translate(+400, 0)
    patternF.set_matrix(scalematrix)
    ctx.mask(patternF)
    ctx.fill()

    # stroke on top
    ctx.set_source_surface(Z, 0, 0)
    patternZ = ctx.get_source()
    SurfacePattern.set_filter(patternZ, FILTER_BEST)

    scalematrix = Matrix()
    scalematrix.scale(1.0 / scale, 1.0 / scale)
    scalematrix.translate(-(600.0 - widthZ * scale / 2.0), -50)
    patternZ.set_matrix(scalematrix)
    ctx.set_source_rgb(1, 0, 0)
    ctx.mask(patternZ)
    ctx.fill()

    scalematrix.translate(-400, 0)
    patternZ.set_matrix(scalematrix)
    ctx.mask(patternZ)
    ctx.fill()

    surface.flush()
    surface.write_to_png("glyph-color-cairo.png")
    Image.open("glyph-color-cairo.png").show()
    Z = ImageSurface(FORMAT_A8, int(round(height+0.5)), int(round(width+0.5)))
ctx = Context(Z)

if (wantRotate):
    ctx.set_matrix(Matrix(xx=0.0,xy=-1.0,yx=1.0,yy=0.0,x0=height))
# Second pass for actual rendering
x, y = -sc(glyph_extents[0].x_bearing + positions[0].x_offset), height + sc(min_iy)
if (emulate_default):
    x = 16
    y = sc(font_extents.asscender) + 16
if (wantTTB):
    x = sc(max_ix)
    y = sc(max_iy)
for info,pos,extent in zip(infos, positions, glyph_extents):
    face.load_glyph(info.codepoint)
    x += sc(extent.x_bearing + pos.x_offset)
    y -= sc(extent.y_bearing + pos.y_offset)
    # cairo does not like zero-width bitmap from the space character!
    if (face.glyph.bitmap.width > 0):
        glyph_surface = make_image_surface(face.glyph.bitmap)
        ctx.set_source_surface(glyph_surface, x, y)
        ctx.paint()
    x += sc(pos.x_advance - extent.x_bearing - pos.x_offset)
    y -= sc(pos.y_advance - extent.y_bearing - pos.y_offset)
Z.flush()
Z.write_to_png("hb-view.png")
Image.open("hb-view.png").show()

### Derived from freetype-py:examples/hello-world-cairo.py ends.
#####################################################################
        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!
        if (bitmap.width > 0):
            glyph_surface = make_image_surface(face.glyph.bitmap)
            ctx.set_source_surface(glyph_surface, x, y)
            ctx.paint()
        x += (slot.advance.x >> 6)
        previous = c
    Z.flush()
    Z.write_to_png("hello-world-cairo.png")
    Image.open("hello-world-cairo.png").show()
            y0 = H//2 + (random.uniform()-.1)*50
            for dx,dy in spiral():
                c = .25+.75*random.random()
                x = int(x0+dx)
                y = int(y0+dy)
                checked = False
                I.flush()
                if not (x <= w//2 or y <= h//2 or x >= (W-w//2) or y >= (H-h//2)):
                    ndI = ndarray(shape=(h,w), buffer=I.get_data(), dtype=ubyte, order='C',
                                  offset=(x-w//2) + I.get_stride() * (y-h//2),
                                  strides=[I.get_stride(), 1])
                    ndL = ndarray(shape=(h,w), buffer=L.get_data(), dtype=ubyte, order='C',
                                  strides=[L.get_stride(), 1])
                    if ((ndI * ndL).sum() == 0):
                       checked = True
                new_region = RectangleInt(x-w//2, y-h//2, w, h)
                if  (checked or ( drawn_regions.contains_rectangle(new_region) == REGION_OVERLAP_OUT )):
                    ctxI.set_source_surface(L, 0, 0)
                    pattern = ctxI.get_source()
                    scalematrix = Matrix()
                    scalematrix.scale(1.0,1.0)
                    scalematrix.translate(w//2 - x, h//2 - y)
                    pattern.set_matrix(scalematrix)
                    ctxI.set_source_rgba(c,c,c,c)
                    ctxI.mask(pattern)
                    drawn_regions.union(new_region)
                    break
    I.flush()
    I.write_to_png("wordle-cairo.png")
    Image.open("wordle-cairo.png").show()
    ctx.set_source_rgb (1 , 1, 0)
    ctx.mask(patternF)
    ctx.fill()

    scalematrix.translate(+400,0)
    patternF.set_matrix(scalematrix)
    ctx.mask(patternF)
    ctx.fill()

    # stroke on top
    ctx.set_source_surface(Z, 0, 0)
    patternZ = ctx.get_source()
    SurfacePattern.set_filter(patternZ, FILTER_BEST)

    scalematrix = Matrix()
    scalematrix.scale(1.0/scale,1.0/scale)
    scalematrix.translate(-(600.0 - widthZ *scale /2.0 ), -50)
    patternZ.set_matrix(scalematrix)
    ctx.set_source_rgb (1 , 0, 0)
    ctx.mask(patternZ)
    ctx.fill()

    scalematrix.translate(-400,0)
    patternZ.set_matrix(scalematrix)
    ctx.mask(patternZ)
    ctx.fill()

    surface.flush()
    surface.write_to_png("glyph-color-cairo.png")
    Image.open("glyph-color-cairo.png").show()
Exemple #24
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)
Exemple #25
0
    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()