Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions bricks/_common/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -679,9 +679,16 @@ else
FW_SECTIONS :=
endif

$(BUILD)/pbio_image_media.c $(BUILD)/pb_type_image_attributes.c: $(MEDIA_CONVERT)
# Force rebuild if list of media sources changed.
-include $(BUILD)/media_sources_gen.mk
MEDIA_SOURCES := $(shell $(MEDIA_CONVERT) --list)
MEDIA_FORCE := $(if $(strip $(filter-out $(MEDIA_SOURCES),$(MEDIA_SOURCES_GEN)) $(filter-out $(MEDIA_SOURCES_GEN),$(MEDIA_SOURCES))),media-force)
media-force:
.PHONY: media-force

$(BUILD)/pbio_image_media.c $(BUILD)/pbio_image_media.h $(BUILD)/pb_type_image_attributes.c: $(MEDIA_CONVERT) $(MEDIA_SOURCES) $(MEDIA_FORCE)
$(ECHO) "Generating image media files"
$(Q)$(PYTHON) $(MEDIA_CONVERT) $(BUILD)
$(Q)$(PYTHON) $(MEDIA_CONVERT) --dest $(BUILD)

$(BUILD)/font_liberationsans_regular_14.c: $(PBTOP)/lib/pbio/src/image/fonts/LiberationSans-Regular.ttf $(FONT_CONVERT)
$(ECHO) "GEN $@"
Expand Down
48 changes: 35 additions & 13 deletions lib/pbio/src/image/media.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path
from PIL import Image
import cairosvg

# Take build directory as argument to save generated C files and PNG files.
parser = argparse.ArgumentParser(description="Convert image files to C structs.")
parser.add_argument("dest", help="Destination build folder for PNG files.")
parser.add_argument(
"--dest", default="build", help="Destination build folder for generated files."
)
parser.add_argument(
"--list-sources", action="store_true", help="Only list sources files."
)
args = parser.parse_args()

media_dir = Path(__file__).parent.relative_to(Path.cwd()) / "media"

# Collect all SVG and image files in media_dir (svg, png, bmp, jpg), including subfolders.
media_images_sources = (
list(media_dir.rglob("*.png"))
+ list(media_dir.rglob("*.bmp"))
+ list(media_dir.rglob("*.jpg"))
)
media_svg_sources = list(media_dir.rglob("*.svg"))
media_sources = media_images_sources + media_svg_sources
media_sources.sort()

if args.list_sources:
for m in media_sources:
print(m)
sys.exit(0)

build_dir = Path(args.dest)
build_dir.mkdir(parents=True, exist_ok=True)
media_dir = Path(__file__).parent / "media"

media_gen = []

# Convert all SVG files in media_dir to PNG and save in build_dir if not already present.
svg_files = media_dir.rglob("*.svg")
for svg in svg_files:
for svg in media_svg_sources:
png = svg.with_suffix(".png").name
png_path = build_dir / png
if png_path.exists():
media_gen.append(png_path)
if png_path.exists() and png_path.stat().st_mtime >= svg.stat().st_mtime:
continue
with open(svg, "rb") as svg_file:
png_bytes = cairosvg.svg2png(file_obj=svg_file)
with open(png_path, "wb") as out_png:
out_png.write(png_bytes)

# Collect all image files in media_dir (png, bmp, jpg) and build_dir (png), including subfolders.
media_images = (
list(media_dir.rglob("*.png"))
+ list(media_dir.rglob("*.bmp"))
+ list(media_dir.rglob("*.jpg"))
+ list(build_dir.rglob("*.png"))
)


# Convert rgba to monochrome, treating fully transparent pixels as white.
def is_black(r, g, b, a):
Expand Down Expand Up @@ -60,6 +76,7 @@ def image_to_8bit_map(img):


# Process each image.
media_images = media_images_sources + media_gen
results = {}
for img_path in media_images:
with Image.open(img_path) as img:
Expand Down Expand Up @@ -129,3 +146,8 @@ def image_to_8bit_map(img):
f.write(
"MP_DEFINE_CONST_DICT(pb_type_image_attributes_dict, pb_type_image_attributes_dict_table);"
)

with open(build_dir / "media_sources_gen.mk", "w") as f:
f.write("MEDIA_SOURCES_GEN = \\\n ")
f.write(" \\\n ".join(str(m) for m in media_sources))
f.write("\n")
Loading