Skip to content

Commit

Permalink
Allow specify directly svg images in definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
pablerass committed Dec 17, 2023
1 parent f66a8d9 commit 9201fd8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
4 changes: 2 additions & 2 deletions cartuli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .output import sheet_output, sheet_pdf_output
from .filters import MultipleFilter, StraightenFilter, InpaintFilter, CropFilter
from .processing import inpaint, straighten, crop
from .templater import SVGTemplate
from .templater import SVGTemplate, svg_file_to_image, svg_content_to_image
from .definition import Definition, DefinitionError


Expand All @@ -27,6 +27,6 @@
sheet_output, sheet_pdf_output,
MultipleFilter, StraightenFilter, InpaintFilter, CropFilter,
inpaint, straighten, crop,
SVGTemplate,
SVGTemplate, svg_file_to_image, svg_content_to_image,
Definition, DefinitionError
]
20 changes: 17 additions & 3 deletions cartuli/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
from itertools import chain, groupby
from multiprocessing import Pool, cpu_count
from pathlib import Path
from PIL import Image

from .card import CardImage, Card
from .deck import Deck
from .filters import Filter, NullFilter, from_dict as filter_from_dict
from .measure import Size, from_str
from .sheet import Sheet
from .templater import svg_file_to_image


_CONCURRENT_PROCESSES = cpu_count() - 1
Expand All @@ -27,6 +29,17 @@ class DefinitionError(Exception):
pass


def _load_image(image_file: str | Path) -> Image.Image:
# TUNE: I am tired of writting this and probably image_file = Path(image_file) will do the trick
if isinstance(image_file, str):
image_file = Path(image_file)

if image_file.suffix == '.svg':
return svg_file_to_image(image_file)
else:
return Image.open(image_file)


class Definition:
"""Definition."""

Expand Down Expand Up @@ -79,7 +92,8 @@ def decks(self) -> list[Deck]:

return self.__decks

def _load_images(self, images_definition: dict, size: Size, deck_name: str, side: str = 'front') -> list[CardImage]:
def _load_images(self, images_definition: dict, size: Size,
deck_name: str, side: str = 'front') -> list[CardImage]:
logger = logging.getLogger('cartuli.definition.Definition.decks')

image_filter = images_definition.get('filter', '')
Expand All @@ -89,7 +103,7 @@ def _load_images(self, images_definition: dict, size: Size, deck_name: str, side
images = pool.map(
self.filters[image_filter].apply,
(CardImage(
path, size=size,
_load_image(path), size=size,
bleed=from_str(images_definition.get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(path).stem
) for path in image_files if self.__cards_filter(path))
Expand Down Expand Up @@ -130,7 +144,7 @@ def _load_deck(self, definition: dict, name: str) -> Deck:
default_back_filter = definition['default_back'].get('filter', '')
default_back = self.filters[default_back_filter].apply(
CardImage(
default_back_file,
_load_image(default_back_file),
size=size,
bleed=from_str(definition['default_back'].get('bleed', str(CardImage.DEFAULT_BLEED))),
name=Path(default_back_file).stem
Expand Down
30 changes: 26 additions & 4 deletions cartuli/templater.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from typing import Iterable


DEFAULT_SVG_DPI = 300

TemplateContent = str
ParameterKey = str
ParameterValue = Image.Image | str
Expand Down Expand Up @@ -48,8 +50,25 @@ def _get_template_image(image_element: etree._Element, encoding: str = 'UTF-8')
return Image.open(io.BytesIO(base64.b64decode(base64_image)))


# TUNE: Probably this should not be implemented here
def svg_file_to_image(svg_file: str | Path, dpi: int = DEFAULT_SVG_DPI) -> Image.Image:
if isinstance(svg_file, str):
svg_file = Path(svg_file)

image_data = svg2png(bytestring=svg_file.read_bytes(), dpi=dpi)

return Image.open(io.BytesIO(image_data))


def svg_content_to_image(svg_content: str, dpi: int = DEFAULT_SVG_DPI) -> Image.Image:
image_data = svg2png(bytestring=svg_content, dpi=dpi)

return Image.open(io.BytesIO(image_data))


class SVGTemplate:
def __init__(self, template: TemplateContent | etree._Element, parameters: Iterable[ParameterKey]):
def __init__(self, template: TemplateContent | etree._Element, parameters: Iterable[ParameterKey],
dpi: int = DEFAULT_SVG_DPI):
if not parameters:
raise ValueError("A template withoyt parameters does not make any sense")

Expand All @@ -72,11 +91,16 @@ def __init__(self, template: TemplateContent | etree._Element, parameters: Itera
raise ValueError(f"Parameter '{parameter}' element '{element.tag}' is unsupported")

self.__parameters = parameters
self.__dpi = dpi

@property
def parameters(self) -> dict[ParameterKey, type]:
return self.__parameters.copy()

@property
def dpi(self) -> int:
return self.__dpi

@classmethod
def from_file(cls, template_file: str | Path, parameters: Iterable[ParameterKey]) -> SVGTemplate:
if isinstance(template_file, str):
Expand Down Expand Up @@ -111,9 +135,7 @@ def apply_parameters(self, parameters: dict[ParameterKey, ParameterValue]) -> Te
def create_image(self, parameters: dict[ParameterKey, ParameterValue]) -> Image.Image:
svg_content = self.apply_parameters(parameters)

image_data = svg2png(bytestring=svg_content)

return Image.open(io.BytesIO(image_data))
return svg_content_to_image(svg_content, dpi=self.__dpi)

def get_values(self, content: TemplateContent | etree._Element,
parameters: tuple(ParameterKey) = None) -> dict[ParameterKey, ParameterValue]:
Expand Down

0 comments on commit 9201fd8

Please sign in to comment.