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)
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)
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)
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)
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)
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)
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)
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)