예제 #1
0
    def __init__(self, size, *args, **kwargs):
        super().__init__()
        self._width = size[0]
        self._height = size[1]
        self.pix_format = kwargs.get('pix_format', 'bgra32')

        shape = (self._height, self._width, 4)
        buffer = np.zeros(shape, dtype=np.uint8)
        canvas_klass = pix_format_canvases[self.pix_format]
        self.gc = canvas_klass(buffer, bottom_up=True)
        self.marker_gc = MarkerRenderer(
            buffer, pix_format=self.pix_format, bottom_up=True
        )

        # init the state variables
        clip = agg.Rect(0, 0, self._width, self._height)
        self.canvas_state = agg.GraphicsState(clip_box=clip)
        self.stroke_paint = agg.SolidPaint(0.0, 0.0, 0.0)
        self.fill_paint = agg.SolidPaint(0.0, 0.0, 0.0)
        self.path = CompiledPath()
        self.text_transform = agg.Transform()
        self.text_pos = (0.0, 0.0)
        self.transform = agg.Transform()
        self.font = None
        self.__state_stack = []

        # For HiDPI support
        self.base_scale = kwargs.pop('base_pixel_scale', 1)
        self.transform.scale(self.base_scale, self.base_scale)

        # Make this look like a kiva.agg GC
        self.bmp_array = buffer
예제 #2
0
def interpret_color(value, context):
    color = parse_color(value)
    if color is not None:
        return agg.SolidPaint(*color)
    elif value.lower() == 'none':
        return None
    elif value.startswith('url'):
        match = re.match(r'url\(#(?P<label>\w+)\)', value)
        if match is None:
            return None
        obj = context.get(match.group('label'))
        if obj is None or 'type' not in obj:
            return None
        if obj['type'] == 'linearGradient':
            grad = agg.LinearGradientPaint(
                obj['x1'], obj['y1'], obj['x2'], obj['y2'], obj['stops'],
                obj.get('spreadMethod', agg.GradientSpread.SpreadPad),
                obj.get('gradientUnits', agg.GradientUnits.ObjectBoundingBox))
            grad.transform = obj.get('gradientTransform', agg.Transform())
            return grad
        if obj['type'] == 'radialGradient':
            grad = agg.RadialGradientPaint(
                obj['cx'], obj['cy'], obj['r'], obj['fx'], obj['fy'],
                obj['stops'],
                obj.get('spreadMethod', agg.GradientSpread.SpreadPad),
                obj.get('gradientUnits', agg.GradientUnits.ObjectBoundingBox))
            grad.transform = obj.get('gradientTransform', agg.Transform())
            return grad
예제 #3
0
def parse_transform(value):
    def rotate(deg):
        t = agg.Transform()
        t.rotate(deg * np.pi / 180)
        return t

    def scale(*s):
        sx = s[0]
        sy = sx if len(s) == 1 else s[1]
        return agg.Transform(sx, 0.0, 0.0, sy, 0.0, 0.0)

    def translate(*t):
        tx = t[0]
        ty = 0.0 if len(t) == 1 else t[1]
        return agg.Transform(1.0, 0.0, 0.0, 1.0, tx, ty)

    FUNCTIONS = {
        'matrix': agg.Transform,
        'translate': translate,
        'rotate': rotate,
        'scale': scale,
        'skewX': lambda s: agg.Transform(1.0, 0.0, s, 1.0, 0.0, 0.0),
        'skewY': lambda s: agg.Transform(1.0, s, 0.0, 1.0, 0.0, 0.0),
    }
    match = re.match(r'(?P<func>\w+)\((?P<args>[0-9.,-e]+)\)', value)
    if match is None:
        return None

    func = FUNCTIONS.get(match.group('func'), lambda *a: None)
    args = match.group('args')
    args = [float(a) for a in args.split(',')]
    return func(*args)
