Source code for tcod.image

from typing import Any, Dict, Tuple

import numpy as np

import tcod.console
from tcod.loader import ffi, lib
from tcod._internal import _console


[docs]class Image(object): """ Args: width (int): Width of the new Image. height (int): Height of the new Image. Attributes: width (int): Read only width of this Image. height (int): Read only height of this Image. """ def __init__(self, width: int, height: int): self.width, self.height = width, height self.image_c = ffi.gc( lib.TCOD_image_new(width, height), lib.TCOD_image_delete ) @classmethod def _from_cdata(cls, cdata: Any) -> "Image": self = object.__new__(cls) # type: "Image" self.image_c = cdata self.width, self.height = self._get_size() return self
[docs] @classmethod def from_array(cls, array: Any) -> "Image": """Create a new Image from a copy of an array-like object. Example: >>> import numpy as np >>> import tcod.image >>> array = np.zeros((5, 5, 3), dtype=np.uint8) >>> image = tcod.image.Image.from_array(array) .. versionadded:: 11.4 """ array = np.asarray(array) height, width, depth = array.shape image = cls(width, height) image_array = np.asarray(image) image_array[...] = array return image
[docs] def clear(self, color: Tuple[int, int, int]) -> None: """Fill this entire Image with color. Args: color (Union[Tuple[int, int, int], Sequence[int]]): An (r, g, b) sequence or Color instance. """ lib.TCOD_image_clear(self.image_c, color)
[docs] def invert(self) -> None: """Invert all colors in this Image.""" lib.TCOD_image_invert(self.image_c)
[docs] def hflip(self) -> None: """Horizontally flip this Image.""" lib.TCOD_image_hflip(self.image_c)
[docs] def rotate90(self, rotations: int = 1) -> None: """Rotate this Image clockwise in 90 degree steps. Args: rotations (int): Number of 90 degree clockwise rotations. """ lib.TCOD_image_rotate90(self.image_c, rotations)
[docs] def vflip(self) -> None: """Vertically flip this Image.""" lib.TCOD_image_vflip(self.image_c)
[docs] def scale(self, width: int, height: int) -> None: """Scale this Image to the new width and height. Args: width (int): The new width of the Image after scaling. height (int): The new height of the Image after scaling. """ lib.TCOD_image_scale(self.image_c, width, height) self.width, self.height = width, height
[docs] def set_key_color(self, color: Tuple[int, int, int]) -> None: """Set a color to be transparent during blitting functions. Args: color (Union[Tuple[int, int, int], Sequence[int]]): An (r, g, b) sequence or Color instance. """ lib.TCOD_image_set_key_color(self.image_c, color)
[docs] def get_alpha(self, x: int, y: int) -> int: """Get the Image alpha of the pixel at x, y. Args: x (int): X pixel of the image. Starting from the left at 0. y (int): Y pixel of the image. Starting from the top at 0. Returns: int: The alpha value of the pixel. With 0 being fully transparent and 255 being fully opaque. """ return lib.TCOD_image_get_alpha(self.image_c, x, y) # type: ignore
[docs] def refresh_console(self, console: tcod.console.Console) -> None: """Update an Image created with :any:`tcod.image_from_console`. The console used with this function should have the same width and height as the Console given to :any:`tcod.image_from_console`. The font width and height must also be the same as when :any:`tcod.image_from_console` was called. Args: console (Console): A Console with a pixel width and height matching this Image. """ lib.TCOD_image_refresh_console(self.image_c, _console(console))
def _get_size(self) -> Tuple[int, int]: """Return the (width, height) for this Image. Returns: Tuple[int, int]: The (width, height) of this Image """ w = ffi.new("int *") h = ffi.new("int *") lib.TCOD_image_get_size(self.image_c, w, h) return w[0], h[0]
[docs] def get_pixel(self, x: int, y: int) -> Tuple[int, int, int]: """Get the color of a pixel in this Image. Args: x (int): X pixel of the Image. Starting from the left at 0. y (int): Y pixel of the Image. Starting from the top at 0. Returns: Tuple[int, int, int]: An (r, g, b) tuple containing the pixels color value. Values are in a 0 to 255 range. """ color = lib.TCOD_image_get_pixel(self.image_c, x, y) return color.r, color.g, color.b
[docs] def get_mipmap_pixel( self, left: float, top: float, right: float, bottom: float ) -> Tuple[int, int, int]: """Get the average color of a rectangle in this Image. Parameters should stay within the following limits: * 0 <= left < right < Image.width * 0 <= top < bottom < Image.height Args: left (float): Left corner of the region. top (float): Top corner of the region. right (float): Right corner of the region. bottom (float): Bottom corner of the region. Returns: Tuple[int, int, int]: An (r, g, b) tuple containing the averaged color value. Values are in a 0 to 255 range. """ color = lib.TCOD_image_get_mipmap_pixel( self.image_c, left, top, right, bottom ) return (color.r, color.g, color.b)
[docs] def put_pixel(self, x: int, y: int, color: Tuple[int, int, int]) -> None: """Change a pixel on this Image. Args: x (int): X pixel of the Image. Starting from the left at 0. y (int): Y pixel of the Image. Starting from the top at 0. color (Union[Tuple[int, int, int], Sequence[int]]): An (r, g, b) sequence or Color instance. """ lib.TCOD_image_put_pixel(self.image_c, x, y, color)
[docs] def blit( self, console: tcod.console.Console, x: float, y: float, bg_blend: int, scale_x: float, scale_y: float, angle: float, ) -> None: """Blit onto a Console using scaling and rotation. Args: console (Console): Blit destination Console. x (float): Console X position for the center of the Image blit. y (float): Console Y position for the center of the Image blit. The Image blit is centered on this position. bg_blend (int): Background blending mode to use. scale_x (float): Scaling along Image x axis. Set to 1 for no scaling. Must be over 0. scale_y (float): Scaling along Image y axis. Set to 1 for no scaling. Must be over 0. angle (float): Rotation angle in radians. (Clockwise?) """ lib.TCOD_image_blit( self.image_c, _console(console), x, y, bg_blend, scale_x, scale_y, angle, )
[docs] def blit_rect( self, console: tcod.console.Console, x: int, y: int, width: int, height: int, bg_blend: int, ) -> None: """Blit onto a Console without scaling or rotation. Args: console (Console): Blit destination Console. x (int): Console tile X position starting from the left at 0. y (int): Console tile Y position starting from the top at 0. width (int): Use -1 for Image width. height (int): Use -1 for Image height. bg_blend (int): Background blending mode to use. """ lib.TCOD_image_blit_rect( self.image_c, _console(console), x, y, width, height, bg_blend )
[docs] def blit_2x( self, console: tcod.console.Console, dest_x: int, dest_y: int, img_x: int = 0, img_y: int = 0, img_width: int = -1, img_height: int = -1, ) -> None: """Blit onto a Console with double resolution. Args: console (Console): Blit destination Console. dest_x (int): Console tile X position starting from the left at 0. dest_y (int): Console tile Y position starting from the top at 0. img_x (int): Left corner pixel of the Image to blit img_y (int): Top corner pixel of the Image to blit img_width (int): Width of the Image to blit. Use -1 for the full Image width. img_height (int): Height of the Image to blit. Use -1 for the full Image height. """ lib.TCOD_image_blit_2x( self.image_c, _console(console), dest_x, dest_y, img_x, img_y, img_width, img_height, )
[docs] def save_as(self, filename: str) -> None: """Save the Image to a 32-bit .bmp or .png file. Args: filename (Text): File path to same this Image. """ lib.TCOD_image_save(self.image_c, filename.encode("utf-8"))
@property def __array_interface__(self) -> Dict[str, Any]: """Return an interface for this images pixel buffer. Use :any:`numpy.asarray` to get the read-write array of this Image. This will often return an RGB array, but could also return an RGBA array or fail silently. Future versions might change what type of array is returned. You can use ``dtype=numpy.uint8`` to ensure that errors are not ignored by NumPy. .. versionadded:: 11.4 """ strides = None if self.image_c.mipmaps: # Libtcod RGB array. depth = 3 data = int(ffi.cast("size_t", self.image_c.mipmaps[0].buf)) else: raise TypeError("Image has no initialized data.") return { "shape": (self.height, self.width, depth), "typestr": "|u1", "data": (data, False), "strides": strides, "version": 3, }
def _get_format_name(format: int) -> str: """Return the SDL_PIXELFORMAT_X name for this format, if possible.""" for attr in dir(lib): if not attr.startswith("SDL_PIXELFORMAT"): continue if not getattr(lib, attr) == format: continue return attr return str(format)
[docs]def load(filename: str) -> np.ndarray: """Load a PNG file as an RGBA array. `filename` is the name of the file to load. The returned array is in the shape: `(height, width, RGBA)`. .. versionadded:: 11.4 """ image = Image._from_cdata( ffi.gc(lib.TCOD_image_load(filename.encode()), lib.TCOD_image_delete) ) array = np.asarray(image, dtype=np.uint8) height, width, depth = array.shape if depth == 3: array = np.concatenate( ( array, np.full((height, width, 1), fill_value=255, dtype=np.uint8), ), axis=2, ) return array