ImageOps
from blanket import ImageOps provides all 18 functions in Pillow's
ImageOps submodule:
- Tone and color:
autocontrast,colorize,equalize,grayscale,invert,posterize,solarize. - Geometry:
contain,cover,crop,deform,expand,fit,flip,mirror,pad,scale. - Orientation:
exif_transpose, includingin_place=True.
from blanket import Image, ImageOps
with Image.open("input.jpg") as image:
upright = ImageOps.exif_transpose(image)
thumbnail = ImageOps.fit(upright, (256, 256), method=Image.Resampling.LANCZOS)
ImageOps.autocontrast(thumbnail).save("thumbnail.png")
Pixel processing runs in Rust, without a Pillow runtime dependency. Geometry
supports all three Blanket modes; histogram and lookup operations accept L
and RGB, while colorize requires L. grayscale accepts all three modes.
The signatures, defaults, border forms, masks, CSS color arguments, and
SupportsGetMesh protocol follow Pillow. Resizing supports all six
Image.Resampling filters; mesh deformation supports nearest, bilinear, and
bicubic sampling. Filtered RGBA operations use premultiplied alpha.
Note that ImageOps.crop(image, border=2) removes pixels from each side by
a border width—its argument is not a rectangle. Use image.crop() for
rectangle-based cropping.
Reference
autocontrast
autocontrast(image: Image, cutoff: float | tuple[float, float] = 0, ignore: int | Sequence[int] | None = None, mask: Image | None = None, preserve_tone: bool = False) -> Image
Stretch histogram endpoints with optional masks, ignored values and tails.
cutoff is a percentage, or separate (low, high) percentages.
preserve_tone uses one luminance histogram for all color channels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
cutoff
|
float | tuple[float, float]
|
Percentage discarded from histogram tails, or separate |
0
|
ignore
|
int | Sequence[int] | None
|
Pixel value or sequence of values excluded from the histogram. |
None
|
mask
|
Image | None
|
Optional mask selecting pixels. Histogram operations require an L mask; compositing also accepts RGBA alpha. |
None
|
preserve_tone
|
bool
|
Use a shared luminance histogram to preserve relative channel tone. |
False
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.autocontrast(image, cutoff=1)
colorize
colorize(image: Image, black: Color, white: Color, mid: Color | None = None, blackpoint: int = 0, whitepoint: int = 255, midpoint: int = 127) -> Image
Map an L image to an RGB gradient with two or three color stops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
black
|
Color
|
Color mapped to the black point. |
required |
white
|
Color
|
Color mapped to the white point. |
required |
mid
|
Color | None
|
Optional color at the midpoint for a three-color gradient. |
None
|
blackpoint
|
int
|
Input intensity mapped to black, in 0 through 255. |
0
|
whitepoint
|
int
|
Input intensity mapped to white, in 0 through 255. |
255
|
midpoint
|
int
|
Input intensity mapped to the middle color. |
127
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.colorize(image.convert("L"), "navy", "white")
contain
Resize to fit inside size while preserving the aspect ratio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
size
|
tuple[int, int]
|
Output |
required |
method
|
int
|
Resampling filter from |
BICUBIC
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.contain(image, (4, 6))
cover
Resize to cover size while preserving the aspect ratio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
size
|
tuple[int, int]
|
Output |
required |
method
|
int
|
Resampling filter from |
BICUBIC
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.cover(image, (4, 6))
pad
pad(image: Image, size: tuple[int, int], method: int = BICUBIC, color: Color | None = None, centering: tuple[float, float] = (0.5, 0.5)) -> Image
Contain the image and pad it to size with the selected background.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
size
|
tuple[int, int]
|
Output |
required |
method
|
int
|
Resampling filter from |
BICUBIC
|
color
|
Color | None
|
Fill value, channel tuple, or CSS color string. |
None
|
centering
|
tuple[float, float]
|
Horizontal and vertical alignment in 0 through 1; 0.5 centers each axis. |
(0.5, 0.5)
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.pad(image, (12, 8), color="white")
crop
Remove border pixels from each side of the image.
Like Pillow, also accepts (horizontal, vertical) or (left, top, right, bottom) border tuples. Use image.crop(box) to select a rectangle instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
border
|
int
|
Border width in pixels. |
0
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.crop(image, border=1)
scale
Resize by a positive scale factor, rounding dimensions to pixels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
factor
|
float
|
Positive multiplier for both image dimensions. |
required |
resample
|
int
|
Resampling filter from |
BICUBIC
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.scale(image, 0.5)
deform
deform(image: Image, deformer: SupportsGetMesh, resample: int = BILINEAR) -> Image
Warp using a deformer mesh with nearest, bilinear or bicubic sampling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
deformer
|
SupportsGetMesh
|
Object implementing |
required |
resample
|
int
|
Resampling filter from |
BILINEAR
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
class IdentityMesh:
def getmesh(self, image):
width, height = image.size
return [((0, 0, width, height), (0, 0, 0, height, width, height, width, 0))]
result = ImageOps.deform(image, IdentityMesh())
equalize
Equalize each channel using the histogram selected by an optional mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
mask
|
Image | None
|
Optional mask selecting pixels. Histogram operations require an L mask; compositing also accepts RGBA alpha. |
None
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.equalize(image)
expand
Add a border filled with a pixel value or CSS color.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
border
|
Border
|
Integer, |
0
|
fill
|
Color
|
Border value, channel tuple, or CSS color. |
0
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.expand(image, border=2, fill="white")
fit
fit(image: Image, size: tuple[int, int], method: int = BICUBIC, bleed: float = 0.0, centering: tuple[float, float] = (0.5, 0.5)) -> Image
Crop to the requested aspect ratio and resize, with optional edge bleed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
size
|
tuple[int, int]
|
Output |
required |
method
|
int
|
Resampling filter from |
BICUBIC
|
bleed
|
float
|
Fraction to remove from each edge before fitting; must be less than 0.5. |
0.0
|
centering
|
tuple[float, float]
|
Horizontal and vertical alignment in 0 through 1; 0.5 centers each axis. |
(0.5, 0.5)
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.fit(image, (4, 6))
flip
Flip vertically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.flip(image)
grayscale
Convert to 8-bit luminance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.grayscale(image)
invert
Replace each channel value with 255 minus that value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.invert(image)
mirror
Flip horizontally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.mirror(image)
posterize
Keep the highest bits of each channel (0 through 8).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
bits
|
int
|
Number of high bits to retain per channel, from 0 through 8. |
required |
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.posterize(image, bits=4)
solarize
Invert channel values greater than or equal to threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
threshold
|
int
|
Intensity threshold, on the 0 through 255 scale. |
128
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.solarize(image, threshold=128)
exif_transpose
exif_transpose(image: Image, *, in_place: Literal[True]) -> None
Apply EXIF orientation and remove it from EXIF and XMP metadata.
Return a copy by default, or update the original and return None when
in_place=True. Other EXIF entries and their offsets are preserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Input image. |
required |
in_place
|
bool
|
Modify the input and return None when true; otherwise return a transformed copy. |
False
|
Examples:
from blanket import Image, ImageOps
image = Image.new("RGB", (8, 8), (40, 100, 180))
result = ImageOps.exif_transpose(image)
SupportsGetMesh
Bases: Protocol
A deformer returning destination boxes and source TL, BL, BR, TR quads.
getmesh
getmesh(image: Image) -> list[tuple[tuple[int, int, int, int], tuple[float, float, float, float, float, float, float, float]]]
Describe destination rectangles and their source quadrilaterals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Image being deformed, used to determine source dimensions. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[tuple[int, int, int, int], tuple[float, float, float, float, float, float, float, float]]]
|
Pairs of destination (left, top, right, bottom) rectangles and source |
list[tuple[tuple[int, int, int, int], tuple[float, float, float, float, float, float, float, float]]]
|
coordinates in top-left, bottom-left, bottom-right, top-right order. |
Examples:
from blanket import Image, ImageOps
class IdentityMesh:
def getmesh(self, image):
width, height = image.size
return [((0, 0, width, height), (0, 0, 0, height, width, height, width, 0))]
image = Image.new("RGB", (8, 8), "navy")
result = ImageOps.deform(image, IdentityMesh())