예제 #4
0
    def show_text(self, text, point=None):
        """ Draw text on the device at current text position.

            This is also used for showing text at a particular point
            specified by x and y.
        """
        if self.font is None:
            raise RuntimeError("show_text called before setting a font!")

        if point is None:
            pos = tuple(self.text_pos)
        else:
            pos = tuple(point)

        transform = agg.Transform()
        transform.multiply(self.transform)
        transform.translate(*pos)

        self.gc.draw_text(
            text,
            self.font,
            transform,
            self.canvas_state,
            fill=self.fill_paint,
            stroke=self.stroke_paint,
        )
예제 #5
0
def sky(width, height, canvas, gs):
    def rcolor():
        return hsv2rgb(.55 + randneghalf2half() * .25,
                       .6 + randneghalf2half() * .125,
                       .25 + randneghalf2half() * .125)

    transform = agg.Transform()
    starpaint = agg.SolidPaint(*hsv2rgb(.165, .96, .99))
    starshape = agg.Path()
    angles = np.linspace(0, 2 * np.pi, num=5, endpoint=False)
    pts = np.stack([np.cos(angles), np.sin(angles)]).T * 7
    starshape.lines([pts[i] for i in (0, 2, 4, 1, 3)])
    starshape.close()

    bgshape = agg.Path()
    bgshape.rect(0, 0, width, height)
    bgpaint = agg.LinearGradientPaint(0, 0, 0, height,
                                      randgradstops(2, rcolor),
                                      agg.GradientSpread.SpreadReflect,
                                      agg.GradientUnits.UserSpace)
    canvas.draw_shape(bgshape, transform, gs, fill=bgpaint)

    star_count = 40
    xs = np.random.rand(star_count) * width
    ys = np.random.rand(star_count) * height
    for x, y in zip(xs, ys):
        transform.reset()
        transform.translate(x, y)
        canvas.draw_shape(starshape, transform, gs, fill=starpaint)
예제 #6
0
파일: celiagg.py 프로젝트: tylott/enable
    def concat_ctm(self, transform):
        """ Concatenate the transform to current coordinate transform matrix.

            transform:affine_matrix -- the transform matrix to concatenate with
                                       the current coordinate matrix.
        """
        self.transform.premultiply(agg.Transform(*transform))
예제 #7
0
def spiral(size, hue, sat, val):
    canvas = agg.CanvasRGB24(np.zeros((size[1], size[0], 3), dtype=np.uint8))
    gs = agg.GraphicsState(drawing_mode=agg.DrawingMode.DrawFill)
    transform = agg.Transform()
    circle = agg.Path()
    circle.ellipse(0, 0, CIRCLE_SIZE, CIRCLE_SIZE)

    divisions = np.linspace(0, 2*np.pi, CIRCLE_COUNT, endpoint=False)
    centers = np.stack((np.cos(divisions), np.sin(divisions)), axis=1)
    offsets = compute_offsets(np.sqrt(size[0]**2 + size[1]**2) / 2)
    color_count = len(offsets)

    hsv = np.ones((color_count, 1, 3))
    hsv[:, 0, 0] = np.linspace(hue[0], hue[1], color_count, endpoint=False)
    hsv[:, 0, 1] = np.linspace(sat[0], sat[1], color_count, endpoint=False)
    hsv[:, 0, 2] = np.linspace(val[0], val[1], color_count, endpoint=False)
    spectrum = hsv2rgb(hsv).reshape(color_count, 3)

    for idx, offset in enumerate(offsets):
        paint = agg.SolidPaint(*spectrum[idx])
        radius = np.pi * offset / CIRCLE_COUNT
        scale = radius / CIRCLE_SIZE
        for i in range(CIRCLE_COUNT):
            if ((idx + i) % 2) == 0:
                continue
            transform.reset()
            transform.translate(size[0]/2 + offset*centers[i, 0],
                                size[1]/2 + offset*centers[i, 1])
            transform.scale(scale, scale)
            canvas.draw_shape(circle, transform, gs, fill=paint)

    imsave('spiral.png', canvas.array)
