Exemplo n.º 1
0
    def tiles_to_pil(self, palette: List[int]) -> Image.Image:
        """
        Exports the BPA as an image, where each row of 8x8 tiles is the
        animation set for a single tile. The 16 color palette passed is used to color the image.
        """
        dummy_tile_map = []
        width_in_tiles = self.number_of_frames
        etr = self.number_of_frames * self.number_of_tiles

        # create a dummy tile map containing all the tiles
        # The tiles in the BPA are stored so, that each tile of the each frame is next
        # to each other. So the second frame of the first tile is at self.number_of_images + 1.
        for tile_idx in range(0, self.number_of_tiles):
            for frame_idx in range(0, self.number_of_frames):
                dummy_tile_map.append(TilemapEntry(
                    idx=frame_idx * self.number_of_tiles + tile_idx,
                    pal_idx=0,
                    flip_x=False,
                    flip_y=False,
                    ignore_too_large=True
                ))
        width = width_in_tiles * BPA_TILE_DIM
        height = math.ceil(etr / width_in_tiles) * BPA_TILE_DIM

        return to_pil(
            dummy_tile_map, self.tiles, [palette], BPA_TILE_DIM, width, height
        )
Exemplo n.º 2
0
    def tiles_to_pil(self, layer: int, palettes: List[List[int]], width_in_tiles=20, single_palette=None) -> Image.Image:
        """
        Convert all individual tiles of the BPC into one PIL image.
        The image contains all tiles next to each other, the image width is tile_width tiles.
        The resulting image has one large palette with all palettes merged together.

        The tiles are exported with the palette of the first placed tile or 0 if tile is not in tilemap,
        for easier editing. The result image contains a palette that consists of all palettes merged together.

        If single_palette is not None, all palettes are exported using the palette no. stored in single_palette.

        The first tile is a NULL tile. It is always empty, even when re-imported.
        """

        # create a dummy tile map containing all the tiles
        dummy_tile_map = []
        for i in range(0, self.layers[layer].number_tiles+1):
            dummy_tile_map.append(TilemapEntry(
                idx=i,
                pal_idx=single_palette if single_palette is not None else self._get_palette_for_tile(layer, i),
                flip_x=False,
                flip_y=False
            ))
        width = width_in_tiles * BPC_TILE_DIM
        height = math.ceil((self.layers[layer].number_tiles+1) / width_in_tiles) * BPC_TILE_DIM

        return to_pil(
            dummy_tile_map, self.layers[layer].tiles, palettes, BPC_TILE_DIM, width, height
        )
Exemplo n.º 3
0
    def tiles_to_pil_separate(self, palette, width_in_tiles=20) -> List[Image.Image]:
        """
        Exports the BPA as an image, where each row of 8x8 tiles is the
        animation set for a single tile. The 16 color palette passed is used to color the image.
        """
        dummy_tile_map = []

        # create a dummy tile map containing all the tiles
        for tile_idx in range(0, self.number_of_tiles * self.number_of_frames):
            dummy_tile_map.append(TilemapEntry(
                idx=tile_idx,
                pal_idx=0,
                flip_x=False,
                flip_y=False,
                ignore_too_large=True
            ))
        width = width_in_tiles * BPA_TILE_DIM
        height = math.ceil(self.number_of_tiles / width_in_tiles) * BPA_TILE_DIM

        images = []
        for frame_start in range(0, self.number_of_tiles * self.number_of_frames, self.number_of_tiles):
            images.append(to_pil(
                dummy_tile_map[frame_start:frame_start+self.number_of_tiles], self.tiles, [palette], BPA_TILE_DIM, width, height
            ))
        return images
