Esempio n. 1
0
def _tonumpy(surface: cairo.ImageSurface):
    np_image = np.ndarray(
        shape=(surface.get_height(), surface.get_width(), 4),
        dtype=np.uint8,
        buffer=surface.get_data(),
        strides=(surface.get_width() * 4, 4, 1)
    )
    np_image = np_image[:, :, :-1]
    np_image = np_image[:, :, ::-1]
    np_image = np_image.copy()
    return np_image
Esempio n. 2
0
def _cairo_surface_write_to_bmp(img: cairo.ImageSurface) -> bytes:

    data = bytes(img.get_data())
    return (
        b"BM"
        + struct.pack(
            "<ihhiiiihhiiiiii",
            54 + len(data),  # size of BMP file
            0,  # unused
            0,  # unused
            54,  # pixel array offset
            40,  # DIB header
            img.get_width(),  # width
            img.get_height(),  # height
            1,  # planes
            32,  # BPP
            0,  # no compression
            len(data),  # size of the raw bitmap data
            2835,  # 72DPI H
            2835,  # 72DPI V
            0,  # palette
            0,  # all colors are important
        )
        + data
    )
Esempio n. 3
0
def getMatrix(x: int, y: int, surf: cairo.ImageSurface):
    sx = surf.get_width() / 8.5 / 25.4
    sy = surf.get_height() / 11 / 25.4

    x0 = (origin[0] + deltaX * x) * sx
    y0 = (origin[1] + deltaY * y) * sy
    return cairo.Matrix(x0=x0, y0=y0, xx=sx, yy=sy)
Esempio n. 4
0
def _surface_to_array(surface: cairo.ImageSurface) -> np.ndarray:
    """convert surface to array"""

    # NOTE! The format of the array is PREMULTIPLIED ALPHA, not RGBA!
    res = np.ndarray(
        (surface.get_height(), surface.get_width(),
         4),  # do height and width work here???
        dtype=np.uint8,
        buffer=surface.get_data())
    res = res[:, :, [2, 1, 0, 3]]  # swap RGB order like OpenCV
    return res
Esempio n. 5
0
    def draw_frame(self, target: cairo.ImageSurface):
        ctx = cairo.Context(target)
        ctx.set_source_rgba(0.92, 0.72, 1, 0.3)
        w, h = target.get_width(), target.get_height()

        projection = np.dot(numgl.perspective(90, w / h, 0.1, 5),
                            self.camera())

        clip = pygl.transform(projection, self.positions)
        screen = pygl.get_screen(clip, (w, h))

        for x, y, _ in screen:
            ctx.move_to(x, y)
            ctx.arc(x, y, 1, 0, TAU)
            ctx.fill()
Esempio n. 6
0
def motionblur(target: cairo.ImageSurface, t: float, draw: Callable, look_ahead: float, n: int):
    w = target.get_width()
    h = target.get_width()
    frames = []
    for tt in np.linspace(0, look_ahead, n):
        frame = np.zeros((w * h * 4,), dtype=np.uint8)
        surface = cairo.ImageSurface.create_for_data(memoryview(frame), cairo.Format.RGB24, w, h)
        draw(surface, t + tt)
        #frames.append(degamma(frame))
        frames.append(frame)

    avg = np.average(np.stack(frames), axis=0).astype(np.uint8)
    #avg = gamma(np.average(np.stack(frames), axis=0)).astype(np.uint8)
    data = target.get_data()
    for i in range(len(data)):
        data[i] = avg[i]
Esempio n. 7
0
    def draw(self, target: cairo.ImageSurface):
        saved = self.positions, self.t

        n = 4
        lookahead = 0.2
        dt = lookahead / n

        targets = []
        for _ in range(n):
            image = cairo.ImageSurface(cairo.Format.RGB24, target.get_width(),
                                       target.get_height())
            self.draw_frame(image)
            targets.append(image)
            self.step(dt)

        data = target.get_data()
        for i in range(len(data)):
            data[i] = int(sum(img.get_data()[i] for img in targets) / n)

        self.positions, self.t = saved
Esempio n. 8
0
def clear(target: cairo.ImageSurface, color=(1, 1, 1)) -> None:
    r, g, b = color
    ctx = cairo.Context(target)
    ctx.rectangle(0, 0, target.get_width(), target.get_height())
    ctx.set_source_rgb(r, g, b)
    ctx.fill()
