diff --git a/README.md b/README.md index 7ad7d32..f72ac69 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -[![Generic badge](https://img.shields.io/badge/status-draft-red.svg)](#) [![PyPI version shields.io](https://img.shields.io/pypi/v/img2texture.svg)](https://pypi.python.org/pypi/img2texture/) [![Generic badge](https://img.shields.io/badge/Python-3.7+-blue.svg)](#) [![Generic badge](https://img.shields.io/badge/OS-Windows%20|%20macOS%20|%20Linux-blue.svg)](#) @@ -45,7 +44,53 @@ $ pip3 install img2texture # Run +Create new `seamless.jpg` from `source.jpg`. ``` -$ img2texture /path/to/source.jpg /path/to/seamless_result.jpg +$ img2texture /path/to/source.jpg /path/to/seamless.jpg ``` +## --overlap + +The `--overlap` option determines how much of the image will be used to hide the seams. + +For example, the following command uses 25% of the width and 25% of the height +of the original image: + +``` +$ img2texture source.jpg seamless.jpg --overlap 0.25 +``` + +Increasing the value makes the seam less visible. However, the image becomes smaller. + +
+ Sample images + +:warning: If images don't load, check out the [original of this document on GitHub](https://github.com/rtmigo/img2texture_py#readme). + +### --overlap 0.05 + +The 5% seam. + +![--overlap 0.05](docs/3_orion_05_2x2.jpg) + + + +### --overlap 0.4 + +The 40% seam. + +![--overlap 40](docs/3_orion_40_2x2.jpg) + +
+ +## --tile + +The `--tile` option will create a 2x2 tiled version in addition to the converted image. + +The following command will create `seamless.jpg` and `seamless_2x2.jpg`. + +``` +$ img2texture source.jpg seamless.jpg --tile +``` + +All the samples on this page were created with `--tile`. diff --git a/docs/3_orion_05.jpg b/docs/3_orion_05.jpg new file mode 100644 index 0000000..6396b40 Binary files /dev/null and b/docs/3_orion_05.jpg differ diff --git a/docs/3_orion_05_2x2.jpg b/docs/3_orion_05_2x2.jpg new file mode 100644 index 0000000..7dfb32f Binary files /dev/null and b/docs/3_orion_05_2x2.jpg differ diff --git a/docs/3_orion_40.jpg b/docs/3_orion_40.jpg new file mode 100644 index 0000000..11c5d0e Binary files /dev/null and b/docs/3_orion_40.jpg differ diff --git a/docs/3_orion_40_2x2.jpg b/docs/3_orion_40_2x2.jpg new file mode 100644 index 0000000..b7b6b62 Binary files /dev/null and b/docs/3_orion_40_2x2.jpg differ diff --git a/docs/3_orion_51.jpg b/docs/3_orion_51.jpg new file mode 100644 index 0000000..11c5d0e Binary files /dev/null and b/docs/3_orion_51.jpg differ diff --git a/docs/3_orion_51_2x2.jpg b/docs/3_orion_51_2x2.jpg new file mode 100644 index 0000000..b7b6b62 Binary files /dev/null and b/docs/3_orion_51_2x2.jpg differ diff --git a/img.png b/img.png new file mode 100644 index 0000000..38df862 Binary files /dev/null and b/img.png differ diff --git a/img2texture/__main__.py b/img2texture/__main__.py new file mode 100644 index 0000000..7c4a768 --- /dev/null +++ b/img2texture/__main__.py @@ -0,0 +1,4 @@ +from . import cli + +if __name__ == "__main__": + cli() diff --git a/img2texture/_cli.py b/img2texture/_cli.py index eac0233..6cf01ff 100644 --- a/img2texture/_cli.py +++ b/img2texture/_cli.py @@ -4,13 +4,14 @@ from enum import Enum from pathlib import Path +import img2texture._constants as constants from img2texture import img2tex -from ._constants import __version__ as version, __copyright__ as copyright +# import __version__ as version, __copyright__ as copyright from ._tiling import tile def print_version(): - print(f'img2texture {version} {copyright}') + print(f'img2texture {constants.__version__} {constants.__copyright__}') class Mode(Enum): @@ -18,29 +19,44 @@ class Mode(Enum): none = "none" +def confirm(message: str) -> bool: + while True: + answer = input(f"{message} (y/n) ").upper() + if answer.startswith("Y"): + return True + if answer.startswith("N"): + return False + + class ParsedArgs: def __init__(self): if "--version" in sys.argv: print_version() exit(0) - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser(description="Converts images to seamless tiles") - parser.add_argument("-m", "--mix", - type=float, - default=0.2) parser.add_argument("source", help="Path of source image file.") parser.add_argument("target", help="Path of the converted file.") - parser.add_argument("--tile", + parser.add_argument("-o", "--overlap", + type=float, + default=0.2, + help="Fraction of the original width and height to " + "use for overlapping seam. Default: 0.2 " + "(i.e. 20%%)") + parser.add_argument("-t", "--tile", action='store_true', default=False, help="Create an additional file with four copies " "of the converted image merged side by side") + + # hidden option parser.add_argument("--mode", choices=[str(m.value) for m in Mode], - default=Mode.both) + default=Mode.both, + help=argparse.SUPPRESS) parser.add_argument('--version', action='store_true', default=False, @@ -48,6 +64,9 @@ def __init__(self): self._parsed = parser.parse_args() + if not 0 <= self.overlap_pct <= 1.0: + parser.error("--overlap must be in range from 0 to 1") + @property def source(self) -> Path: return Path(self._parsed.source) @@ -57,8 +76,8 @@ def target(self) -> Path: return Path(self._parsed.target) @property - def mix(self) -> float: - return self._parsed.mix + def overlap_pct(self) -> float: + return self._parsed.overlap @property def mode(self) -> Mode: @@ -78,10 +97,21 @@ def tile_filename(texture: Path) -> Path: def cli(): args = ParsedArgs() - img2tex(args.source, args.target, pct=args.mix) + + if args.target.exists(): + if not confirm(f"File '{args.target.name}' exists. Overwrite?"): + exit(3) + os.remove(args.target) + + img2tex(args.source, args.target, pct=args.overlap_pct) + if args.tile: tile_src = args.target if args.mode != Mode.none else args.source tile_fn = tile_filename(tile_src) + if tile_fn.exists() and not confirm( + f"File '{tile_fn}' exists. Overwrite?"): + exit(3) + if tile_fn.exists(): os.remove(tile_fn) tile(tile_src, tile_fn, horizontal=2, vertical=2) diff --git a/img2texture/_constants.py b/img2texture/_constants.py index 1d4c5fb..696c905 100644 --- a/img2texture/_constants.py +++ b/img2texture/_constants.py @@ -1,4 +1,4 @@ -__version__ = "0.0.1" +__version__ = "0.1.0" __copyright__ = "(c) 2021 Artyom Galkin " __license__ = "MIT" diff --git a/setup.py b/setup.py index dd5f28d..9d5d990 100644 --- a/setup.py +++ b/setup.py @@ -17,6 +17,7 @@ def load_module_dict(filename: str) -> dict: constants = load_module_dict(f'{name}/_constants.py') readme = (Path(__file__).parent / 'README.md').read_text(encoding="utf-8") +readme = "#"+readme.partition('\n#')[-1] setup( name=name, @@ -59,4 +60,3 @@ def load_module_dict(filename: str) -> dict: test_suite="test_unit.suite" ) - diff --git a/test_pkg.py b/test_pkg.py index 26346db..6bb7d18 100644 --- a/test_pkg.py +++ b/test_pkg.py @@ -2,7 +2,14 @@ if __name__ == "__main__": with Package() as pkg: + # running console_scripts defined in setup.py pkg.run_shell_code('img2texture --help') pkg.run_shell_code('img2texture', expected_return_code=2) + # running img2texture/__main__.py + pkg.run_shell_code('python -m img2texture', + expected_return_code=2) + pkg.run_shell_code('python -m img2texture --help', + expected_return_code=0) + print("\nPackage is OK!")