Exemplo n.º 1
0
def read_strip(im, strip, g2l, hotspot, tile_ht):
    paletteid, l, t, w, h, lpad, tpad, dstl, dstt = strip

    # Crop and convert to subpalette
    cropped = im.crop((l, t, l + w, t + h)).point(g2l[paletteid])

    # Add padding at left and top for exceeding the crop rect,
    # and at right and bottom to a multiple of one tile
    wnew = -(-(w + lpad) // TILE_W) * TILE_W
    hnew = -(-(h + tpad) // tile_ht) * tile_ht
    padded = Image.new('P', (wnew, hnew), 0)
    padded.paste(cropped, (lpad, tpad))

    # Convert image to tiles
    tilefmt = lambda x: pilbmp2nes.formatTilePlanar(x, TILE_PLANEMAP)
    striptiles = pilbmp2nes.pilbmp2chr(padded, TILE_W, tile_ht, tilefmt)

    # Convert coords to hotspot-relative
    dstl -= hotspot[0]
    dstt -= hotspot[1]

    # Convert tiles to horizontal strips
    tperrow = (tile_ht // 8) * (wnew // 8)
    tend = 0
    for y in range(hnew // tile_ht):
        tstart, tend = tend, tend + tperrow
        yield paletteid, striptiles[tstart:tend], dstl, dstt + y * tile_ht
Exemplo n.º 2
0
def main(argv=None):
    argv = argv or sys.argv
    op = argv[1]
    filename = argv[2]
    if op == 'font':
        w = int(argv[3])
        h = int(argv[4])
        title = argv[5]
        print(cvt_font(filename, 24, 32, '0;1', title))
        return
    if op == 'img':
        starttile = int(argv[3])
        title = argv[4]
        im = Image.open(filename)
        c = pilbmp2chr(im, 8, 8, lambda k: formatTilePlanar(k, '0;1'))
        tiles, itiles, nam = chrtonam(c)
        nam = bytearray(starttile + c for c in nam)
        tiles = b''.join(tiles)
        ctiles = zeroelim(tiles)
        out = [
            "; image converted with cvtfont.py",
            ".export %s_zet, %s_chr_size, %s_nam" % (title, title, title),
            ".exportzp %s_w, %s_h" % (title, title), '.segment "RODATA"',
            "%s_w = %d" % (title, (im.size[0] + 7) // 8),
            "%s_h = %d" % (title, (im.size[1] + 7) // 8),
            "%s_chr_size = %d" % (title, len(tiles)),
            "%s_zet:" % title,
            ca65_bytearray(ctiles),
            "%s_nam:" % title,
            ca65_bytearray(nam)
        ]
        print('\n'.join(out))
        return
Exemplo n.º 3
0
def test_iur():
    from PIL import Image
    from pilbmp2nes import pilbmp2chr, formatTilePlanar

    gbformat = lambda tile: formatTilePlanar(tile, "0,1")
    test_filenames = [
        ("Proposed MF title screen",
         "../renders/title_bgonly.png"),
        ("Green Hill Zone for GB",
         "../../240p-test-mini/gameboy/tilesets/greenhillzone.png"),
        ("Gus portrait for DMG",
         "../../240p-test-mini/gameboy/tilesets/Gus_portrait.png"),
        ("Linearity quadrant for GB",
         "../../240p-test-mini/gameboy/tilesets/linearity-quadrant.png"),
        ("Sharpness for GB",
         "../../240p-test-mini/gameboy/tilesets/sharpness.png"),
        ("Stopwatch face for GB",
         "../../240p-test-mini/gameboy/tilesets/stopwatchface.png"),
    ]
    for title, filename in test_filenames:
        print("Stats for %s (%s)" % (title, os.path.basename(filename)))
        im = Image.open(filename)
        chrdata = pilbmp2chr(im, formatTile=gbformat)
        iur_encode(chrdata, report=True)
        print()
Exemplo n.º 4
0
def im_to_gbc(im, palettes):
    imfinal, attrs = colorround(im, palettes, (8, 8), 4)
    gbformat = lambda im: formatTilePlanar(im, "0,1")
    tiles = pilbmp2chr(imfinal, formatTile=formatTileGB)
    utiles, tilemap = flipuniq(tiles)
    assert len(tilemap) == len(attrs)
    tilemap_hi = bytearray((t >> 8) | c for t, c in zip(tilemap, attrs))
    tilemap_lo = bytearray(t & 0xFF for t in tilemap)
    return imfinal, utiles, tilemap_lo, tilemap_hi
Exemplo n.º 5
0
def load_glyph_tiles_from(filename, cellw, cellh, fmt):
    """Load tiles from glyphs in filename.

im -- PIL image object in indexed color or filename to load
cellw -- width of each glyph box, multiple of 8
cellh -- height of glyph box, multiple of 8
fmt -- a pilbmp2nes planemap string, such as "0,1" for GB or "0;1" for NES

The glyphs in `im` are left-aligned in their boxes, using color 0
for transparent and the highest color value for space between glyphs.

Return a list of lists of tiles in column-major order.

"""
    if isinstance(filename, str):
        im = Image.open(filename)
    else:
        im, filename = filename, '<image>'
    if im.mode != 'P':
        raise ValueError("%s: not indexed color" % filename)
    st = ImageStat.Stat(im)
    bordercolor = st.extrema[0][1]

    # Crop each glyph out of the image
    portions = (im.crop((x, y, x + cellw, y + cellh))
                for y in range(0, im.size[1], cellh)
                for x in range(0, im.size[0], cellw))

    # Crop out the internal border to right of each glyph
    # ImageChops.difference(im, flat).getbbox(): thanks Eugene Nagorny
    # http://stackoverflow.com/q/10615901/2738262
    flatborder = Image.new(im.mode, (cellw, cellh), bordercolor)
    bboxes = ((portion, ImageChops.difference(portion, flatborder).getbbox())
              for portion in portions)

    portionsC = (portion.crop(bb) if bb is not None else None
                 for portion, bb in bboxes)

    # Now break each glyph down into tiles
    fmtTile = lambda im: formatTilePlanar(im, fmt)
    portionsT = [
        pilbmp2chr(portion, 8, 32, fmtTile) if portion is not None else []
        for portion in portionsC
    ]
    return portionsT
Exemplo n.º 6
0
def snesformat(tile):
    return formatTilePlanar(tile, "0,1;2,3")
Exemplo n.º 7
0
def formatTileGB(im):
    return formatTilePlanar(im, "0,1")
Exemplo n.º 8
0
def main(argv=None):
    global printStats
    import sys

    from pilbmp2nes import formatTilePlanar, pilbmp2chr

    if argv is None:
        argv = sys.argv
        if (argvTestingMode and len(argv) < 2 and sys.stdin.isatty()
                and sys.stdout.isatty()):
            argv.extend(raw_input('args:').split())
    try:
        (infilename, outfilename, maxTiles, useDims, chrCodec, useIndexRLE,
         printStats) = parse_argv(argv)
    except Exception as e:
        sys.stderr.write("%s: %s\n" % (argv[0], str(e)))
        sys.exit(1)

    if printStats:
        print("filename: %s" % infilename, file=sys.stderr)
    im = Image.open(infilename)
    (w, h) = im.size
    if printStats:
        print >> sys.stderr, "size: %dx%d" % im.size
    if w % 8 != 0:
        raise ValueError("image width %d is not a multiple of 8" % w)
    if h % 8 != 0:
        raise ValueError("image height %d is not a multiple of 8" % h)

    ochrdata = pilbmp2chr(im, 8, 8, lambda im: formatTilePlanar(im, 2))
    del im
    (chrdata, ntdata) = dedupe_chr(ochrdata)
    numTiles = len(chrdata)

    if numTiles > maxTiles:
        raise ValueError("%d distinct tiles exceed maximum %d" %
                         (numTiles, maxTiles))

    ochrdata = ''.join(ochrdata)
    chrdata = ''.join(chrdata)
    if printStats:
        print("CHR size before dedupe: %d" % len(ochrdata), file=sys.stderr)
        print("distinct tiles: %d of %d" % (numTiles, len(ntdata)),
              file=sys.stderr)
        print("unpacked CHR size: %d" % len(chrdata), file=sys.stderr)
    if useIndexRLE:
        cntdata = compress_nt(ntdata)
        if printStats:
            print("compressed nametable size: %s" % len(cntdata),
                  file=sys.stderr)
        ntdata = cntdata
    else:
        ntdata = ''.join(chr(x) for x in ntdata)
    if chrCodec == 'packbits':
        from packbits import PackBits
        sz = len(chrdata) % 0x10000
        pchrdata = PackBits(chrdata).flush().tostring()
        pchrdata = bytes([chr(sz >> 8), chr(sz & 0xFF)]) + pchrdata
        if printStats:
            print("packed CHR size: %d" % len(pchrdata), file=sys.stderr)
        chrdata = pchrdata
    elif chrCodec == 'pb8':
        from pb8 import pb8
        sz = len(chrdata) // 16
        pchrdata = pb8(chrdata)
        pchrdata = bytes([sz & 0xFF]) + pchrdata
        if printStats:
            print("packed CHR size: %d" % len(pchrdata), file=sys.stderr)
        chrdata = pchrdata

    if useDims:
        dimsdata = bytes([w // 8, h // 8, numTiles & 0xFF, 0])
    else:
        dimsdata = ''
    outdata = b''.join([dimsdata, ntdata, chrdata])

    # Write output file
    outfp = None
    try:
        if outfilename != '-':
            outfp = open(outfilename, 'wb')
        else:
            outfp = sys.stdout
        outfp.write(outdata)
    finally:
        if outfp and outfilename != '-':
            outfp.close()