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
def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0): # used mainly for saving (transparent PNG) #assert dst_has_alpha is True if self.mipmap_level < mipmap_level: return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty, mipmap_level) assert dst.shape[2] == 4 if dst.dtype not in ('uint16', 'uint8'): raise ValueError('Unsupported destination buffer type %r', dst.dtype) dst_is_uint16 = (dst.dtype == 'uint16') with self.tile_request(tx, ty, readonly=True) as src: if src is transparent_tile.rgba: #dst[:] = 0 # <-- notably slower than memset() if dst_is_uint16: mypaintlib.tile_clear_rgba16(dst) else: mypaintlib.tile_clear_rgba8(dst) else: if dst_is_uint16: # this will do memcpy, not worth to bother skipping the u channel mypaintlib.tile_copy_rgba16_into_rgba16(src, dst) else: if dst_has_alpha: mypaintlib.tile_convert_rgba16_to_rgba8(src, dst) else: mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
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
def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0, *args, **kwargs): """Copy one tile from this object into a destination array See lib.surface.TileBlittable for the parameters. This implementation adds an extra param: :param int mipmap_level: layer mipmap level to use Used mainly for saving (transparent PNG). """ # assert dst_has_alpha is True if self.mipmap_level < mipmap_level: return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty, mipmap_level) assert dst.shape[2] == 4 if dst.dtype not in ('uint16', 'uint8'): raise ValueError('Unsupported destination buffer type %r', dst.dtype) dst_is_uint16 = (dst.dtype == 'uint16') with self.tile_request(tx, ty, readonly=True) as src: if src is transparent_tile.rgba: # dst[:] = 0 # <-- notably slower than memset() if dst_is_uint16: mypaintlib.tile_clear_rgba16(dst) else: mypaintlib.tile_clear_rgba8(dst) else: if dst_is_uint16: # this will do memcpy, not worth to bother skipping # the u channel mypaintlib.tile_copy_rgba16_into_rgba16(src, dst) else: if dst_has_alpha: mypaintlib.tile_convert_rgba16_to_rgba8(src, dst) else: mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0, *args, **kwargs): """Copy one tile from this object into a destination array See lib.surface.TileBlittable for the parameters. This implementation adds an extra param: :param int mipmap_level: layer mipmap level to use """ # used mainly for saving (transparent PNG) #assert dst_has_alpha is True if self.mipmap_level < mipmap_level: return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty, mipmap_level) assert dst.shape[2] == 4 if dst.dtype not in ('uint16', 'uint8'): raise ValueError('Unsupported destination buffer type %r', dst.dtype) dst_is_uint16 = (dst.dtype == 'uint16') with self.tile_request(tx, ty, readonly=True) as src: if src is transparent_tile.rgba: #dst[:] = 0 # <-- notably slower than memset() if dst_is_uint16: mypaintlib.tile_clear_rgba16(dst) else: mypaintlib.tile_clear_rgba8(dst) else: if dst_is_uint16: # this will do memcpy, not worth to bother skipping the u channel mypaintlib.tile_copy_rgba16_into_rgba16(src, dst) else: if dst_has_alpha: mypaintlib.tile_convert_rgba16_to_rgba8(src, dst) else: mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
def scanline_strips_iter(surface, rect, alpha=False, single_tile_pattern=False, **kwargs): """Generate (render) scanline strips from a tile-blittable object :param lib.surface.TileBlittable surface: Surface to iterate over :param bool alpha: If true, write a PNG with alpha :param bool single_tile_pattern: True if surface is a one tile only. :param tuple \*\*kwargs: Passed to blit_tile_into. The `alpha` parameter is passed to the surface's `blit_tile_into()`. Rendering is skipped for all but the first line of single-tile patterns. The scanline strips yielded by this generator are suitable for feeding to a mypaintlib.ProgressivePNGWriter. """ # Sizes x, y, w, h = rect assert w > 0 assert h > 0 # 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 = np.empty((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 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) # 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
def scanline_strips_iter(surface, rect, alpha=False, single_tile_pattern=False, **kwargs): """Generate (render) scanline strips from a tile-blittable object :param lib.surface.TileBlittable surface: Surface to iterate over :param bool alpha: If true, write a PNG with alpha :param bool single_tile_pattern: True if surface is a one tile only. :param tuple \*\*kwargs: Passed to blit_tile_into. The `alpha` parameter is passed to the surface's `blit_tile_into()`. Rendering is skipped for all but the first line of single-tile patterns. The scanline strips yielded by this generator are suitable for feeding to a mypaintlib.ProgressivePNGWriter. """ # Sizes x, y, w, h = rect assert w > 0 assert h > 0 # 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 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) # 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