feat: add go icon support
This commit is contained in:
@@ -2,8 +2,8 @@ import logging
|
||||
from pathlib import Path
|
||||
from .assemblicon.context import Context
|
||||
from .assemblicon.utils import setup_logging
|
||||
from .image_icons import build_image_icons
|
||||
from .std_icons import build_standard_icons
|
||||
from .ext_icons import build_ext_icons
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -22,4 +22,4 @@ def main() -> None:
|
||||
|
||||
def _build_icons(ctx: Context) -> None:
|
||||
build_standard_icons(ctx)
|
||||
#build_image_icons(ctx)
|
||||
#build_ext_icons(ctx)
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import PIL.Image
|
||||
import PIL.ImageFile
|
||||
|
||||
|
||||
def load_artifact(p: Path) -> PIL.Image.ImageFile.ImageFile:
|
||||
def load_asset(p: Path) -> PIL.ImageFile.ImageFile:
|
||||
logging.info("Loading asset: %s", p)
|
||||
return PIL.Image.open(p, "r", ["PNG", "JPEG", "BMP"])
|
||||
|
||||
|
||||
def load_artifact(p: Path) -> PIL.ImageFile.ImageFile:
|
||||
logging.info("Loading artifact: %s", p)
|
||||
return PIL.Image.open(p, "r", ["PNG"])
|
||||
|
||||
|
||||
def save_artifact(art: PIL.Image.Image, p: Path) -> None:
|
||||
logging.info("Saving artifact: %s", p)
|
||||
art.save(p, format="PNG")
|
||||
|
||||
@@ -3,11 +3,11 @@ import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
|
||||
import PIL.Image
|
||||
|
||||
import PIL.ImageFile
|
||||
from .context import Context
|
||||
from .utils import Artifact
|
||||
from .artio import load_artifact
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -25,8 +25,12 @@ class InkscapeConfig:
|
||||
f"The image height in Inkscape config must be a positive integer"
|
||||
)
|
||||
|
||||
# TODO: Add "resvg" alternative for Inkscape
|
||||
# because Inkscape is too slow.
|
||||
|
||||
def inkscape_render(src: Path, dst: Path, cfg: InkscapeConfig) -> None:
|
||||
def inkscape_render(
|
||||
src: Path, dst: Path, cfg: InkscapeConfig
|
||||
) -> PIL.ImageFile.ImageFile:
|
||||
logging.info("Rendering Inkscape artifact: %s -> %s", src, dst)
|
||||
|
||||
inkscape_bin = os.getenv("ASSEMBLICON_INKSCAPE", "inkscape")
|
||||
@@ -55,6 +59,8 @@ def inkscape_render(src: Path, dst: Path, cfg: InkscapeConfig) -> None:
|
||||
f"Fail to execute Inkscape. Return code is {proc.returncode}"
|
||||
)
|
||||
|
||||
return load_artifact(dst)
|
||||
|
||||
|
||||
@dataclass
|
||||
class BlenderConfig:
|
||||
@@ -96,9 +102,11 @@ except BaseException:
|
||||
"""
|
||||
|
||||
|
||||
def blender_render(ctx: Context, src: Path, dst: Path, cfg: BlenderConfig) -> None:
|
||||
def blender_render(
|
||||
ctx: Context, src: Path, dst: Path, cfg: BlenderConfig
|
||||
) -> PIL.ImageFile.ImageFile:
|
||||
logging.info("Rendering Blender artifact: %s -> %s", src, dst)
|
||||
|
||||
|
||||
script = _BLENDER_RENDER_SCRIPT.format(
|
||||
width=cfg.width, height=cfg.height, dst=repr(str(dst))
|
||||
)
|
||||
@@ -115,14 +123,14 @@ def blender_render(ctx: Context, src: Path, dst: Path, cfg: BlenderConfig) -> No
|
||||
]
|
||||
proc = subprocess.run(cmd, capture_output=False)
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f"Fail to execute Blender. Return code is {proc.returncode}"
|
||||
)
|
||||
raise RuntimeError(f"Fail to execute Blender. Return code is {proc.returncode}")
|
||||
if not dst.exists():
|
||||
raise RuntimeError(
|
||||
f"Blender exited successfully but output file {dst} is missing"
|
||||
)
|
||||
|
||||
return load_artifact(dst)
|
||||
|
||||
|
||||
_ICON_ART_SIZE = 1024
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
from ..assemblicon.context import Context
|
||||
from .image_icons import build_image_icons
|
||||
|
||||
|
||||
def build_ext_icons(ctx: Context) -> None:
|
||||
build_image_icons(ctx)
|
||||
+12
-12
@@ -1,10 +1,11 @@
|
||||
import PIL.Image
|
||||
import PIL.ImageEnhance
|
||||
from .assemblicon.render import inkscape_render, ico_render, InkscapeConfig
|
||||
from .assemblicon.context import Context
|
||||
from .assemblicon.utils import Artifact
|
||||
from .assemblicon.geometry import MinMaxRect, PosSizeRect
|
||||
from .assemblicon.artproc import (
|
||||
from ..assemblicon.render import inkscape_render, ico_render, InkscapeConfig
|
||||
from ..assemblicon.context import Context
|
||||
from ..assemblicon.utils import Artifact
|
||||
from ..assemblicon.geometry import MinMaxRect, PosSizeRect
|
||||
from ..assemblicon.artio import load_asset, save_artifact
|
||||
from ..assemblicon.artproc import (
|
||||
aspect_ratio_scale_and_crop,
|
||||
VerticalAnchor,
|
||||
HorizontalAnchor,
|
||||
@@ -16,24 +17,23 @@ IMAGE_INNER_RECT_POSSIZE = IMAGE_INNER_RECT_MINMAX.to_pos_size_rect()
|
||||
|
||||
def build_image_icons(ctx: Context) -> None:
|
||||
# build image base
|
||||
inkscape_render(
|
||||
image_base = inkscape_render(
|
||||
ctx.input_artifact("component", "image-base.svg"),
|
||||
ctx.temporary_artifact("component", "image-base.png"),
|
||||
InkscapeConfig(1024, 1024),
|
||||
)
|
||||
# load image base
|
||||
with PIL.Image.open(
|
||||
ctx.temporary_artifact("component", "image-base.png")
|
||||
) as image_base:
|
||||
with image_base:
|
||||
_build_jpg_icon(ctx, image_base)
|
||||
|
||||
|
||||
def _build_jpg_icon(ctx: Context, base: Artifact) -> None:
|
||||
jpg_image = base.copy()
|
||||
|
||||
with PIL.Image.open(
|
||||
jpg_image_inner = load_asset(
|
||||
ctx.input_artifact("ext", "bitmap", "Niinsaare_järv.jpg")
|
||||
) as jpg_image_inner:
|
||||
)
|
||||
with jpg_image_inner:
|
||||
# crop the area which is interested by ourselves
|
||||
interest_area = PosSizeRect(2700, 0, 5016, 3888).to_min_max_rect()
|
||||
crop_jpg_image_inner = jpg_image_inner.crop(interest_area.to_pillow_tuple())
|
||||
@@ -59,7 +59,7 @@ def _build_jpg_icon(ctx: Context, base: Artifact) -> None:
|
||||
bestfit_jpg_image_inner, IMAGE_INNER_RECT_POSSIZE.to_pillow_tuple()
|
||||
)
|
||||
# build artifacts
|
||||
jpg_image.save(ctx.temporary_artifact("ext", "jpg-image.png"))
|
||||
save_artifact(jpg_image, ctx.temporary_artifact("ext", "jpg-image.png"))
|
||||
ico_render(
|
||||
ctx,
|
||||
jpg_image,
|
||||
@@ -1,14 +1,9 @@
|
||||
from pathlib import Path
|
||||
import PIL.Image
|
||||
from ..assemblicon.render import inkscape_render, ico_render, InkscapeConfig
|
||||
from ..assemblicon.render import inkscape_render, InkscapeConfig
|
||||
from ..assemblicon.context import Context
|
||||
from ..assemblicon.utils import Artifact
|
||||
from ..assemblicon.geometry import MinMaxRect, PosSizeRect
|
||||
from ..assemblicon.artproc import (
|
||||
aspect_ratio_scale_and_crop,
|
||||
VerticalAnchor,
|
||||
HorizontalAnchor,
|
||||
)
|
||||
from ..assemblicon.artio import save_artifact
|
||||
|
||||
|
||||
def build_action_icons(ctx: Context) -> None:
|
||||
@@ -17,27 +12,44 @@ def build_action_icons(ctx: Context) -> None:
|
||||
|
||||
def _build_go_icons(ctx: Context) -> None:
|
||||
# build go-* base
|
||||
inkscape_render(
|
||||
go_base = inkscape_render(
|
||||
ctx.input_artifact("component", "go-base.svg"),
|
||||
ctx.temporary_artifact("component", "go-base.png"),
|
||||
InkscapeConfig(1024, 1024),
|
||||
)
|
||||
# build go-* shining
|
||||
inkscape_render(
|
||||
go_shining = inkscape_render(
|
||||
ctx.input_artifact("component", "go-inner-shining.svg"),
|
||||
ctx.temporary_artifact("component", "go-inner-shining.png"),
|
||||
InkscapeConfig(1024, 1024),
|
||||
)
|
||||
|
||||
with PIL.Image.open(ctx.temporary_artifact("component", "go-base.png")) as go_base:
|
||||
with PIL.Image.open(
|
||||
ctx.temporary_artifact("component", "go-inner-shining.png")
|
||||
) as go_shining:
|
||||
_build_go_icon(ctx, go_base, go_shining, ctx.input_artifact("go-previous.svg"))
|
||||
_build_go_icon(ctx, go_base, go_shining, ctx.input_artifact("go-next.svg"))
|
||||
with go_base, go_shining:
|
||||
_build_go_icon(
|
||||
ctx,
|
||||
go_base,
|
||||
go_shining,
|
||||
ctx.input_artifact("go-previous.svg"),
|
||||
ctx.temporary_artifact("go-previous.png"),
|
||||
ctx.output_artifact("go-previous.png")
|
||||
)
|
||||
_build_go_icon(
|
||||
ctx,
|
||||
go_base,
|
||||
go_shining,
|
||||
ctx.input_artifact("go-next.svg"),
|
||||
ctx.temporary_artifact("go-next.png"),
|
||||
ctx.output_artifact("go-next.png")
|
||||
)
|
||||
|
||||
|
||||
def _build_go_icon(ctx: Context, base: Artifact, shining: Artifact, mask: Path) -> None:
|
||||
def _build_go_icon(
|
||||
ctx: Context, base: Artifact, shining: Artifact, mask: Path, mask_dst: Path, dst: Path
|
||||
) -> None:
|
||||
go = base.copy()
|
||||
|
||||
# render shining with mask
|
||||
go_mask = inkscape_render(mask, mask_dst, InkscapeConfig(1024, 1024))
|
||||
go.paste(shining, (0, 0), go_mask)
|
||||
# save as image
|
||||
save_artifact(go, dst)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user