예제 #8
0
파일: celiagg.py 프로젝트: tylott/enable
    def draw_rect(self, rect, mode=constants.FILL_STROKE):
        """ Draw a rect.
        """

        # XXX: kiva::graphics_context<>::_draw_rect_simple() does a VERY
        # specific optimization for drawing rectangles in certain circumstances
        # which results in chaco plot borders which are sharp.
        # This implements that same special case.  - JW 2018/09/01
        transform = self.transform
        if (not self.canvas_state.anti_aliased
                and self.canvas_state.line_width in (0.0, 1.0)
                and fabs(self.transform.shx) < 1e-3
                and fabs(self.transform.shy) < 1e-3):
            scale_x = self.transform.sx
            scale_y = self.transform.sy
            tx = self.transform.tx
            ty = self.transform.ty
            x1 = int(rect[0] * scale_x + tx)
            y1 = int(rect[1] * scale_y + ty)
            x2 = int((rect[0] + rect[2]) * scale_x + tx)
            y2 = int((rect[1] + rect[3]) * scale_y + ty)
            rect = (x1, y1, abs(x2 - x1), abs(y2 - y1))
            # XXX: The base transform is a half-pixel translate
            transform = agg.Transform(tx=0.5, ty=0.5)

        path = agg.Path()
        path.rect(*rect)

        self.canvas_state.drawing_mode = draw_modes[mode]
        self.gc.draw_shape(path,
                           transform,
                           self.canvas_state,
                           stroke=self.stroke_paint,
                           fill=self.fill_paint)
예제 #9
0
def test_bad_method_args():
    canvas = agg.CanvasG8(np.zeros((1, 1), dtype=np.uint8))
    pix_format = agg.PixelFormat.Gray8
    gs = agg.GraphicsState()
    path = agg.Path()
    transform = agg.Transform()

    with pytest.raises(TypeError):
        canvas.draw_image(None, pix_format, transform, gs)
    with pytest.raises(TypeError):
        canvas.draw_image(canvas.array, None, transform, gs)
    with pytest.raises(TypeError):
        canvas.draw_image(canvas.array, pix_format, None, gs)
    with pytest.raises(TypeError):
        canvas.draw_image(canvas.array, pix_format, transform, None)
    # But this version should work
    canvas.draw_image(canvas.image, None, transform, gs)

    with pytest.raises(TypeError):
        canvas.draw_shape(None, transform, gs)
    with pytest.raises(TypeError):
        canvas.draw_shape(path, None, gs)
    with pytest.raises(TypeError):
        canvas.draw_shape(path, transform, None)

    text = "Hello!"
    font = agg.Font("Times New Roman", 12.0, agg.FontCacheType.RasterFontCache)
    with pytest.raises(TypeError):
        canvas.draw_text(text, None, transform, gs)
    with pytest.raises(TypeError):
        canvas.draw_text(text, font, None, gs)
    with pytest.raises(TypeError):
        canvas.draw_text(text, font, transform, None)
예제 #10
0
파일: draw.py 프로젝트: zplab/zplib
def draw_mask(image_shape, geometry, antialias=False):
    """Draw a mask (0-255) from a given celiagg path. Requires celiagg installed.

    Note: to produce a True/False mask from the output, simply do the following:
        mask = draw_mask(image_shape, geometry)
        bool_mask = mask > 0

    Parameters:
        image_shape: shape of the resulting image
        geometry: celiagg VertexSource class, such as celiagg.Path or
            celiagg.BSpline, containing geometry to draw
        antialias: if False (default), output contains only 0 and 255. If True,
            output will be antialiased (better for visualization).

    Returns: mask array of dtype numpy.uint8
    """
    import celiagg
    image = numpy.zeros(image_shape, dtype=numpy.uint8, order='F')
    # NB celiagg uses (h, w) C-order convention for image shapes, so give it the transpose
    canvas = celiagg.CanvasG8(image.T)
    state = celiagg.GraphicsState(drawing_mode=celiagg.DrawingMode.DrawFill, anti_aliased=antialias)
    fill = celiagg.SolidPaint(1,1,1)
    transform = celiagg.Transform()
    canvas.draw_shape(geometry, transform, state, fill=fill)
    return image
