Exemplo n.º 1
0
def save_as_png(surface, filename, *rect, **kwargs):
    alpha = kwargs['alpha']
    feedback_cb = kwargs.get('feedback_cb', None)
    write_legacy_png = kwargs.get("write_legacy_png", True)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h = rect
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, 1, 1

    # calculate bounding box in full tiles
    render_tx = x/N
    render_ty = y/N
    render_tw = (x+w-1)/N - render_tx + 1
    render_th = (y+h-1)/N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = numpy.empty((1*N, render_tw*N, 4), 'uint8') # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:,x-render_tx*N:x-render_tx*N+w,:]

    first_row = render_ty
    last_row = render_ty+render_th-1

    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty+render_th):
            skip_rendering = False
            if kwargs.get('single_tile_pattern', False):
                # optimization for simple background patterns (e.g. solid color)
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:,tx_rel*N:(tx_rel+1)*N,:]
                if not skip_rendering:
                    surface.blit_tile_into(dst, alpha, render_tx+tx_rel, ty)

                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y+h-ty*N,:,:]
            if ty == first_row:
                res = res[y-render_ty*N:,:,:]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)
Exemplo n.º 2
0
def save_as_png(surface, filename, *rect, **kwargs):
    alpha = kwargs['alpha']
    feedback_cb = kwargs.get('feedback_cb', None)
    write_legacy_png = kwargs.get("write_legacy_png", True)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h = rect
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, 1, 1

    # calculate bounding box in full tiles
    render_tx = x / N
    render_ty = y / N
    render_tw = (x + w - 1) / N - render_tx + 1
    render_th = (y + h - 1) / N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = numpy.empty((1 * N, render_tw * N, 4), 'uint8')  # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:, x - render_tx * N:x - render_tx * N + w, :]

    first_row = render_ty
    last_row = render_ty + render_th - 1

    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty + render_th):
            skip_rendering = False
            if kwargs.get('single_tile_pattern', False):
                # optimization for simple background patterns (e.g. solid color)
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
                if not skip_rendering:
                    surface.blit_tile_into(dst, alpha, render_tx + tx_rel, ty)

                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y + h - ty * N, :, :]
            if ty == first_row:
                res = res[y - render_ty * N:, :, :]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)
Exemplo n.º 3
0
def save_as_png(surface, filename, *rect, **kwargs):
    alpha = kwargs['alpha']
    feedback_cb = kwargs.get('feedback_cb', None)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h, = rect
    assert x % N == 0 and y % N == 0, 'only saving of full tiles is implemented (for now)'
    assert w % N == 0 and h % N == 0, 'only saving of full tiles is implemented (for now)'
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, N, N

    if alpha:
        bpp = 4
    else:
        bpp = 3
    arr = numpy.empty((N, w, bpp), 'uint8')

    tn_ref = [
        0
    ]  # is there a nicer way of letting callbacks in swig code increment this?
    ty_list = range(y / N, (y + h) / N)

    def render_tile_scanline():
        ty = ty_list.pop(0)
        for tx_rel in xrange(w / N):
            # OPTIMIZE: shortcut for empty tiles (not in tiledict)?
            dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
            surface.blit_tile_into(dst, x / N + tx_rel, ty)
            if feedback_cb is not None and tn_ref[0] % TILES_PER_CALLBACK == 0:
                feedback_cb()
            tn_ref[0] += 1
        return arr

    if kwargs.get('single_tile_pattern', False):
        render_tile_scanline()

        def render_tile_scanline():
            return arr

    filename_sys = filename.encode(sys.getfilesystemencoding(
    ))  # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanline)
