diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-05-22 12:53:03 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-05-22 12:53:03 +0100 |
commit | cf000407b8d2d4e75a6f56b5d111f3e55e7400e5 (patch) | |
tree | 9ed14ce5c38213acfad0994018dbfe0c807197ab /tools | |
parent | f89c327501a841d5bdcb5d26be065819e0e13229 (diff) | |
download | tr8vm-cf000407b8d2d4e75a6f56b5d111f3e55e7400e5.tar.gz tr8vm-cf000407b8d2d4e75a6f56b5d111f3e55e7400e5.zip |
Added rotate tiles tool
Diffstat (limited to 'tools')
-rw-r--r-- | tools/rotate.md | 40 | ||||
-rwxr-xr-x | tools/rotate.py | 83 |
2 files changed, 123 insertions, 0 deletions
diff --git a/tools/rotate.md b/tools/rotate.md new file mode 100644 index 0000000..ab95c07 --- /dev/null +++ b/tools/rotate.md @@ -0,0 +1,40 @@ +# Rotate tiles + +This tool can be used to transform an image containing a tileset into a new +one with a single column of tiles, so can be loaded with ".incpng" and the +result is easy to index. + +For example, given 6 tiles of 8x8 pixels in `origin.ong`: + +``` +012345 +``` + +The command `./rotate.py origin.png 8 8 dest.png` will generate an image with +the tiles rearranged like this: + +``` +0 +1 +2 +3 +4 +5 +``` + +In this way tile 0 is in `addr`, tile 1 in `addr + 64`, tile 2 in `addr + 128`, etc. + +## Requirements + +The tool requires: + +- Python 3 +- PIL (or Pillow) + +For example, you can install Pillow with: + +``` +python3 -m pip install --upgrade pip +python3 -m pip install --upgrade Pillow +``` + diff --git a/tools/rotate.py b/tools/rotate.py new file mode 100755 index 0000000..1fcc2c9 --- /dev/null +++ b/tools/rotate.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# +# Rotate tiles +# Copyright (C) 2023 by Juan J. Martinez <jjm@usebox.net> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +__version__ = "1.0" + +import sys +from argparse import ArgumentParser +from itertools import chain + +try: + from PIL import Image +except ImportError: + sys.exit("Please install PIP (or pillow)") + + +def main(): + + parser = ArgumentParser( + description="Rotate tiles", + epilog="Copyright (C) 2023 Juan J Martinez <jjm@usebox.net>", + ) + + parser.add_argument( + "--version", action="version", version="%(prog)s " + __version__ + ) + + parser.add_argument("image", help="image to convert") + parser.add_argument("width", help="witdth of the tiles", type=int) + parser.add_argument("height", help="height of the tiles", type=int) + parser.add_argument("dest", help="destination image") + + args = parser.parse_args() + + try: + image = Image.open(args.image) + except IOError: + parser.error("failed to open the image") + + (w, h) = image.size + + if w % args.width or h % args.height: + parser.error("%s size is not multiple of the tile size" % args.image) + + data = list(image.convert("RGB").getdata()) + + ntiles = 0 + out = [] + for base_y in range(0, h, args.height): + for x in range(0, w, args.width): + tile = [] + for y in range(base_y, base_y + args.height): + tile.extend(data[x + y * w : x + y * w + args.width]) + out.extend(tile) + ntiles += 1 + + out_data = list(chain.from_iterable(out)) + result = Image.frombytes("RGB", (args.width, args.height * ntiles), bytes(out_data)) + with open(args.dest, "wb") as fd: + result.save(fd) + + +if __name__ == "__main__": + main() |