Exemplo n.º 4
0
def output_at_dungeon_tiles(fn: str, common_at: CommonAt, pal: Dpla):
    print("Outputting dungeon AT as image.")
    img_bin = common_at.decompress()
    tiles = list(iter_bytes(img_bin, int(8 * 8)))
    # create a dummy tile map containing all the tiles
    tilemap = []
    for i in range(0, len(tiles)):
        tilemap.append(TilemapEntry(i, False, False, 0, True))
    out_img = to_pil(tilemap,
                     tiles, [pal.get_palette_for_frame(0, 0)],
                     8,
                     int(len(tiles) * 8 / 3),
                     4 * 8,
                     tiling_width=1,
                     tiling_height=1,
                     bpp=8)
    # Alternate stategy:
    img_8bpp = img_bin  #bytes(x for x in iter_bytes_4bit_le(img_bin))
    mod = 16 * 4
    channels = 1
    mode = 'RGB' if channels == 3 else 'P'
    out_img = Image.frombuffer(mode,
                               (int(len(img_8bpp) / mod / channels), mod),
                               bytes(img_8bpp), 'raw', mode, 0, 1)
    if mode == 'P':
        out_img.putpalette(pal.get_palette_for_frame(0, 0))
    os.makedirs(os.path.join(output_dir, 'raw_img'), exist_ok=True)
    with open(os.path.join(output_dir, 'raw_img', fn), 'wb') as f:
        f.write(img_bin)

    out_img.save(os.path.join(output_dir, fn + '.png'))
Exemplo n.º 5
0
    def chunks_to_pil(self,
                      layer: int,
                      palettes: List[List[int]],
                      width_in_mtiles=20) -> Image.Image:
        """
        Convert all chunks of the BPC to one big PIL image.
        The chunks are all placed next to each other.
        The resulting image has one large palette with all palettes merged together.

        To get the palettes, use the data from the BPL file for this map background:

        >>> bpc.chunks_to_pil(bpl.palettes)

        The first chunk is a NULL tile. It is always empty, even when re-imported.

        Does NOT export BPA tiles. Chunks that reference BPA tiles are replaced with empty tiles. You will see
        warnings by the tiled_image module when this is the case.
        The mapping to BPA tiles has to be done programmatically using set_tile or set_chunk.

        """
        width = width_in_mtiles * self.tiling_width * BPC_TILE_DIM
        height = math.ceil(self.layers[layer].chunk_tilemap_len /
                           width_in_mtiles) * self.tiling_height * BPC_TILE_DIM
        return to_pil(self.layers[layer].tilemap, self.layers[layer].tiles,
                      palettes, BPC_TILE_DIM, width, height, self.tiling_width,
                      self.tiling_height)
Exemplo n.º 6
0
    def to_pil(self, index, palette_index=0) -> Image.Image:
        dummy_tilemap = []
        for i in range(CHUNK_DIM * CHUNK_DIM):
            dummy_tilemap.append(TilemapEntry(i, False, False, palette_index))

        return to_pil(dummy_tilemap, self.sprites[index], self.palettes,
                      TILE_DIM, TILE_DIM * CHUNK_DIM, TILE_DIM * CHUNK_DIM,
                      CHUNK_DIM, CHUNK_DIM)
Exemplo n.º 7
0
 def single_chunk_to_pil(self, chunk_idx, dpci: Dpci,
                         palettes: List[List[int]]):
     """
     Convert a single chunk of the DPC into a PIL image. For general notes, see chunks_to_pil.
     """
     return to_pil(self.chunks[chunk_idx], dpci.tiles, palettes,
                   DPCI_TILE_DIM, DPCI_TILE_DIM * DPC_TILING_DIM,
                   DPCI_TILE_DIM * DPC_TILING_DIM, DPC_TILING_DIM,
                   DPC_TILING_DIM)
Exemplo n.º 8
0
    def single_chunk_to_pil(self, layer: int, chunk_idx: int, palettes: List[List[int]]) -> Image.Image:
        """
        Convert a single chunk of the BPC to one big PIL image. For general notes, see chunks_to_pil.

        Does NOT export BPA tiles. Chunks that reference BPA tiles are replaced with empty tiles.
        """
        mtidx = chunk_idx * self.tiling_width * self.tiling_height
        return to_pil(
            self.layers[layer].tilemap[mtidx:mtidx + 9], self.layers[layer].tiles, palettes, BPC_TILE_DIM,
            BPC_TILE_DIM * self.tiling_width, BPC_TILE_DIM * self.tiling_height,
            self.tiling_width, self.tiling_height
        )
Exemplo n.º 9
0
    def to_pil(self, ignore_flip_bits=False) -> Image.Image:
        """
        Convert all tiles of the BGP to one big PIL image.
        The resulting image has one large palette with 256 colors.
        If ignore_flip_bits is set, tiles are not flipped.

        The image returned will have the size 256x192.
        For dimension calculating, see the constants of this module.
        """
        return to_pil(
            self.tilemap[:BGP_TOTAL_NUMBER_TILES], self.tiles, self.palettes, BGP_TILE_DIM, BGP_RES_WIDTH, BGP_RES_HEIGHT, 1, 1, ignore_flip_bits
        )
