Enhance thumbnail generation
This commit is contained in:
@@ -9,11 +9,17 @@ from pathlib import Path
|
||||
from a1_swap_mod_packer.builder import (
|
||||
preview_members_for_gcode_member,
|
||||
resolve_output_gcode_member,
|
||||
select_preview_sources,
|
||||
write_output_3mf,
|
||||
)
|
||||
from a1_swap_mod_packer.metadata import read_model_settings_gcode_members
|
||||
from a1_swap_mod_packer.models import BuildOptions, PlateSource
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except Exception: # pragma: no cover
|
||||
Image = None
|
||||
|
||||
|
||||
class ActivePlateMemberTest(unittest.TestCase):
|
||||
def test_write_output_preserves_configured_plate_member(self) -> None:
|
||||
@@ -56,8 +62,72 @@ class ActivePlateMemberTest(unittest.TestCase):
|
||||
self.assertEqual(archive.read("Metadata/plate_2.gcode.md5").decode(), md5)
|
||||
self.assertEqual(md5, hashlib.md5(gcode_bytes).hexdigest())
|
||||
|
||||
def test_preview_composite_uses_first_nine_unique_input_files(self) -> None:
|
||||
if Image is None:
|
||||
self.skipTest("Pillow is not installed")
|
||||
|
||||
colors = [
|
||||
(255, 0, 0, 255),
|
||||
(0, 0, 255, 255),
|
||||
(255, 255, 0, 255),
|
||||
(255, 0, 255, 255),
|
||||
(0, 255, 255, 255),
|
||||
(128, 0, 0, 255),
|
||||
(0, 0, 128, 255),
|
||||
(128, 128, 0, 255),
|
||||
(128, 0, 128, 255),
|
||||
(255, 128, 0, 255),
|
||||
]
|
||||
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
sources: list[PlateSource] = []
|
||||
for index, color in enumerate(colors):
|
||||
source_3mf = root / f"source_{index}.3mf"
|
||||
self.write_plate2_archive(source_3mf, image_color=color, image_size=300)
|
||||
sources.append(
|
||||
PlateSource(
|
||||
source_3mf=source_3mf,
|
||||
member_name="Metadata/plate_2.gcode",
|
||||
gcode_text="G1 X0\n",
|
||||
)
|
||||
)
|
||||
|
||||
selected = select_preview_sources(sources)
|
||||
self.assertEqual(len(selected), 9)
|
||||
self.assertEqual(selected[-1].source_3mf.name, "source_8.3mf")
|
||||
|
||||
output_3mf = root / "out.3mf"
|
||||
options = BuildOptions(
|
||||
swap_gcode="",
|
||||
output_3mf=output_3mf,
|
||||
add_preview_label=True,
|
||||
apply_gcode_patches=False,
|
||||
)
|
||||
write_output_3mf(sources[0].source_3mf, output_3mf, b"G1 X1\n", sources, options)
|
||||
|
||||
with zipfile.ZipFile(output_3mf, "r") as archive:
|
||||
image_bytes = archive.read("Metadata/plate_2.png")
|
||||
|
||||
import io
|
||||
|
||||
image = Image.open(io.BytesIO(image_bytes)).convert("RGBA")
|
||||
sampled_colors = {
|
||||
image.getpixel((50, 50)),
|
||||
image.getpixel((150, 50)),
|
||||
image.getpixel((250, 50)),
|
||||
image.getpixel((50, 150)),
|
||||
image.getpixel((150, 150)),
|
||||
image.getpixel((250, 150)),
|
||||
image.getpixel((50, 250)),
|
||||
image.getpixel((150, 250)),
|
||||
image.getpixel((250, 250)),
|
||||
}
|
||||
self.assertTrue(set(colors[:9]).issubset(sampled_colors))
|
||||
self.assertNotIn(colors[9], sampled_colors)
|
||||
|
||||
@staticmethod
|
||||
def write_plate2_archive(path: Path) -> None:
|
||||
def write_plate2_archive(path: Path, image_color: tuple[int, int, int, int] | None = None, image_size: int = 128) -> None:
|
||||
model_settings = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config>
|
||||
<plate>
|
||||
@@ -82,8 +152,20 @@ class ActivePlateMemberTest(unittest.TestCase):
|
||||
archive.writestr("Metadata/slice_info.config", slice_info)
|
||||
archive.writestr("Metadata/plate_2.gcode", "G1 X0\n")
|
||||
archive.writestr("Metadata/plate_2.gcode.md5", "old")
|
||||
archive.writestr("Metadata/plate_2.png", b"png")
|
||||
archive.writestr("Metadata/plate_2_small.png", b"png")
|
||||
if image_color is None or Image is None:
|
||||
archive.writestr("Metadata/plate_2.png", b"png")
|
||||
archive.writestr("Metadata/plate_2_small.png", b"png")
|
||||
else:
|
||||
import io
|
||||
|
||||
image = Image.new("RGBA", (image_size, image_size), image_color)
|
||||
output = io.BytesIO()
|
||||
image.save(output, format="PNG")
|
||||
archive.writestr("Metadata/plate_2.png", output.getvalue())
|
||||
small = image.resize((max(1, image_size // 2), max(1, image_size // 2)))
|
||||
output = io.BytesIO()
|
||||
small.save(output, format="PNG")
|
||||
archive.writestr("Metadata/plate_2_small.png", output.getvalue())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user