diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index aaab7a3..93330c8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -8,6 +8,7 @@ repos:
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
+ args: ['--maxkb=950']
- repo: https://github.com/psf/black
rev: 24.2.0
hooks:
diff --git a/README.md b/README.md
index 9fb49e3..cfbdb5b 100644
--- a/README.md
+++ b/README.md
@@ -14,13 +14,12 @@ Takes an image file and generates a cross stitch pattern using a user specified
## Results
-Photo by [Kiki Siepel](https://unsplash.com/@studiokiek?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/images/nature/flower?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
-
+
-
-
-
-
+
+
+
+
## Usage
@@ -31,7 +30,7 @@ pip install tarraz
### CLI Example
```shell
-tarraz .tmp/palestinian_flag.jpg --colors 6 --stitches-count 100
+tarraz images/palestine.png --colors 4 --stitches-count 200
```
### Python Example
@@ -45,7 +44,7 @@ from tarraz.models import RGB
# Choose a color provider
-image_path = ".tmp/flower.jpg"
+image_path = "images/palestine.png"
provider = DMCProvider()
tarraz = Tarraz(
@@ -76,7 +75,7 @@ SVGStitcher.stitch(
### Options
```shell
$ tarraz --help
-usage: tarraz [-h] [-v] [-c COLORS] [-n STITCHES_COUNT] [-w WIDTH] [-m DMC] [-t TRANSPARENT [TRANSPARENT ...]] [-s DIST] [-z CELL_SIZE] [--no-cleanup] [--svg] image
+usage: tarraz [-h] [--version] [-c COLORS] [-n STITCHES_COUNT] [-w WIDTH] [-m DMC] [-t TRANSPARENT [TRANSPARENT ...]] [-o DIST] [-z CELL_SIZE] [--no-cleanup] [--svg] image
Generate a DMC-colored cross-stitch pattern from a given image.
@@ -95,7 +94,7 @@ optional arguments:
-m DMC, --dmc DMC DMC json color path.
-t TRANSPARENT [TRANSPARENT ...], --transparent TRANSPARENT [TRANSPARENT ...]
A Color to ignore from the end result.
- -s DIST, --dist DIST DMC json color path.
+ -o DIST, --dist DIST DMC json color path.
-z CELL_SIZE, --cell-size CELL_SIZE
The size of the generated Aida fabric cell.
--no-cleanup Don't run cleanup job on generated image.
diff --git a/images/black_white_symbols.jpg b/images/black_white_symbols.jpg
deleted file mode 100644
index d9399bb..0000000
Binary files a/images/black_white_symbols.jpg and /dev/null differ
diff --git a/images/colored.jpg b/images/colored.jpg
deleted file mode 100644
index 3369245..0000000
Binary files a/images/colored.jpg and /dev/null differ
diff --git a/images/colored_symbols.jpg b/images/colored_symbols.jpg
deleted file mode 100644
index 7bc82b8..0000000
Binary files a/images/colored_symbols.jpg and /dev/null differ
diff --git a/images/flower.jpg b/images/flower.jpg
deleted file mode 100644
index bc99b93..0000000
Binary files a/images/flower.jpg and /dev/null differ
diff --git a/images/key.jpg b/images/key.jpg
deleted file mode 100644
index 3cc821c..0000000
Binary files a/images/key.jpg and /dev/null differ
diff --git a/images/palestine.png b/images/palestine.png
new file mode 100644
index 0000000..567e326
Binary files /dev/null and b/images/palestine.png differ
diff --git a/images/results/black_white_symbols.jpg b/images/results/black_white_symbols.jpg
new file mode 100644
index 0000000..43ec466
Binary files /dev/null and b/images/results/black_white_symbols.jpg differ
diff --git a/images/results/colored.jpg b/images/results/colored.jpg
new file mode 100644
index 0000000..397d644
Binary files /dev/null and b/images/results/colored.jpg differ
diff --git a/images/results/colored_symbols.jpg b/images/results/colored_symbols.jpg
new file mode 100644
index 0000000..2f81ddd
Binary files /dev/null and b/images/results/colored_symbols.jpg differ
diff --git a/images/results/key.jpg b/images/results/key.jpg
new file mode 100644
index 0000000..205e983
Binary files /dev/null and b/images/results/key.jpg differ
diff --git a/poetry.lock b/poetry.lock
index d4aa756..21a50f4 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -283,4 +283,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[metadata]
lock-version = "2.0"
python-versions = ">=3.8"
-content-hash = "37d4f9bacb4d3c587d57e39c38450d50a7418ae4197c4fd62ac3a33f2d68aa55"
+content-hash = "546bc79e6fb6361e242d9d393a3e67dd9a92409efd0eda6ac5233055923cb0a5"
diff --git a/pyproject.toml b/pyproject.toml
index 87d7c4c..717efed 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,14 +15,14 @@ known_first_party = "tarraz"
[tool.poetry]
name = "tarraz"
-version = "1.1.2"
+version = "1.2.0"
description = "A cross-stitch image generator. Generates a cross stitch pattern given by a user and generates a DMC colored pattern."
authors = ["Ahmed Jazzar "]
maintainers = []
license = "GNU Affero General Public License v3"
readme = "README.md"
-packages = [{ include = "tarraz"}]
+packages = [{ include = "tarraz" }]
homepage = "https://www.nitfe.com/"
repository = "https://github.com/nitfe/tarraz.git"
documentation = "https://github.com/nitfe/tarraz/blob/main/README.md"
@@ -47,11 +47,11 @@ Changelog = "https://github.com/nitfe/tarraz/releases"
# Requirements
[tool.poetry.dependencies]
python = ">=3.8"
-pillow = "*"
+pillow = ">=9.5.0"
[tool.poetry.dev-dependencies]
pre-commit = { version = "*" }
# Entry point
-[tool.poetry.scripts]
-tarraz = "tarraz.main:main"
+[tool.poetry.plugins.console_scripts]
+"tarraz" = "tarraz.main:main"
diff --git a/tarraz/main.py b/tarraz/main.py
index 4a72c61..040a423 100644
--- a/tarraz/main.py
+++ b/tarraz/main.py
@@ -1,5 +1,6 @@
import argparse
import importlib.metadata
+import logging
import os
from tarraz import constants
@@ -14,7 +15,6 @@
def init_argparse() -> argparse.ArgumentParser:
parser.add_argument(
- "-v",
"--version",
action="version",
version=f"{parser.prog} version {VERSION}",
@@ -59,7 +59,7 @@ def init_argparse() -> argparse.ArgumentParser:
help="A Color to ignore from the end result.",
)
parser.add_argument(
- "-s",
+ "-o",
"--dist",
type=str,
default=constants.BASE_DIR / ".tmp/",
@@ -82,6 +82,12 @@ def init_argparse() -> argparse.ArgumentParser:
action="store_true",
help="Export result to svg files.",
)
+ parser.add_argument(
+ "-v",
+ "--verbose",
+ action="store_true",
+ help="Show debug messages.",
+ )
return parser
@@ -89,6 +95,9 @@ def main() -> None:
p = init_argparse()
args = p.parse_args()
+ if args.verbose:
+ logger.setLevel(logging.DEBUG)
+
base_file_name = os.path.basename(args.image).split(".")[0]
logger.info("Generating pattern for %s...", base_file_name)
diff --git a/tarraz/processor.py b/tarraz/processor.py
index 1d56c21..c6097a8 100644
--- a/tarraz/processor.py
+++ b/tarraz/processor.py
@@ -1,8 +1,9 @@
+from typing import TYPE_CHECKING, List, Union
+
from PIL import Image
-from typing import List, TYPE_CHECKING, Union
from tarraz.logger import logger
-from tarraz.models import Color, Coordinate, ImageSize, RGB
+from tarraz.models import RGB, Color, Coordinate, ImageSize
from tarraz.providers import DMCProvider
from tarraz.utils import generate_image, get_neighbours, index_of
@@ -31,7 +32,7 @@ def __init__(
self._cleanup = cleanup
self._colors_num = colors_num
- self._image = Image.open(image_path)
+ self._image = Image.open(image_path).convert("RGB")
self._provider = provider
self._x_count = x_count
diff --git a/tarraz/stitcher/display.py b/tarraz/stitcher/display.py
index d8ba0d8..dbfb50e 100644
--- a/tarraz/stitcher/display.py
+++ b/tarraz/stitcher/display.py
@@ -1,6 +1,7 @@
from typing import TYPE_CHECKING, Optional
from PIL import Image
+
from tarraz.stitcher import Stitcher
if TYPE_CHECKING:
@@ -12,16 +13,16 @@ def init(self, width: int, height: int) -> None:
self.result = Image.new("RGB", (width, height))
def draw_cell(
- self, color: "Optional[Color]", coordinate: "Coordinate", size: int
+ self, coordinate: "Coordinate", size: int, color: "Optional[Color]" = None
) -> None:
pixels = self.result.load()
for i in range(coordinate.x, coordinate.x + size):
for j in range(coordinate.y, coordinate.y + size):
- pixels[i - size, j - size] = color.rgb
+ pixels[i - size, j - size] = color.rgb if color else (255, 255, 255, 0)
def finish(self) -> None:
self.result.show()
- def save(self, dist_dir: str, ext: str) -> None:
+ def save(self, ext: str) -> None:
return
diff --git a/tarraz/stitcher/stitcher.py b/tarraz/stitcher/stitcher.py
index 82e6dd1..d38dcf9 100644
--- a/tarraz/stitcher/stitcher.py
+++ b/tarraz/stitcher/stitcher.py
@@ -1,13 +1,13 @@
import os
from abc import ABC
-from typing import TYPE_CHECKING, Optional, List
+from typing import TYPE_CHECKING, List, Optional
from tarraz import constants
from tarraz.logger import logger
from tarraz.models import Coordinate
if TYPE_CHECKING:
- from tarraz.models import Color, ImageSize, Palette, PaletteImage, RGB
+ from tarraz.models import RGB, Color, ImageSize, Palette, PaletteImage
class Stitcher(ABC):
@@ -56,7 +56,7 @@ def generate_key(
return NotImplemented
def draw_cell(
- self, color: "Optional[Color]", coordinate: "Coordinate", size: int
+ self, coordinate: "Coordinate", size: int, color: "Optional[Color]" = None
) -> NotImplemented:
return NotImplemented
@@ -69,6 +69,9 @@ def draw_cells(
config: "Optional[dict]" = None,
transparent: "Optional[List[RGB]]" = None,
):
+ if not transparent:
+ transparent = []
+
x = y = cell_size
for row in pattern:
for color_i in row:
@@ -76,7 +79,7 @@ def draw_cells(
color = (
colors[color_i] if colors[color_i].rgb not in transparent else None
)
- self.draw_cell(color, coordinate, cell_size)
+ self.draw_cell(coordinate, cell_size, color=color)
x += cell_size
y += cell_size
x = cell_size
@@ -104,6 +107,9 @@ def stitch(
width = size.width * cell_size
height = size.height * cell_size
+ if not transparent:
+ transparent = []
+
if not configs:
configs = [{"name": "NO_CONFIG"}]
diff --git a/tarraz/stitcher/svg.py b/tarraz/stitcher/svg.py
index ab03e97..d85c8a1 100644
--- a/tarraz/stitcher/svg.py
+++ b/tarraz/stitcher/svg.py
@@ -1,5 +1,5 @@
import os
-from typing import TYPE_CHECKING, Optional, List
+from typing import TYPE_CHECKING, List, Optional
from tarraz.logger import logger
from tarraz.models import Color, Coordinate
@@ -7,10 +7,10 @@
if TYPE_CHECKING:
from tarraz.models import (
+ RGB,
ImageSize,
Palette,
PaletteImage,
- RGB,
StrokeType,
SVGAttributes,
)
@@ -77,9 +77,9 @@ def generate_key(
keyed.add(color.code)
def draw_cell(
- self, color: "Optional[Color]", coordinate: "Coordinate", size: int
+ self, coordinate: "Coordinate", size: int, color: "Optional[Color]" = None
) -> None:
- fill, symbols, stroke = self._get_svg_attributes(color, coordinate, size)
+ fill, symbols, stroke = self._get_svg_attributes(coordinate, size, color=color)
self._append_to_file(
f"""
@@ -244,7 +244,7 @@ def _gen_glyph(color: "Color", coordinate: "Coordinate", scale: float = 1.0) ->
def _add_key_to_svg(
self, coordinate: "Coordinate", size: int, color: "Color"
) -> None:
- fill, symbols, stroke = self._get_svg_attributes(color, coordinate, size)
+ fill, symbols, stroke = self._get_svg_attributes(coordinate, size, color)
self._append_to_file(
f"""
@@ -308,7 +308,7 @@ def _add_key_to_svg(
)
def _get_svg_attributes(
- self, color: "Optional[Color]", coordinate: "Coordinate", size: int
+ self, coordinate: "Coordinate", size: int, color: "Optional[Color]" = None
) -> "SVGAttributes":
fill = "fill:rgb(255,255,255);"
stroke: "StrokeType" = "stroke:none;"