1717from resizeimage .imageexceptions import ImageSizeError
1818
1919from zimscraperlib .image import presets
20- from zimscraperlib .image .conversion import convert_image , create_favicon
20+ from zimscraperlib .image .conversion import (
21+ convert_image ,
22+ convert_svg2png ,
23+ create_favicon ,
24+ )
2125from zimscraperlib .image .optimization import (
2226 ensure_matches ,
2327 get_optimization_method ,
@@ -64,8 +68,15 @@ def get_src_dst(
6468 jpg_image : pathlib .Path | None = None ,
6569 gif_image : pathlib .Path | None = None ,
6670 webp_image : pathlib .Path | None = None ,
71+ svg_image : pathlib .Path | None = None ,
6772) -> tuple [pathlib .Path , pathlib .Path ]:
68- options = {"png" : png_image , "jpg" : jpg_image , "webp" : webp_image , "gif" : gif_image }
73+ options = {
74+ "png" : png_image ,
75+ "jpg" : jpg_image ,
76+ "webp" : webp_image ,
77+ "gif" : gif_image ,
78+ "svg" : svg_image ,
79+ }
6980 if fmt not in options :
7081 raise LookupError (f"Unsupported fmt passed: { fmt } " )
7182 src = options [fmt ]
@@ -328,6 +339,42 @@ def test_convert_path_src_io_dst(png_image: pathlib.Path):
328339 assert dst_image .format == "PNG"
329340
330341
342+ def test_convert_svg_io_src_path_dst (svg_image : pathlib .Path , tmp_path : pathlib .Path ):
343+ src = io .BytesIO (svg_image .read_bytes ())
344+ dst = tmp_path / "test.png"
345+ convert_svg2png (src , dst )
346+ dst_image = Image .open (dst )
347+ assert dst_image .format == "PNG"
348+
349+
350+ def test_convert_svg_io_src_io_dst (svg_image : pathlib .Path ):
351+ src = io .BytesIO (svg_image .read_bytes ())
352+ dst = io .BytesIO ()
353+ convert_svg2png (src , dst )
354+ dst_image = Image .open (dst )
355+ assert dst_image .format == "PNG"
356+
357+
358+ def test_convert_svg_path_src_path_dst (svg_image : pathlib .Path , tmp_path : pathlib .Path ):
359+ src = svg_image
360+ dst = tmp_path / "test.png"
361+ convert_svg2png (src , dst , width = 96 , height = 96 )
362+ dst_image = Image .open (dst )
363+ assert dst_image .format == "PNG"
364+ assert dst_image .width == 96
365+ assert dst_image .height == 96
366+
367+
368+ def test_convert_svg_path_src_io_dst (svg_image : pathlib .Path ):
369+ src = svg_image
370+ dst = io .BytesIO ()
371+ convert_svg2png (src , dst , width = 96 , height = 96 )
372+ dst_image = Image .open (dst )
373+ assert dst_image .format == "PNG"
374+ assert dst_image .width == 96
375+ assert dst_image .height == 96
376+
377+
331378@pytest .mark .parametrize (
332379 "fmt,exp_size" ,
333380 [("png" , 128 ), ("jpg" , 128 )],
@@ -576,10 +623,10 @@ def test_ensure_matches(webp_image):
576623
577624@pytest .mark .parametrize (
578625 "fmt,expected" ,
579- [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" )],
626+ [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" ), ( "svg" , "SVG" ) ],
580627)
581628def test_format_for_real_images_suffix (
582- png_image , jpg_image , gif_image , webp_image , tmp_path , fmt , expected
629+ png_image , jpg_image , gif_image , webp_image , svg_image , tmp_path , fmt , expected
583630):
584631 src , _ = get_src_dst (
585632 tmp_path ,
@@ -588,16 +635,17 @@ def test_format_for_real_images_suffix(
588635 jpg_image = jpg_image ,
589636 gif_image = gif_image ,
590637 webp_image = webp_image ,
638+ svg_image = svg_image ,
591639 )
592640 assert format_for (src ) == expected
593641
594642
595643@pytest .mark .parametrize (
596644 "fmt,expected" ,
597- [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" )],
645+ [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" ), ( "svg" , "SVG" ) ],
598646)
599647def test_format_for_real_images_content_path (
600- png_image , jpg_image , gif_image , webp_image , tmp_path , fmt , expected
648+ png_image , jpg_image , gif_image , webp_image , svg_image , tmp_path , fmt , expected
601649):
602650 src , _ = get_src_dst (
603651 tmp_path ,
@@ -606,16 +654,17 @@ def test_format_for_real_images_content_path(
606654 jpg_image = jpg_image ,
607655 gif_image = gif_image ,
608656 webp_image = webp_image ,
657+ svg_image = svg_image ,
609658 )
610659 assert format_for (src , from_suffix = False ) == expected
611660
612661
613662@pytest .mark .parametrize (
614663 "fmt,expected" ,
615- [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" )],
664+ [("png" , "PNG" ), ("jpg" , "JPEG" ), ("gif" , "GIF" ), ("webp" , "WEBP" ), ( "svg" , "SVG" ) ],
616665)
617666def test_format_for_real_images_content_bytes (
618- png_image , jpg_image , gif_image , webp_image , tmp_path , fmt , expected
667+ png_image , jpg_image , gif_image , webp_image , svg_image , tmp_path , fmt , expected
619668):
620669 src , _ = get_src_dst (
621670 tmp_path ,
@@ -624,6 +673,7 @@ def test_format_for_real_images_content_bytes(
624673 jpg_image = jpg_image ,
625674 gif_image = gif_image ,
626675 webp_image = webp_image ,
676+ svg_image = svg_image ,
627677 )
628678 assert format_for (io .BytesIO (src .read_bytes ()), from_suffix = False ) == expected
629679
@@ -635,6 +685,7 @@ def test_format_for_real_images_content_bytes(
635685 ("image.jpg" , "JPEG" ),
636686 ("image.gif" , "GIF" ),
637687 ("image.webp" , "WEBP" ),
688+ ("image.svg" , "SVG" ),
638689 ("image.raster" , None ),
639690 ],
640691)
0 commit comments