#!/usr/bin/env python3 # # Rotate tiles # Copyright (C) 2023 by Juan J. Martinez # # 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 ", ) 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()