예제 #11
0
def test_stencil_size_mismatch():
    canvas = agg.CanvasRGB24(np.zeros((4, 5, 3), dtype=np.uint8))
    stencil_canvas = agg.CanvasG8(np.zeros((1, 2), dtype=np.uint8))
    gs = agg.GraphicsState(stencil=stencil_canvas.image)
    path = agg.Path()
    transform = agg.Transform()

    with pytest.raises(agg.AggError):
        canvas.draw_shape(path, transform, gs)
예제 #12
0
def test_no_text_draw_text_failure():
    if agg.HAS_TEXT:
        return

    buffer = np.zeros((1, 1), dtype=np.uint8)
    canvas = agg.CanvasG8(buffer)
    transform = agg.Transform()
    line_paint = agg.SolidPaint(1.0, 1.0, 1.0)
    gs = agg.GraphicsState()

    with pytest.raises(RuntimeError):
        canvas.draw_text("", None, transform, line_paint, line_paint, gs)
예제 #13
0
파일: celiagg.py 프로젝트: tylott/enable
    def __init__(self, size, *args, **kwargs):
        super(GraphicsContext, self).__init__()
        self._width = size[0]
        self._height = size[1]
        self.pix_format = kwargs.get('pix_format', 'rgba32')

        shape = (self._height, self._width, 4)
        canvas_klass = pix_format_canvases[self.pix_format]
        self.gc = canvas_klass(np.zeros(shape, dtype=np.uint8), bottom_up=True)

        # init the state variables
        clip = agg.Rect(0, 0, self._width, self._height)
        self.canvas_state = agg.GraphicsState(clip_box=clip)
        self.stroke_paint = agg.SolidPaint(0.0, 0.0, 0.0)
        self.fill_paint = agg.SolidPaint(0.0, 0.0, 0.0)
        self.path = CompiledPath()
        self.text_transform = agg.Transform()
        self.text_pos = (0.0, 0.0)
        self.transform = agg.Transform()
        self.font = None
        self.__state_stack = []
예제 #14
0
    def draw_image(self, img, rect=None):
        """
        img is either a N*M*3 or N*M*4 numpy array, or a PIL Image

        rect - a tuple (x, y, w, h)
        """
        from PIL import Image

        def normalize_image(img):
            if not img.mode.startswith('RGB'):
                img = img.convert('RGB')

            if img.mode == 'RGB':
                return img, agg.PixelFormat.RGB24
            elif img.mode == 'RGBA':
                return img, agg.PixelFormat.RGBA32

        img_format = agg.PixelFormat.RGB24
        if isinstance(img, np.ndarray):
            # Numeric array
            img = Image.fromarray(img)
            img, img_format = normalize_image(img)
            img_array = np.array(img)
        elif isinstance(img, Image.Image):
            img, img_format = normalize_image(img)
            img_array = np.array(img)
        elif isinstance(img, GraphicsContext):
            img_array = img.gc.array
            img_format = pix_formats[img.pix_format]
        elif hasattr(img, 'bmp_array'):
            # An offscreen kiva.agg context
            # XXX: Use a copy to kill the read-only flag which plays havoc
            # with the Cython memoryviews used by celiagg
            img = Image.fromarray(img.bmp_array)
            img, img_format = normalize_image(img)
            img_array = np.array(img)
        else:
            msg = "Cannot render image of type '{}' into celiagg context."
            warnings.warn(msg.format(type(img)))
            return

        x, y, w, h = rect
        img_height, img_width = img_array.shape[:2]
        sx, sy = w / img_width, h / img_height
        transform = agg.Transform()
        transform.multiply(self.transform)
        transform.translate(x, y)
        transform.scale(sx, sy)

        self.gc.draw_image(
            img_array, img_format, transform, self.canvas_state, bottom_up=True
        )
