55
55
_plugins ,
56
56
)
57
57
from ._binary import i32le , o32be , o32le
58
+ from ._typing import TypeGuard
58
59
from ._util import DeferredError , is_path
59
60
60
61
ElementTree : ModuleType | None
@@ -120,7 +121,7 @@ class DecompressionBombError(Exception):
120
121
cffi = None
121
122
122
123
123
- def isImageType (t ) :
124
+ def isImageType (t : Any ) -> TypeGuard [ Image ] :
124
125
"""
125
126
Checks if an object is an image object.
126
127
@@ -267,7 +268,7 @@ def getmodebase(mode: str) -> str:
267
268
return ImageMode .getmode (mode ).basemode
268
269
269
270
270
- def getmodetype (mode ) :
271
+ def getmodetype (mode : str ) -> str :
271
272
"""
272
273
Gets the storage type mode. Given a mode, this function returns a
273
274
single-layer mode suitable for storing individual bands.
@@ -279,7 +280,7 @@ def getmodetype(mode):
279
280
return ImageMode .getmode (mode ).basetype
280
281
281
282
282
- def getmodebandnames (mode ) :
283
+ def getmodebandnames (mode : str ) -> tuple [ str , ...] :
283
284
"""
284
285
Gets a list of individual band names. Given a mode, this function returns
285
286
a tuple containing the names of individual bands (use
@@ -311,7 +312,7 @@ def getmodebands(mode: str) -> int:
311
312
_initialized = 0
312
313
313
314
314
- def preinit ():
315
+ def preinit () -> None :
315
316
"""
316
317
Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers.
317
318
@@ -437,7 +438,7 @@ def _getencoder(mode, encoder_name, args, extra=()):
437
438
438
439
439
440
class _E :
440
- def __init__ (self , scale , offset ):
441
+ def __init__ (self , scale , offset ) -> None :
441
442
self .scale = scale
442
443
self .offset = offset
443
444
@@ -508,22 +509,22 @@ def __init__(self):
508
509
self ._exif = None
509
510
510
511
@property
511
- def width (self ):
512
+ def width (self ) -> int :
512
513
return self .size [0 ]
513
514
514
515
@property
515
- def height (self ):
516
+ def height (self ) -> int :
516
517
return self .size [1 ]
517
518
518
519
@property
519
- def size (self ):
520
+ def size (self ) -> tuple [ int , int ] :
520
521
return self ._size
521
522
522
523
@property
523
524
def mode (self ):
524
525
return self ._mode
525
526
526
- def _new (self , im ):
527
+ def _new (self , im ) -> Image :
527
528
new = Image ()
528
529
new .im = im
529
530
new ._mode = im .mode
@@ -556,7 +557,7 @@ def __exit__(self, *args):
556
557
self ._close_fp ()
557
558
self .fp = None
558
559
559
- def close (self ):
560
+ def close (self ) -> None :
560
561
"""
561
562
Closes the file pointer, if possible.
562
563
@@ -589,7 +590,7 @@ def _copy(self) -> None:
589
590
self .pyaccess = None
590
591
self .readonly = 0
591
592
592
- def _ensure_mutable (self ):
593
+ def _ensure_mutable (self ) -> None :
593
594
if self .readonly :
594
595
self ._copy ()
595
596
else :
@@ -629,7 +630,7 @@ def __eq__(self, other):
629
630
and self .tobytes () == other .tobytes ()
630
631
)
631
632
632
- def __repr__ (self ):
633
+ def __repr__ (self ) -> str :
633
634
return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % (
634
635
self .__class__ .__module__ ,
635
636
self .__class__ .__name__ ,
@@ -639,7 +640,7 @@ def __repr__(self):
639
640
id (self ),
640
641
)
641
642
642
- def _repr_pretty_ (self , p , cycle ):
643
+ def _repr_pretty_ (self , p , cycle ) -> None :
643
644
"""IPython plain text display support"""
644
645
645
646
# Same as __repr__ but without unpredictable id(self),
@@ -711,7 +712,7 @@ def __getstate__(self):
711
712
im_data = self .tobytes () # load image first
712
713
return [self .info , self .mode , self .size , self .getpalette (), im_data ]
713
714
714
- def __setstate__ (self , state ):
715
+ def __setstate__ (self , state ) -> None :
715
716
Image .__init__ (self )
716
717
info , mode , size , palette , data = state
717
718
self .info = info
@@ -774,7 +775,7 @@ def tobytes(self, encoder_name: str = "raw", *args) -> bytes:
774
775
775
776
return b"" .join (output )
776
777
777
- def tobitmap (self , name = "image" ):
778
+ def tobitmap (self , name : str = "image" ) -> bytes :
778
779
"""
779
780
Returns the image converted to an X11 bitmap.
780
781
@@ -886,7 +887,12 @@ def verify(self):
886
887
pass
887
888
888
889
def convert (
889
- self , mode = None , matrix = None , dither = None , palette = Palette .WEB , colors = 256
890
+ self ,
891
+ mode : str | None = None ,
892
+ matrix : tuple [float , ...] | None = None ,
893
+ dither : Dither | None = None ,
894
+ palette : Palette = Palette .WEB ,
895
+ colors : int = 256 ,
890
896
) -> Image :
891
897
"""
892
898
Returns a converted copy of this image. For the "P" mode, this
@@ -1117,12 +1123,12 @@ def convert_transparency(m, v):
1117
1123
1118
1124
def quantize (
1119
1125
self ,
1120
- colors = 256 ,
1121
- method = None ,
1122
- kmeans = 0 ,
1126
+ colors : int = 256 ,
1127
+ method : Quantize | None = None ,
1128
+ kmeans : int = 0 ,
1123
1129
palette = None ,
1124
- dither = Dither .FLOYDSTEINBERG ,
1125
- ):
1130
+ dither : Dither = Dither .FLOYDSTEINBERG ,
1131
+ ) -> Image :
1126
1132
"""
1127
1133
Convert the image to 'P' mode with the specified number
1128
1134
of colors.
@@ -1210,7 +1216,7 @@ def copy(self) -> Image:
1210
1216
1211
1217
__copy__ = copy
1212
1218
1213
- def crop (self , box = None ) -> Image :
1219
+ def crop (self , box : tuple [ int , int , int , int ] | None = None ) -> Image :
1214
1220
"""
1215
1221
Returns a rectangular region from this image. The box is a
1216
1222
4-tuple defining the left, upper, right, and lower pixel
@@ -1341,7 +1347,7 @@ def getbbox(self, *, alpha_only: bool = True) -> tuple[int, int, int, int]:
1341
1347
self .load ()
1342
1348
return self .im .getbbox (alpha_only )
1343
1349
1344
- def getcolors (self , maxcolors = 256 ):
1350
+ def getcolors (self , maxcolors : int = 256 ):
1345
1351
"""
1346
1352
Returns a list of colors used in this image.
1347
1353
@@ -1364,7 +1370,7 @@ def getcolors(self, maxcolors=256):
1364
1370
return out
1365
1371
return self .im .getcolors (maxcolors )
1366
1372
1367
- def getdata (self , band = None ):
1373
+ def getdata (self , band : int | None = None ):
1368
1374
"""
1369
1375
Returns the contents of this image as a sequence object
1370
1376
containing pixel values. The sequence object is flattened, so
@@ -1387,7 +1393,7 @@ def getdata(self, band=None):
1387
1393
return self .im .getband (band )
1388
1394
return self .im # could be abused
1389
1395
1390
- def getextrema (self ):
1396
+ def getextrema (self ) -> tuple [ float , float ] | tuple [ tuple [ int , int ], ...] :
1391
1397
"""
1392
1398
Gets the minimum and maximum pixel values for each band in
1393
1399
the image.
@@ -1468,7 +1474,7 @@ def getexif(self) -> Exif:
1468
1474
1469
1475
return self ._exif
1470
1476
1471
- def _reload_exif (self ):
1477
+ def _reload_exif (self ) -> None :
1472
1478
if self ._exif is None or not self ._exif ._loaded :
1473
1479
return
1474
1480
self ._exif ._loaded = False
@@ -1605,7 +1611,7 @@ def getpixel(self, xy):
1605
1611
return self .pyaccess .getpixel (xy )
1606
1612
return self .im .getpixel (tuple (xy ))
1607
1613
1608
- def getprojection (self ):
1614
+ def getprojection (self ) -> tuple [ list [ int ], list [ int ]] :
1609
1615
"""
1610
1616
Get projection to x and y axes
1611
1617
@@ -1617,7 +1623,7 @@ def getprojection(self):
1617
1623
x , y = self .im .getprojection ()
1618
1624
return list (x ), list (y )
1619
1625
1620
- def histogram (self , mask = None , extrema = None ) -> list [int ]:
1626
+ def histogram (self , mask : Image | None = None , extrema = None ) -> list [int ]:
1621
1627
"""
1622
1628
Returns a histogram for the image. The histogram is returned as a
1623
1629
list of pixel counts, one for each pixel value in the source
@@ -2463,7 +2469,7 @@ def save(self, fp, format=None, **params) -> None:
2463
2469
if open_fp :
2464
2470
fp .close ()
2465
2471
2466
- def seek (self , frame ) -> None :
2472
+ def seek (self , frame : int ) -> None :
2467
2473
"""
2468
2474
Seeks to the given frame in this sequence file. If you seek
2469
2475
beyond the end of the sequence, the method raises an
@@ -2485,7 +2491,7 @@ def seek(self, frame) -> None:
2485
2491
msg = "no more images in file"
2486
2492
raise EOFError (msg )
2487
2493
2488
- def show (self , title = None ):
2494
+ def show (self , title : str | None = None ) -> None :
2489
2495
"""
2490
2496
Displays this image. This method is mainly intended for debugging purposes.
2491
2497
@@ -2526,7 +2532,7 @@ def split(self) -> tuple[Image, ...]:
2526
2532
return (self .copy (),)
2527
2533
return tuple (map (self ._new , self .im .split ()))
2528
2534
2529
- def getchannel (self , channel ) :
2535
+ def getchannel (self , channel : int | str ) -> Image :
2530
2536
"""
2531
2537
Returns an image containing a single channel of the source image.
2532
2538
@@ -2601,13 +2607,13 @@ def thumbnail(self, size, resample=Resampling.BICUBIC, reducing_gap=2.0):
2601
2607
2602
2608
provided_size = tuple (map (math .floor , size ))
2603
2609
2604
- def preserve_aspect_ratio ():
2610
+ def preserve_aspect_ratio () -> tuple [ int , int ] | None :
2605
2611
def round_aspect (number , key ):
2606
2612
return max (min (math .floor (number ), math .ceil (number ), key = key ), 1 )
2607
2613
2608
2614
x , y = provided_size
2609
2615
if x >= self .width and y >= self .height :
2610
- return
2616
+ return None
2611
2617
2612
2618
aspect = self .width / self .height
2613
2619
if x / y >= aspect :
@@ -2927,7 +2933,9 @@ def _check_size(size):
2927
2933
return True
2928
2934
2929
2935
2930
- def new (mode , size , color = 0 ) -> Image :
2936
+ def new (
2937
+ mode : str , size : tuple [int , int ], color : float | tuple [float , ...] | str | None = 0
2938
+ ) -> Image :
2931
2939
"""
2932
2940
Creates a new image with the given mode and size.
2933
2941
@@ -3193,7 +3201,7 @@ def fromqpixmap(im):
3193
3201
}
3194
3202
3195
3203
3196
- def _decompression_bomb_check (size ) :
3204
+ def _decompression_bomb_check (size : tuple [ int , int ]) -> None :
3197
3205
if MAX_IMAGE_PIXELS is None :
3198
3206
return
3199
3207
@@ -3335,7 +3343,7 @@ def _open_core(fp, filename, prefix, formats):
3335
3343
# Image processing.
3336
3344
3337
3345
3338
- def alpha_composite (im1 , im2 ) :
3346
+ def alpha_composite (im1 : Image , im2 : Image ) -> Image :
3339
3347
"""
3340
3348
Alpha composite im2 over im1.
3341
3349
@@ -3350,7 +3358,7 @@ def alpha_composite(im1, im2):
3350
3358
return im1 ._new (core .alpha_composite (im1 .im , im2 .im ))
3351
3359
3352
3360
3353
- def blend (im1 , im2 , alpha ) :
3361
+ def blend (im1 : Image , im2 : Image , alpha : float ) -> Image :
3354
3362
"""
3355
3363
Creates a new image by interpolating between two input images, using
3356
3364
a constant alpha::
@@ -3373,7 +3381,7 @@ def blend(im1, im2, alpha):
3373
3381
return im1 ._new (core .blend (im1 .im , im2 .im , alpha ))
3374
3382
3375
3383
3376
- def composite (image1 , image2 , mask ) :
3384
+ def composite (image1 : Image , image2 : Image , mask : Image ) -> Image :
3377
3385
"""
3378
3386
Create composite image by blending images using a transparency mask.
3379
3387
@@ -3483,7 +3491,7 @@ def register_save(id: str, driver) -> None:
3483
3491
SAVE [id .upper ()] = driver
3484
3492
3485
3493
3486
- def register_save_all (id , driver ):
3494
+ def register_save_all (id , driver ) -> None :
3487
3495
"""
3488
3496
Registers an image function to save all the frames
3489
3497
of a multiframe format. This function should not be
@@ -3557,7 +3565,7 @@ def register_encoder(name: str, encoder: type[ImageFile.PyEncoder]) -> None:
3557
3565
# Simple display support.
3558
3566
3559
3567
3560
- def _show (image , ** options ):
3568
+ def _show (image , ** options ) -> None :
3561
3569
from . import ImageShow
3562
3570
3563
3571
ImageShow .show (image , ** options )
@@ -3613,7 +3621,7 @@ def radial_gradient(mode):
3613
3621
# Resources
3614
3622
3615
3623
3616
- def _apply_env_variables (env = None ):
3624
+ def _apply_env_variables (env = None ) -> None :
3617
3625
if env is None :
3618
3626
env = os .environ
3619
3627
@@ -3928,21 +3936,21 @@ def get_ifd(self, tag):
3928
3936
}
3929
3937
return ifd
3930
3938
3931
- def hide_offsets (self ):
3939
+ def hide_offsets (self ) -> None :
3932
3940
for tag in (ExifTags .IFD .Exif , ExifTags .IFD .GPSInfo ):
3933
3941
if tag in self :
3934
3942
self ._hidden_data [tag ] = self [tag ]
3935
3943
del self [tag ]
3936
3944
3937
- def __str__ (self ):
3945
+ def __str__ (self ) -> str :
3938
3946
if self ._info is not None :
3939
3947
# Load all keys into self._data
3940
3948
for tag in self ._info :
3941
3949
self [tag ]
3942
3950
3943
3951
return str (self ._data )
3944
3952
3945
- def __len__ (self ):
3953
+ def __len__ (self ) -> int :
3946
3954
keys = set (self ._data )
3947
3955
if self ._info is not None :
3948
3956
keys .update (self ._info )
@@ -3954,10 +3962,10 @@ def __getitem__(self, tag):
3954
3962
del self ._info [tag ]
3955
3963
return self ._data [tag ]
3956
3964
3957
- def __contains__ (self , tag ):
3965
+ def __contains__ (self , tag ) -> bool :
3958
3966
return tag in self ._data or (self ._info is not None and tag in self ._info )
3959
3967
3960
- def __setitem__ (self , tag , value ):
3968
+ def __setitem__ (self , tag , value ) -> None :
3961
3969
if self ._info is not None and tag in self ._info :
3962
3970
del self ._info [tag ]
3963
3971
self ._data [tag ] = value
0 commit comments