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 :rtype: :py:class:`~PIL.Image.Image` 

27 """ 

28 

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

30 

31 

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

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

34 

35 :rtype: :py:class:`~PIL.Image.Image` 

36 """ 

37 

38 return image.copy() 

39 

40 

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

42 """ 

43 Invert an image (channel). :: 

44 

45 out = MAX - image 

46 

47 :rtype: :py:class:`~PIL.Image.Image` 

48 """ 

49 

50 image.load() 

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

52 

53 

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

55 """ 

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

57 the lighter values. :: 

58 

59 out = max(image1, image2) 

60 

61 :rtype: :py:class:`~PIL.Image.Image` 

62 """ 

63 

64 image1.load() 

65 image2.load() 

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

67 

68 

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

70 """ 

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

72 the darker values. :: 

73 

74 out = min(image1, image2) 

75 

76 :rtype: :py:class:`~PIL.Image.Image` 

77 """ 

78 

79 image1.load() 

80 image2.load() 

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

82 

83 

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

85 """ 

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

87 images. :: 

88 

89 out = abs(image1 - image2) 

90 

91 :rtype: :py:class:`~PIL.Image.Image` 

92 """ 

93 

94 image1.load() 

95 image2.load() 

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

97 

98 

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

100 """ 

101 Superimposes two images on top of each other. 

102 

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

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

105 

106 out = image1 * image2 / MAX 

107 

108 :rtype: :py:class:`~PIL.Image.Image` 

109 """ 

110 

111 image1.load() 

112 image2.load() 

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

114 

115 

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

117 """ 

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

119 

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

121 

122 :rtype: :py:class:`~PIL.Image.Image` 

123 """ 

124 

125 image1.load() 

126 image2.load() 

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

128 

129 

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

131 """ 

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

133 

134 :rtype: :py:class:`~PIL.Image.Image` 

135 """ 

136 

137 image1.load() 

138 image2.load() 

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

140 

141 

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

143 """ 

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

145 

146 :rtype: :py:class:`~PIL.Image.Image` 

147 """ 

148 

149 image1.load() 

150 image2.load() 

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

152 

153 

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

155 """ 

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

157 

158 :rtype: :py:class:`~PIL.Image.Image` 

159 """ 

160 

161 image1.load() 

162 image2.load() 

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

164 

165 

166def add( 

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

168) -> Image.Image: 

169 """ 

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

171 offset. If omitted, scale defaults to 1.0, and offset to 0.0. :: 

172 

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

174 

175 :rtype: :py:class:`~PIL.Image.Image` 

176 """ 

177 

178 image1.load() 

179 image2.load() 

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

181 

182 

183def subtract( 

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

185) -> Image.Image: 

186 """ 

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

188 If omitted, scale defaults to 1.0, and offset to 0.0. :: 

189 

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

191 

192 :rtype: :py:class:`~PIL.Image.Image` 

193 """ 

194 

195 image1.load() 

196 image2.load() 

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

198 

199 

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

201 """Add two images, without clipping the result. :: 

202 

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

204 

205 :rtype: :py:class:`~PIL.Image.Image` 

206 """ 

207 

208 image1.load() 

209 image2.load() 

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

211 

212 

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

214 """Subtract two images, without clipping the result. :: 

215 

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

217 

218 :rtype: :py:class:`~PIL.Image.Image` 

219 """ 

220 

221 image1.load() 

222 image2.load() 

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

224 

225 

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

227 """Logical AND between two images. 

228 

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

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

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

232 as the second image. :: 

233 

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

235 

236 :rtype: :py:class:`~PIL.Image.Image` 

237 """ 

238 

239 image1.load() 

240 image2.load() 

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

242 

243 

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

245 """Logical OR between two images. 

246 

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

248 

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

250 

251 :rtype: :py:class:`~PIL.Image.Image` 

252 """ 

253 

254 image1.load() 

255 image2.load() 

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

257 

258 

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

260 """Logical XOR between two images. 

261 

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

263 

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

265 

266 :rtype: :py:class:`~PIL.Image.Image` 

267 """ 

268 

269 image1.load() 

270 image2.load() 

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

272 

273 

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

275 """Blend images using constant transparency weight. Alias for 

276 :py:func:`PIL.Image.blend`. 

277 

278 :rtype: :py:class:`~PIL.Image.Image` 

279 """ 

280 

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

282 

283 

284def composite( 

285 image1: Image.Image, image2: Image.Image, mask: Image.Image 

286) -> Image.Image: 

287 """Create composite using transparency mask. Alias for 

288 :py:func:`PIL.Image.composite`. 

289 

290 :rtype: :py:class:`~PIL.Image.Image` 

291 """ 

292 

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

294 

295 

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

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

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

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

300 

301 :param image: Input image. 

302 :param xoffset: The horizontal distance. 

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

304 distances are set to the same value. 

305 :rtype: :py:class:`~PIL.Image.Image` 

306 """ 

307 

308 if yoffset is None: 

309 yoffset = xoffset 

310 image.load() 

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