예제 #15
0
def render(context, scale=1.0):
    docattrs = context['__document__']
    width = parse_united(docattrs.get('width', '100')) * scale
    height = parse_united(docattrs.get('height', '100')) * scale
    canvas = agg.CanvasRGB24(
        np.empty((int(height), int(width), 3), dtype=np.uint8))
    canvas.clear(1, 1, 1)
    for group in context['graphics']:
        for elem in group.values():
            transform = elem.get('transform') or agg.Transform()
            shape = elem['data']
            gs, stroke, fill = interpret_style(elem['style'], context)
            transform.scale(scale, scale)
            canvas.draw_shape(shape, transform, gs, stroke=stroke, fill=fill)
    return canvas.array
예제 #16
0
파일: celiagg.py 프로젝트: tylott/enable
    def draw_image(self, img, rect=None):
        """
        img is either a N*M*3 or N*M*4 numpy array, or a Kiva image

        rect - a tuple (x, y, w, h)
        """
        def get_format(array):
            if array.shape[2] == 3:
                return agg.PixelFormat.RGB24
            elif array.shape[2] == 4:
                return agg.PixelFormat.RGBA32

        img_format = agg.PixelFormat.RGB24
        if isinstance(img, np.ndarray):
            # Numeric array
            img_array = img.astype(np.uint8)
            img_format = get_format(img_array)
        elif isinstance(img, GraphicsContext):
            img_array = img.gc.array
            img_format = pix_formats[img.pix_format]
        elif hasattr(img, 'bmp_array'):
            # An offscreen kiva context
            # XXX: Use a copy to kill the read-only flag which plays havoc
            # with the Cython memoryviews used by celiagg
            img_array = img.bmp_array.copy()
            img_format = get_format(img_array)
        else:
            msg = "Cannot render image of type '{}' into celiagg context."
            warnings.warn(msg.format(type(img)))
            return

        x, y, w, h = rect
        img_height, img_width = img_array.shape[:2]
        sx, sy = w / img_width, h / img_height
        transform = agg.Transform()
        transform.multiply(self.transform)
        transform.translate(x, y)
        transform.scale(sx, sy)

        self.gc.draw_image(img_array,
                           img_format,
                           transform,
                           self.canvas_state,
                           bottom_up=True)
예제 #17
0
def draw_horizon(xs, ys, canvas, gs):
    def rcolor():
        return hsv2rgb(.125 + randneghalf2half() * .25,
                       .6 + randneghalf2half() * .4,
                       .6 + randneghalf2half() * .4)

    width = xs[-1]
    path = agg.Path()
    path.move_to(0, 0)
    path.line_to(xs[0], ys[0])
    for x, y in zip(xs[1:], ys[1:]):
        path.line_to(x, y)
    path.line_to(width, 0)
    path.close()

    transform = agg.Transform()
    fill = agg.LinearGradientPaint(0, 0, width, 0, randgradstops(2, rcolor),
                                   agg.GradientSpread.SpreadReflect,
                                   agg.GradientUnits.UserSpace)
    canvas.draw_shape(path, transform, gs, fill=fill)
예제 #18
0
import pathlib
import pickle
import numpy

import celiagg
import freeimage
from zplib.curve import spline_geometry
from zplib.curve import interpolate
from zplib.image import resample

AGG_STATE = celiagg.GraphicsState(anti_aliased=False)
AGG_PAINT = celiagg.SolidPaint(1, 1, 1)
AGG_TRANSFORM = celiagg.Transform()
AGG_TRANSPARENT = celiagg.SolidPaint(0, 0, 0, 0)