Exemplo n.º 10
0
    def to_pil(self) -> Image.Image:
        tilemap = []
        for i in range(ICON_DIM_IMG_TILES * ICON_DIM_IMG_TILES):
            tilemap.append(
                TilemapEntry(idx=i, pal_idx=0, flip_x=False, flip_y=False))

        return to_pil(
            tilemap,
            list(chunks(self.bitmap, ICON_DIM_TILE * ICON_DIM_TILE // 2)),
            [self._palette],
            ICON_DIM_TILE,
            ICON_DIM_IMG_PX,
            ICON_DIM_IMG_PX,
            bpp=4,
        )
Exemplo n.º 11
0
    def get(self) -> Image.Image:
        decompressed_data = self.decompress()
        w = TILE_DIM * self.entry_data.width
        h = TILE_DIM * self.entry_data.height

        # Create a virtual tilemap
        tilemap = []
        for i in range(int((w * h) / (TILE_DIM * TILE_DIM))):
            tilemap.append(
                TilemapEntry(idx=i, pal_idx=0, flip_x=False, flip_y=False))

        return to_pil(
            tilemap,
            list(grouper(int(TILE_DIM * TILE_DIM / 2), decompressed_data)),
            [self.pal], TILE_DIM, w, h)
Exemplo n.º 12
0
def output_at_water_tiles(fn: str, common_at: CommonAt, pal: Dpla):
    print("Outputting water AT as image.")
    img_bin = common_at.decompress()
    tiles = list(iter_bytes(img_bin, int(8 * 8 / 2)))
    # create a dummy tile map containing all the tiles
    tilemap = []
    for i in range(0, len(tiles)):
        tilemap.append(TilemapEntry(i, False, False, 0, True))
    out_img = to_pil(tilemap,
                     tiles, [pal.get_palette_for_frame(0, 0)],
                     8,
                     int(len(tiles) * 8 / 3),
                     4 * 8,
                     tiling_width=1,
                     tiling_height=1)
    os.makedirs(os.path.join(output_dir, 'raw_img'), exist_ok=True)
    with open(os.path.join(output_dir, 'raw_img', fn), 'wb') as f:
        f.write(img_bin)

    out_img.save(os.path.join(output_dir, fn + '.png'))
Exemplo n.º 13
0
    def chunks_to_pil(self,
                      dpci: Dpci,
                      palettes: List[List[int]],
                      width_in_mtiles=16) -> Image.Image:
        """
        Convert all chunks of the DPC to one big PIL image.
        The chunks are all placed next to each other.
        The resulting image has one large palette with all palettes merged together.

        To be used with the DPCI file for this dungeon.
        To get the palettes, use the data from the DPL file for this dungeon:

        >>> dpc.chunks_to_pil(dpci, dpl.palettes)

        """
        width = width_in_mtiles * DPC_TILING_DIM * DPCI_TILE_DIM
        height = math.ceil(len(self.chunks) /
                           width_in_mtiles) * DPC_TILING_DIM * DPCI_TILE_DIM
        return to_pil(list(itertools.chain.from_iterable(self.chunks)),
                      dpci.tiles, palettes, DPCI_TILE_DIM, width, height,
                      DPC_TILING_DIM, DPC_TILING_DIM)
Exemplo n.º 14
0
    def tiles_to_pil(self,
                     palettes: Sequence[Sequence[int]],
                     width_in_tiles=20,
                     palette_index=0) -> Image.Image:
        """
        Convert all individual tiles of the DPCI into one PIL image.
        The image contains all tiles next to each other, the image width is tile_width tiles.
        The resulting image has one large palette with all palettes merged together.

        palettes is a list of 16 16 color palettes.
        The tiles are exported with the first palette in the list of palettes.
        The result image contains a palette that consists of all palettes merged together.
        """
        # create a dummy tile map containing all the tiles
        tilemap = []
        for i in range(0, len(self.tiles)):
            tilemap.append(TilemapEntry(i, False, False, palette_index, True))

        width = width_in_tiles * DPCI_TILE_DIM
        height = math.ceil((len(self.tiles)) / width_in_tiles) * DPCI_TILE_DIM

        return to_pil(tilemap, self.tiles, palettes, DPCI_TILE_DIM, width,
                      height)