def bmptowidesb53(infilename, palette, outfilename): im = Image.open(infilename) if im.size[0] != 512: raise ValueError("Image width is %d pixels (expected 512)" % im.size[0]) if im.size[1] != 240: raise ValueError("Image height is %d pixels (expected 240)" % im.size[0]) # Quantize picture to palette palette = b''.join(palette[0:1] + palette[i + 1:i + 4] for i in range(0, 16, 4)) palettes = [[tuple(savtool.bisqpal[r]) for r in palette[i:i + 4]] for i in range(0, 16, 4)] imf, attrs = savtool.colorround(im, palettes) # Convert to unique tiles chrdata = pilbmp2nes.pilbmp2chr(imf, 8, 8) chrdata, linear_namdata = chnutils.dedupe_chr(chrdata) print("%d distinct tiles" % len(chrdata)) # Split into separate 32x32 nametables nametables = [[ linear_namdata[i:i + 32] for i in range(x, len(linear_namdata), im.size[0] // 8) ] for x in range(0, im.size[0] // 8, 32)] nametables = [bytes(b for row in nt for b in row) for nt in nametables] # Pack attributes into bytes if len(attrs) % 2: attrs.append([0] * len(attrs[0])) attrs = [[lc | (rc << 2) for lc, rc in zip(row[0::2], row[1::2])] for row in attrs] attrs = [[tc | (bc << 4) for (tc, bc) in zip(t, b)] for (t, b) in zip(attrs[0::2], attrs[1::2])] # Split into separate 32x32 nametables attrs = [ bytes(b for row in attrs for b in row[i:i + 8]) for i in range(0, len(attrs[0]), 8) ] print([len(x) for x in attrs]) outdata = [ bytearray([len(chrdata) & 0xFF]), pb53(b''.join(chrdata), copyprev=False)[0] ] outdata.extend( pb53(nt + at, copyprev=False)[0] for nt, at in zip(nametables, attrs)) outdata.append(palette) with open(outfilename, 'wb') as outfp: outfp.writelines(outdata)
def bmptowidesb53(infilename, palette, outfilename): im = Image.open(infilename) if im.size[0] != 512: raise ValueError("Image width is %d pixels (expected 512)" % im.size[0]) if im.size[1] != 240: raise ValueError("Image height is %d pixels (expected 240)" % im.size[0]) # Quantize picture to palette palette = b''.join(palette[0:1] + palette[i + 1:i + 4] for i in range(0, 16, 4)) palettes = [[tuple(savtool.bisqpal[r]) for r in palette[i:i + 4]] for i in range(0, 16, 4)] imf, attrs = savtool.colorround(im, palettes) # Convert to unique tiles chrdata = pilbmp2nes.pilbmp2chr(imf, 8, 8) chrdata, linear_namdata = chnutils.dedupe_chr(chrdata) print("%d distinct tiles" % len(chrdata)) # Split into separate 32x32 nametables nametables = [[linear_namdata[i:i + 32] for i in range(x, len(linear_namdata), im.size[0] // 8)] for x in range(0, im.size[0] // 8, 32)] nametables = [bytes(b for row in nt for b in row) for nt in nametables] # Pack attributes into bytes if len(attrs) % 2: attrs.append([0] * len(attrs[0])) attrs = [[lc | (rc << 2) for lc, rc in zip(row[0::2], row[1::2])] for row in attrs] attrs = [[tc | (bc << 4) for (tc, bc) in zip(t, b)] for (t, b) in zip(attrs[0::2], attrs[1::2])] # Split into separate 32x32 nametables attrs = [bytes(b for row in attrs for b in row[i:i + 8]) for i in range(0, len(attrs[0]), 8)] print([len(x) for x in attrs]) outdata = [ bytearray([len(chrdata) & 0xFF]), pb53(b''.join(chrdata), copyprev=False)[0] ] outdata.extend(pb53(nt + at, copyprev=False)[0] for nt, at in zip(nametables, attrs)) outdata.append(palette) with open(outfilename, 'wb') as outfp: outfp.writelines(outdata)
def bitmap_to_sav(im, max_tiles=None): """Convert a PIL bitmap without remapping the colors.""" from pilbmp2nes import pilbmp2chr from chnutils import dedupe_chr (w, h) = im.size im = pilbmp2chr(im, 8, 8) if max_tiles is not None: from jrtilevq import reduce_tiles im = reduce_tiles(im, max_tiles) namdata = bytearray([0xFF]) * 960 namdata.extend(bytes(64)) # If smaller than 16384 pixels, output as a tile sheet # with a blank nametable if len(im) > 256: im, linear_namdata = dedupe_chr(im) if len(im) > 256: raise IndexError("image has %d distinct tiles, which exceeds 256" % len(im)) width_in_tiles = w // 8 height_in_tiles = len(linear_namdata) // width_in_tiles topborder = (31 - height_in_tiles) // 2 leftborder = (32 - width_in_tiles) // 2 rightborder = 32 - width_in_tiles - leftborder offset = topborder * 32 + leftborder for i in range(0, len(linear_namdata), width_in_tiles): namdata[offset:offset + width_in_tiles] = linear_namdata[i:i + width_in_tiles] offset += 32 assert len(namdata) == 1024 chrdata = b''.join(im) chrpad = b'\xFF' * (6144 - len(chrdata)) assert len(chrdata) <= 4096 assert len(chrdata) + len(chrpad) == 6144 assert len(namdata) == 1024 sav = b''.join((chrdata, chrpad, namdata, b'\xFF' * 768, default_palette, default_palette, b'\xFF' * 224)) assert len(sav) == 8192 return sav
def bitmap_to_sav(im): """Convert a PIL bitmap without remapping the colors.""" from pilbmp2nes import pilbmp2chr from chnutils import dedupe_chr (w, h) = im.size im = pilbmp2chr(im, 8, 8) if len(im) <= 256: # smaller than 16384 pixels: output as a tile sheet # with a blank nametable chrdata = ''.join(im) namdata = '\xFF' * 960 + '\x00' * 64 else: from array import array im, linear_namdata = dedupe_chr(im) if len(im) > 256: raise IndexError("image has %d distinct tiles, which exceeds 256" % len(im)) width_in_tiles = w // 8 height_in_tiles = len(linear_namdata) // width_in_tiles topborder = (31 - height_in_tiles) // 2 leftborder = (32 - width_in_tiles) // 2 rightborder = 32 - width_in_tiles - leftborder namdata = array('B', '\xFF' * (32 * topborder)) for i in range(0, len(linear_namdata), width_in_tiles): namdata.fromstring('\xFF' * leftborder) namdata.extend(linear_namdata[i:i + width_in_tiles]) namdata.fromstring('\xFF' * rightborder) namdata.fromstring('\xFF' * (960 - len(namdata))) namdata.fromstring('\x00' * 64) namdata = namdata.tostring() assert len(namdata) == 1024 chrdata = ''.join(im) chrdata = chrdata + '\xFF' * (4096 - len(chrdata)) sav = ''.join((chrdata, '\xFF' * 2048, namdata, '\xFF' * 768, default_palette, default_palette, '\xFF' * 224)) return sav
def bitmap_to_sav(im): """Convert a PIL bitmap without remapping the colors.""" from pilbmp2nes import pilbmp2chr from chnutils import dedupe_chr (w, h) = im.size im = pilbmp2chr(im, 8, 8) if len(im) <= 256: # smaller than 16384 pixels: output as a tile sheet # with a blank nametable chrdata = "".join(im) namdata = "\xFF" * 960 + "\x00" * 64 else: from array import array im, linear_namdata = dedupe_chr(im) if len(im) > 256: raise IndexError("image has %d distinct tiles, which exceeds 256" % len(im)) width_in_tiles = w // 8 height_in_tiles = len(linear_namdata) // width_in_tiles topborder = (31 - height_in_tiles) // 2 leftborder = (32 - width_in_tiles) // 2 rightborder = 32 - width_in_tiles - leftborder namdata = array("B", "\xFF" * (32 * topborder)) for i in range(0, len(linear_namdata), width_in_tiles): namdata.fromstring("\xFF" * leftborder) namdata.extend(linear_namdata[i : i + width_in_tiles]) namdata.fromstring("\xFF" * rightborder) namdata.fromstring("\xFF" * (960 - len(namdata))) namdata.fromstring("\x00" * 64) namdata = namdata.tostring() assert len(namdata) == 1024 chrdata = "".join(im) chrdata = chrdata + "\xFF" * (4096 - len(chrdata)) sav = "".join((chrdata, "\xFF" * 2048, namdata, "\xFF" * 768, default_palette, default_palette, "\xFF" * 224)) return sav
def bitmap_to_sav(im): """Convert a PIL bitmap without remapping the colors.""" from pilbmp2nes import pilbmp2chr from chnutils import dedupe_chr (w, h) = im.size im = pilbmp2chr(im, 8, 8) namdata = bytearray([0xFF] * 960) namdata.extend([0x00] * 64) # If smaller than 16384 pixels, output as a tile sheet # with a blank nametable if len(im) > 256: im, linear_namdata = dedupe_chr(im) if len(im) > 256: raise IndexError("image has %d distinct tiles, which exceeds 256" % len(im)) width_in_tiles = w // 8 height_in_tiles = len(linear_namdata) // width_in_tiles topborder = (31 - height_in_tiles) // 2 leftborder = (32 - width_in_tiles) // 2 rightborder = 32 - width_in_tiles - leftborder offset = topborder * 32 + leftborder for i in range(0, len(linear_namdata), width_in_tiles): namdata[offset:offset + width_in_tiles] = linear_namdata[i:i + width_in_tiles] offset += 32 assert len(namdata) == 1024 chrdata = b''.join(im) chrpad = b'\xFF' * (6144 - len(chrdata)) assert len(chrdata) <= 4096 assert len(chrdata) + len(chrpad) == 6144 assert len(namdata) == 1024 sav = b''.join((chrdata, chrpad, namdata, b'\xFF' * 768, default_palette, default_palette, b'\xFF' * 224)) assert len(sav) == 8192 return sav