Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/ImageChops.py: 29%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

79 statements  

1# 

2# The Python Imaging Library. 

3# $Id$ 

4# 

5# standard channel operations 

6# 

7# History: 

8# 1996-03-24 fl Created 

9# 1996-08-13 fl Added logical operations (for "1" images) 

10# 2000-10-12 fl Added offset method (from Image.py) 

11# 

12# Copyright (c) 1997-2000 by Secret Labs AB 

13# Copyright (c) 1996-2000 by Fredrik Lundh 

14# 

15# See the README file for information on usage and redistribution. 

16# 

17 

18from __future__ import annotations 

19 

20from . import Image 

21 

22 

23def constant(image: Image.Image, value: int) -> Image.Image: 

24 """Fill a channel with a given gray level.""" 

25 

26 return Image.new("L", image.size, value) 

27 

28 

29def duplicate(image: Image.Image) -> Image.Image: 

30 """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`.""" 

31 

32 return image.copy() 

33 

34 

35def invert(image: Image.Image) -> Image.Image: 

36 """ 

37 Invert an image (channel). :: 

38 

39 out = MAX - image 

40 """ 

41 

42 image.load() 

43 return image._new(image.im.chop_invert()) 

44 

45 

46def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image: 

47 """ 

48 Compares the two images, pixel by pixel, and returns a new image containing 

49 the lighter values. :: 

50 

51 out = max(image1, image2) 

52 """ 

53 

54 image1.load() 

55 image2.load() 

56 return image1._new(image1.im.chop_lighter(image2.im)) 

57 

58 

59def darker(image1: Image.Image, image2: Image.Image) -> Image.Image: 

60 """ 

61 Compares the two images, pixel by pixel, and returns a new image containing 

62 the darker values. :: 

63 

64 out = min(image1, image2) 

65 """ 

66 

67 image1.load() 

68 image2.load() 

69 return image1._new(image1.im.chop_darker(image2.im)) 

70 

71 

72def difference(image1: Image.Image, image2: Image.Image) -> Image.Image: 

73 """ 

74 Returns the absolute value of the pixel-by-pixel difference between the two 

75 images. :: 

76 

77 out = abs(image1 - image2) 

78 """ 

79 

80 image1.load() 

81 image2.load() 

82 return image1._new(image1.im.chop_difference(image2.im)) 

83 

84 

85def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image: 

86 """ 

87 Superimposes two images on top of each other. 

88 

89 If you multiply an image with a solid black image, the result is black. If 

90 you multiply with a solid white image, the image is unaffected. :: 

91 

92 out = image1 * image2 / MAX 

93 """ 

94 

95 image1.load() 

96 image2.load() 

97 return image1._new(image1.im.chop_multiply(image2.im)) 

98 

99 

100def screen(image1: Image.Image, image2: Image.Image) -> Image.Image: 

101 """ 

102 Superimposes two inverted images on top of each other. :: 

103 

104 out = MAX - ((MAX - image1) * (MAX - image2) / MAX) 

105 """ 

106 

107 image1.load() 

108 image2.load() 

109 return image1._new(image1.im.chop_screen(image2.im)) 

110 

111 

112def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image: 

113 """ 

114 Superimposes two images on top of each other using the Soft Light algorithm 

115 """ 

116 

117 image1.load() 

118 image2.load() 

119 return image1._new(image1.im.chop_soft_light(image2.im)) 

120 

121 

122def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image: 

123 """ 

124 Superimposes two images on top of each other using the Hard Light algorithm 

125 """ 

126 

127 image1.load() 

128 image2.load() 

129 return image1._new(image1.im.chop_hard_light(image2.im)) 

130 

131 

132def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image: 

133 """ 

134 Superimposes two images on top of each other using the Overlay algorithm 

135 """ 

136 

137 image1.load() 

138 image2.load() 

139 return image1._new(image1.im.chop_overlay(image2.im)) 

140 

141 

142def add( 

143 image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 

144) -> Image.Image: 

145 """ 

146 Adds two images, dividing the result by scale and adding the 

147 offset. If omitted, scale defaults to 1.0, and offset to 0.0. 

148 

149 :: 

150 

151 out = ((image1 + image2) / scale + offset) 

152 """ 

153 

154 image1.load() 

155 image2.load() 

156 return image1._new(image1.im.chop_add(image2.im, scale, offset)) 

157 

158 

159def subtract( 

160 image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 

161) -> Image.Image: 

162 """ 

163 Subtracts two images, dividing the result by scale and adding the offset. 

164 If omitted, scale defaults to 1.0, and offset to 0.0. 

165 

166 :: 

167 

168 out = ((image1 - image2) / scale + offset) 

169 """ 

170 

171 image1.load() 

172 image2.load() 

173 return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) 

174 

175 

176def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: 

177 """Add two images, without clipping the result. 

178 

179 :: 

180 

181 out = ((image1 + image2) % MAX) 

182 """ 

183 

184 image1.load() 

185 image2.load() 

186 return image1._new(image1.im.chop_add_modulo(image2.im)) 

187 

188 

189def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: 

190 """Subtract two images, without clipping the result. 

191 

192 :: 

193 

194 out = ((image1 - image2) % MAX) 

195 """ 

196 

197 image1.load() 

198 image2.load() 

199 return image1._new(image1.im.chop_subtract_modulo(image2.im)) 

200 

201 

202def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image: 

203 """Logical AND between two images. 

204 

205 Both of the images must have mode "1". If you would like to perform a 

206 logical AND on an image with a mode other than "1", try 

207 :py:meth:`~PIL.ImageChops.multiply` instead, using a black-and-white mask 

208 as the second image. :: 

209 

210 out = ((image1 and image2) % MAX) 

211 """ 

212 

213 image1.load() 

214 image2.load() 

215 return image1._new(image1.im.chop_and(image2.im)) 

216 

217 

218def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image: 

219 """Logical OR between two images. 

220 

221 Both of the images must have mode "1". :: 

222 

223 out = ((image1 or image2) % MAX) 

224 """ 

225 

226 image1.load() 

227 image2.load() 

228 return image1._new(image1.im.chop_or(image2.im)) 

229 

230 

231def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image: 

232 """Logical XOR between two images. 

233 

234 Both of the images must have mode "1". :: 

235 

236 out = ((bool(image1) != bool(image2)) % MAX) 

237 """ 

238 

239 image1.load() 

240 image2.load() 

241 return image1._new(image1.im.chop_xor(image2.im)) 

242 

243 

244def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image: 

245 """Blend images using constant transparency weight. 

246 

247 Alias for :py:func:`PIL.Image.blend`. 

248 """ 

249 

250 return Image.blend(image1, image2, alpha) 

251 

252 

253def composite( 

254 image1: Image.Image, image2: Image.Image, mask: Image.Image 

255) -> Image.Image: 

256 """Create composite using transparency mask. 

257 

258 Alias for :py:func:`PIL.Image.composite`. 

259 """ 

260 

261 return Image.composite(image1, image2, mask) 

262 

263 

264def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image: 

265 """Returns a copy of the image where data has been offset by the given 

266 distances. Data wraps around the edges. If ``yoffset`` is omitted, it 

267 is assumed to be equal to ``xoffset``. 

268 

269 :param image: Input image. 

270 :param xoffset: The horizontal distance. 

271 :param yoffset: The vertical distance. If omitted, both 

272 distances are set to the same value. 

273 """ 

274 

275 if yoffset is None: 

276 yoffset = xoffset 

277 image.load() 

278 return image._new(image.im.offset(xoffset, yoffset))