from PIL import Imagepackage Pillow, import PIL; Image.open is lazy
methods return new imagesassign resize/crop/rotate/filter results; thumbnail & paste mutate
resize vs thumbnailresize = exact size (new img); thumbnail = fit-in-box, in place, keeps aspect
LANCZOS for downscalingImage.Resampling.LANCZOS gives the cleanest shrink
convert("RGB") before JPEGJPEG has no alpha/palette
exif_transpose earlyfix phone-photo orientation before other edits
ImageDraw for boxes/textDraw(img) then rectangle/text; truetype for real fonts
np.array / fromarrayHWC RGB uint8 bridge to NumPy
save_all + append_imageswrite animated GIFs