Esempio n. 9
0
def clear(target: cairo.ImageSurface, color: Color=Color.WHITE) -> None:
    ctx = cairo.Context(target)
    ctx.rectangle(0, 0, target.get_width(), target.get_height())
    ctx.set_source_rgb(color.r, color.g, color.b)
    ctx.fill()
Esempio n. 10
0
def resolution(surface: cairo.ImageSurface) -> Resolution:
    return surface.get_width(), surface.get_height()
Esempio n. 11
0
def downloadOSMMap(west, south, east, north, zoom, mapType=None):
    """
    Download OSM map of selected area.

    Original was found on https://smyt.ru/blog/statc-osm-map-with-python/
    Map may be download from few different OSM tile servers with different zoom.
    Download speed depends on size of selected area.

    Parameters
    ----------
    weast,south,east,north : float
        coordinates of borders of map

    zoom : int
        map zoom, changes map detail

    mapType : {'white', 'dark', 'toner', None}, optional
        type of OSM tile server, default is None
        None - regular OSM map
        white, dark - white or dark cartodb OSM map
        toner - stamen toner OSM map

    Returns
    -------
    numpy.array
        background map of selected area
    """

    tiles = list(mercantile.tiles(west, south, east, north, zoom))

    min_x = min([t.x for t in tiles])
    min_y = min([t.y for t in tiles])
    max_x = max([t.x for t in tiles])
    max_y = max([t.y for t in tiles])

    tile_size = (256, 256)
    map_image = ImageSurface(
        FORMAT_ARGB32,
        tile_size[0] * (max_x - min_x + 1),
        tile_size[1] * (max_y - min_y + 1),
    )

    ctx = Context(map_image)

    def getTileUrl(mapType, zoom, x, y):
        if mapType == None:
            server = random.choice(["a", "b", "c"])
            return "http://{server}.tile.openstreetmap.org/{zoom}/{x}/{y}.png".format(
                server=server, zoom=zoom, x=x, y=y)

        if mapType == "white":
            return "http://cartodb-basemaps-1.global.ssl.fastly.net/light_all/{zoom}/{x}/{y}.png".format(
                zoom=zoom, x=x, y=y)

        if mapType == "dark":
            return "http://cartodb-basemaps-2.global.ssl.fastly.net/dark_all/{zoom}/{x}/{y}.png".format(
                zoom=zoom, x=x, y=y)

        if mapType == "toner":
            return "http://a.tile.stamen.com/toner/{zoom}/{x}/{y}.png".format(
                zoom=zoom, x=x, y=y)

    for t in tiles:
        headers = {
            "User-Agent":
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3"
        }

        url = getTileUrl(mapType, t.z, t.x, t.y)
        req = Request(url, headers=headers)
        response = urlopen(req)

        img = ImageSurface.create_from_png(io.BytesIO(response.read()))

        ctx.set_source_surface(img, (t.x - min_x) * tile_size[0],
                               (t.y - min_y) * tile_size[0])
        ctx.paint()

    bounds = {
        "left": min([mercantile.xy_bounds(t).left for t in tiles]),
        "right": max([mercantile.xy_bounds(t).right for t in tiles]),
        "bottom": min([mercantile.xy_bounds(t).bottom for t in tiles]),
        "top": max([mercantile.xy_bounds(t).top for t in tiles]),
    }

    kx = map_image.get_width() / (bounds["right"] - bounds["left"])
    ky = map_image.get_height() / (bounds["top"] - bounds["bottom"])

    left_top = mercantile.xy(west, north)
    right_bottom = mercantile.xy(east, south)
    offset_left = (left_top[0] - bounds["left"]) * kx
    offset_top = (bounds["top"] - left_top[1]) * ky
    offset_right = (bounds["right"] - right_bottom[0]) * kx
    offset_bottom = (right_bottom[1] - bounds["bottom"]) * ky

    result_width = map_image.get_width() - int(offset_left + offset_right)
    result_height = map_image.get_height() - int(offset_top + offset_bottom)

    map_image_clipped = ImageSurface(FORMAT_ARGB32, result_width,
                                     result_height)

    ctx = Context(map_image_clipped)
    ctx.set_source_surface(map_image, -offset_left, -offset_top)
    ctx.paint()

    def surface_to_npim(surface):
        """ Transforms a Cairo surface into a numpy array. """
        im = +np.frombuffer(surface.get_data(), np.uint8)
        H, W = surface.get_height(), surface.get_width()
        im.shape = (H, W, 4)  # for RGBA
        return im[:, :, :3]

    return surface_to_npim(map_image_clipped)