Version 1.1.7 fügt PNG to JPEG Funktion hinzu. Ist das komprimierte PNG immer noch >500 KB wird versucht, dies als JPEG mit quality=90 zu konvertieren, das ist oft sehr viel besser komprimiert
This commit is contained in:
@@ -23,11 +23,13 @@ class TestPptxImageCompress(unittest.TestCase):
|
||||
orig_size=1000,
|
||||
chosen_size=800,
|
||||
slide_nr="[1, 2]",
|
||||
image_type_changed="",
|
||||
)
|
||||
line = pic.image_result_to_log_line(image_result)
|
||||
self.assertIn("image1.png", line)
|
||||
self.assertIn("[1, 2]", line)
|
||||
self.assertIn("20.0", line)
|
||||
self.assertTrue(line.endswith(";\n"))
|
||||
|
||||
def test_process_image_file_replaces_when_smaller(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
@@ -57,6 +59,40 @@ class TestPptxImageCompress(unittest.TestCase):
|
||||
self.assertEqual(img.stat().st_size, 40)
|
||||
self.assertEqual(result.slide_nr, "[1]")
|
||||
|
||||
def test_process_image_file_converts_large_png_to_jpg(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
root = Path(td)
|
||||
img = root / "image1.png"
|
||||
img.write_bytes(b"A" * 800000)
|
||||
scratch = root / "scratch"
|
||||
|
||||
def fake_compressor(original: Path, out_dir: Path, caesium_threads: int | None, quality: int, min_savings: str, output_format: str = "original"):
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
if output_format == "jpeg":
|
||||
out = out_dir / "image1.jpg"
|
||||
out.write_bytes(b"C" * 200000)
|
||||
return out
|
||||
out = out_dir / original.name
|
||||
out.write_bytes(b"B" * 700000)
|
||||
return out
|
||||
|
||||
result = pic.process_image_file(
|
||||
idx=1,
|
||||
img_path=img,
|
||||
scratch_dir=scratch,
|
||||
image_to_slides={"image1.png": [2]},
|
||||
caesium_threads=1,
|
||||
quality=90,
|
||||
min_savings="2%",
|
||||
compressor=fake_compressor,
|
||||
)
|
||||
|
||||
self.assertEqual(result.image_name, "image1.jpg")
|
||||
self.assertEqual(result.chosen_size, 200000)
|
||||
self.assertEqual(result.image_type_changed, "png_jpg")
|
||||
self.assertFalse(img.exists())
|
||||
self.assertTrue((root / "image1.jpg").exists())
|
||||
|
||||
def test_process_image_file_keeps_original_when_bigger(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
root = Path(td)
|
||||
@@ -84,6 +120,7 @@ class TestPptxImageCompress(unittest.TestCase):
|
||||
self.assertEqual(result.chosen_size, 100)
|
||||
self.assertEqual(img.stat().st_size, 100)
|
||||
self.assertEqual(result.slide_nr, "NOT_USED")
|
||||
self.assertEqual(result.image_type_changed, "")
|
||||
|
||||
def test_process_single_deck_with_injected_compressor(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
@@ -136,8 +173,75 @@ class TestPptxImageCompress(unittest.TestCase):
|
||||
if log_file is None:
|
||||
self.fail("log_file should not be None")
|
||||
log_text = Path(log_file).read_text(encoding="utf-8")
|
||||
self.assertIn("image_name;size_before(kb);size_after(kb);saving(kb);saving_percent(%);in_slide_number;image_type_changed", log_text)
|
||||
self.assertIn("image1.png", log_text)
|
||||
self.assertIn("[1]", log_text)
|
||||
def test_process_single_deck_updates_rels_on_png_to_jpg(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
root = Path(td)
|
||||
input_pptx = root / "input_convert.pptx"
|
||||
output_pptx = root / "output_convert.pptx"
|
||||
source_tree = root / "src_convert"
|
||||
rels_dir = source_tree / "ppt" / "slides" / "_rels"
|
||||
media_dir = source_tree / "ppt" / "media"
|
||||
rels_dir.mkdir(parents=True, exist_ok=True)
|
||||
media_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
rels_xml = (
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
|
||||
"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">"
|
||||
"<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image1.png\"/>"
|
||||
"</Relationships>"
|
||||
)
|
||||
content_types_xml = (
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
|
||||
"<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"
|
||||
"<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>"
|
||||
"<Default Extension=\"xml\" ContentType=\"application/xml\"/>"
|
||||
"<Default Extension=\"png\" ContentType=\"image/png\"/>"
|
||||
"</Types>"
|
||||
)
|
||||
(source_tree / "[Content_Types].xml").write_text(content_types_xml, encoding="utf-8")
|
||||
(rels_dir / "slide1.xml.rels").write_text(rels_xml, encoding="utf-8")
|
||||
(media_dir / "image1.png").write_bytes(b"A" * 800000)
|
||||
|
||||
with zipfile.ZipFile(input_pptx, "w", compression=zipfile.ZIP_DEFLATED) as z:
|
||||
for p in source_tree.rglob("*"):
|
||||
if p.is_file():
|
||||
z.write(p, arcname=str(p.relative_to(source_tree)))
|
||||
|
||||
def fake_compressor(original: Path, out_dir: Path, caesium_threads: int | None, quality: int, min_savings: str, output_format: str = "original"):
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
if output_format == "jpeg":
|
||||
out = out_dir / "image1.jpg"
|
||||
out.write_bytes(b"C" * 200000)
|
||||
return out
|
||||
out = out_dir / original.name
|
||||
out.write_bytes(b"B" * 700000)
|
||||
return out
|
||||
|
||||
result = pic.process_single_deck(
|
||||
input_pptx=input_pptx,
|
||||
output_pptx=output_pptx,
|
||||
threads=1,
|
||||
quality=90,
|
||||
min_savings="2%",
|
||||
compressor=fake_compressor,
|
||||
)
|
||||
|
||||
self.assertTrue(result.ok)
|
||||
with zipfile.ZipFile(output_pptx, "r") as z:
|
||||
self.assertIn("ppt/media/image1.jpg", z.namelist())
|
||||
self.assertNotIn("ppt/media/image1.png", z.namelist())
|
||||
rels_out = z.read("ppt/slides/_rels/slide1.xml.rels").decode("utf-8")
|
||||
content_types_out = z.read("[Content_Types].xml").decode("utf-8")
|
||||
self.assertIn("image1.jpg", rels_out)
|
||||
self.assertIn("Extension=\"jpg\"", content_types_out)
|
||||
log_file = result.log_file
|
||||
if log_file is None:
|
||||
self.fail("log_file should not be None")
|
||||
log_text = Path(log_file).read_text(encoding="utf-8")
|
||||
self.assertIn("png_jpg", log_text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user