Coverage for pyguymer3/media/images2webp.py: 5%

22 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def images2webp( 

5 imgs, 

6 webp, 

7 /, 

8 *, 

9 exif = None, 

10 fps = 25.0, 

11 lossless = False, 

12 method = 6, 

13 minimize_size = True, 

14 mode = "RGB", 

15 quality = 100, 

16 screenHeight = -1, 

17 screenWidth = -1, 

18): 

19 """Convert a sequence of images to a WEBP animation. 

20 

21 This function makes a WEBP animation from either a list of PIL Images or a 

22 list of file paths. The user is able to set the framerate. 

23 

24 Parameters 

25 ---------- 

26 imgs : list of PIL.Image.Image or list of str 

27 the list of input PIL Images or list of paths to the input images 

28 webp : str 

29 the path to the output WEBP 

30 exif : dict, optional 

31 a dictionary of EXIF data to save in the output WEBP (default None) 

32 fps : float, optional 

33 the framerate, default 25.0 

34 lossless : bool, optional 

35 save a lossless WEBP (default False) 

36 method : int, optional 

37 the method to use when saving the WEBP (default 6) 

38 minimize_size : bool, optional 

39 minimize the output size (default True) 

40 mode : str, optional 

41 the mode of the outout WEBP (default "RGB") 

42 quality : int, optional 

43 the quality of the output WEBP (default 100) 

44 screenHeight : int, optional 

45 the height of the screen to downscale the input images to fit within, 

46 currently only implemented if "imgs" is a list of str (default -1; 

47 integers less than 100 imply no downscaling) 

48 screenWidth : int, optional 

49 the width of the screen to downscale the input images to fit within, 

50 currently only implemented if "imgs" is a list of str (default -1; 

51 integers less than 100 imply no downscaling) 

52 

53 Notes 

54 ----- 

55 Copyright 2017 Thomas Guymer [1]_ 

56 

57 References 

58 ---------- 

59 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

60 """ 

61 

62 # Import special modules ... 

63 try: 

64 import PIL 

65 import PIL.Image 

66 PIL.Image.MAX_IMAGE_PIXELS = 1024 * 1024 * 1024 # [px] 

67 except: 

68 raise Exception("\"PIL\" is not installed; run \"pip install --user Pillow\"") from None 

69 

70 # Import sub-functions ... 

71 from ..image import dict2exif 

72 

73 # ************************************************************************** 

74 

75 # Initialize list ... 

76 tmpImgs = [] 

77 

78 # Loop over input ... 

79 for img in imgs: 

80 # Find out what the user supplied ... 

81 match img: 

82 case str(): 

83 # Open image as RGB (even if it is paletted) ... 

84 with PIL.Image.open(img) as iObj: 

85 tmpImg = iObj.convert("RGB") 

86 

87 # Check if the user wants to scale the image down to fit within 

88 # a screen size ... 

89 if screenWidth >= 100 and screenHeight >= 100: 

90 # Resize image in place ... 

91 tmpImg.thumbnail( 

92 (screenWidth, screenHeight), 

93 resample = PIL.Image.Resampling.LANCZOS, 

94 ) 

95 

96 # Convert it to whatever mode the user asked for ... 

97 tmpImgs.append(tmpImg.convert(mode)) 

98 case PIL.Image.Image(): 

99 # Convert image to whatever mode the user asked for ... 

100 tmpImgs.append(img.convert(mode)) 

101 case _: 

102 # Crash ... 

103 raise TypeError(f"\"img\" is an unexpected type ({repr(type(img))})") from None 

104 

105 # Save it as a WEBP ... 

106 # NOTE: See https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#webp 

107 tmpImgs[0].save( 

108 webp, 

109 append_images = tmpImgs[1:], 

110 duration = round(1000.0 / fps), 

111 exif = dict2exif(exif, mode = mode), 

112 loop = 0, 

113 lossless = lossless, 

114 method = method, 

115 minimize_size = minimize_size, 

116 quality = quality, 

117 save_all = True, 

118 )