def write_xy_positions(filename, positions):
    position_lines = ['{}\t{}'.format(x, y) for x, y in positions]
    with open(filename, 'w') as f:
        f.write('\n'.join(position_lines))


def save_centerline(metadata, centerline_file):
    spine_tck = metadata['spine_tck']
    positions = interpolate.spline_interpolate(spine_tck, 50)
    write_xy_positions(centerline_file, positions)


def save_landmarks(metadata, landmark_file):
    spine_tck = metadata['spine_tck']
    vulva_t = metadata['vulva_t']
예제 #19
0
import numpy as np
from skimage.io import imsave

import celiagg as agg

SIZE = 1000

order = (2, 4, 1, 3, 0)
angles = np.linspace(0, 2 * np.pi, num=5, endpoint=False)
pts = np.stack([np.cos(angles), np.sin(angles)]).T * SIZE / 2 + SIZE / 2
star_shape = agg.Path()
star_shape.lines([pts[i] for i in (0, 2, 4, 1, 3)])
star_shape.close()
star_transform = agg.Transform()
star_transform.translate(SIZE / 2, SIZE / 2)
star_transform.rotate(-np.pi / 2)
star_transform.translate(-SIZE / 2, -SIZE / 2)

big_box = agg.Path()
big_box.rect(0, 0, SIZE, SIZE)
small_box = agg.Path()
small_box.rect(0, 0, SIZE / 2, SIZE / 2)

stencil_canvas = agg.CanvasG8(np.zeros((SIZE, SIZE), dtype=np.uint8))
canvas = agg.CanvasRGB24(np.zeros((SIZE, SIZE, 3), dtype=np.uint8))
gs = agg.GraphicsState(drawing_mode=agg.DrawingMode.DrawFill, line_width=6.0)
transform = agg.Transform()
blue_paint = agg.SolidPaint(0.1, 0.1, 1.0)
white_paint = agg.SolidPaint(1.0, 1.0, 1.0)
stops = ((0.0, 0.0, 0.0, 0.0, 1.0), (1.0, 0.3, 0.3, 0.75, 1.0))
bw_grad = agg.LinearGradientPaint(0, 0, 2, 5, stops,
예제 #20
0
def transform():
    return agg.Transform()
예제 #21
0
import celiagg as agg
import numpy as np
from skimage.io import imsave

canvas = agg.CanvasRGB24(np.ones((400, 400, 3), dtype=np.uint8))
state = agg.GraphicsState(drawing_mode=agg.DrawingMode.DrawStroke,
                          line_width=10.0)
transform = agg.Transform()
red_paint = agg.SolidPaint(1.0, 0.0, 0.0)
black_paint = agg.SolidPaint(0.0, 0.0, 0.0)
font = agg.Font("/Library/Fonts/Verdana.ttf", 96.0,
                agg.FontCacheType.RasterFontCache)
path = agg.Path()
path.ellipse(200, 200, 190, 190)
canvas.clear(1.0, 1.0, 1.0)
canvas.draw_shape(path, transform, state, stroke=red_paint)
transform.translate(30.0, 220.0)
canvas.draw_text("celiagg", font, transform, state, stroke=black_paint)

imsave("example.png", canvas.array)
예제 #22
0
 def translate(*t):
     tx = t[0]
     ty = 0.0 if len(t) == 1 else t[1]
     return agg.Transform(1.0, 0.0, 0.0, 1.0, tx, ty)
예제 #23
0
 def scale(*s):
     sx = s[0]
     sy = sx if len(s) == 1 else s[1]
     return agg.Transform(sx, 0.0, 0.0, sy, 0.0, 0.0)
예제 #24
0
 def rotate(deg):
     t = agg.Transform()
     t.rotate(deg * np.pi / 180)
     return t