Exemplo n.º 4
0
def save_as_png(surface, filename, *rect, **kwargs):
    alpha = kwargs['alpha']
    feedback_cb = kwargs.get('feedback_cb', None)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h, = rect
    assert x % N == 0 and y % N == 0, 'only saving of full tiles is implemented (for now)'
    assert w % N == 0 and h % N == 0, 'only saving of full tiles is implemented (for now)'
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, N, N

    if alpha:
        bpp = 4
    else:
        bpp = 3
    arr = numpy.empty((N, w, bpp), 'uint8')

    tn_ref = [0]   # is there a nicer way of letting callbacks in swig code increment this?
    ty_list = range(y/N, (y+h)/N)

    def render_tile_scanline():
        ty = ty_list.pop(0)
        for tx_rel in xrange(w/N):
            # OPTIMIZE: shortcut for empty tiles (not in tiledict)?
            dst = arr[:,tx_rel*N:(tx_rel+1)*N,:]
            surface.blit_tile_into(dst, x/N+tx_rel, ty)
            if feedback_cb is not None and tn_ref[0] % TILES_PER_CALLBACK == 0:
                feedback_cb()
            tn_ref[0] += 1
        return arr

    if kwargs.get('single_tile_pattern', False):
        render_tile_scanline()
        def render_tile_scanline():
            return arr

    filename_sys = filename.encode(sys.getfilesystemencoding()) # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha, render_tile_scanline)
Exemplo n.º 5
0
def save_as_png(surface, filename, *rect, **kwargs):
    """Saves a surface to a file in PNG format"""
    # TODO: Document keyword params and their meanings, mentioning that
    # TODO:  some are processed and removed here, and that others are
    # TODO:  passed to blit_tile_into().
    alpha = kwargs.pop('alpha', False)
    feedback_cb = kwargs.pop('feedback_cb', None)
    write_legacy_png = kwargs.pop("write_legacy_png", True)
    single_tile_pattern = kwargs.pop("single_tile_pattern", False)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h = rect
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, 1, 1

    # calculate bounding box in full tiles
    render_tx = x / N
    render_ty = y / N
    render_tw = (x + w - 1) / N - render_tx + 1
    render_th = (y + h - 1) / N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = numpy.empty((1 * N, render_tw * N, 4), 'uint8')  # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:, x - render_tx * N:x - render_tx * N + w, :]

    first_row = render_ty
    last_row = render_ty + render_th - 1

    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty + render_th):
            skip_rendering = False
            if single_tile_pattern:
                # optimization for simple background patterns
                # e.g. solid color
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear_rgba8(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y + h - ty * N, :, :]
            if ty == first_row:
                res = res[y - render_ty * N:, :, :]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)
Exemplo n.º 6
0
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception, ex:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear_rgba8(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y + h - ty * N, :, :]
            if ty == first_row:
                res = res[y - render_ty * N:, :, :]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)
Exemplo n.º 7
0
def save_as_png(surface, filename, *rect, **kwargs):
    """Saves a surface to a file in PNG format"""
    # TODO: Document keyword params and their meanings, mentioning that
    # TODO:  some are processed and removed here, and that others are
    # TODO:  passed to blit_tile_into().
    alpha = kwargs.pop('alpha', False)
    feedback_cb = kwargs.pop('feedback_cb', None)
    write_legacy_png = kwargs.pop("write_legacy_png", True)
    single_tile_pattern = kwargs.pop("single_tile_pattern", False)
    if not rect:
        rect = surface.get_bbox()
    x, y, w, h = rect
    if w == 0 or h == 0:
        # workaround to save empty documents
        x, y, w, h = 0, 0, 1, 1

    # calculate bounding box in full tiles
    render_tx = x/N
    render_ty = y/N
    render_tw = (x+w-1)/N - render_tx + 1
    render_th = (y+h-1)/N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = numpy.empty((1*N, render_tw*N, 4), 'uint8')  # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:, x-render_tx*N:x-render_tx*N+w, :]

    first_row = render_ty
    last_row = render_ty+render_th-1

    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty+render_th):
            skip_rendering = False
            if single_tile_pattern:
                # optimization for simple background patterns
                # e.g. solid color
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel*N:(tx_rel+1)*N, :]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear_rgba8(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y+h-ty*N, :, :]
            if ty == first_row:
                res = res[y-render_ty*N:, :, :]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)
Exemplo n.º 8
0
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:,tx_rel*N:(tx_rel+1)*N,:]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception, ex:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y+h-ty*N,:,:]
            if ty == first_row:
                res = res[y-render_ty*N:,:,:]
            yield res

    filename_sys = filename.encode(sys.getfilesystemencoding())
    # FIXME: should not do that, should use open(unicode_object)
    mypaintlib.save_png_fast_progressive(filename_sys, w, h, alpha,
                                         render_tile_scanlines(),
                                         write_legacy_png)