zignal
zero-dependency image processing library.
RGBA image for processing and manipulation.
Create a new Image with the specified dimensions and optional fill color.
Parameters
rows
(int): Number of rows (height) of the imagecols
(int): Number of columns (width) of the imagecolor
(optional): Fill color. Can be:- Integer (0-255) for grayscale
- RGB tuple (r, g, b) with values 0-255
- RGBA tuple (r, g, b, a) with values 0-255
- Any color object (Rgb, Hsl, Hsv, etc.)
- Defaults to transparent (0, 0, 0, 0)
Examples
# Create a 100x200 transparent image
img = Image(100, 200)
# Create a 100x200 red image
img = Image(100, 200, (255, 0, 0))
# Create a 100x200 gray image
img = Image(100, 200, 128)
# Create an image from numpy array dimensions
img = Image(*arr.shape[:2])
# Create with semi-transparent blue
img = Image(100, 200, (0, 0, 255, 128))
Load an image from file (PNG/JPEG).
Parameters
path
(str
): Path to the image file to load
Raises
FileNotFoundError
: If the image file is not foundValueError
: If the image format is not supportedMemoryError
: If allocation fails
Examples
img = Image.load("photo.png")
print(img.rows, img.cols)
# Output: 512 768
Create Image from NumPy array with shape (rows, cols, 3) or (rows, cols, 4) and dtype uint8.
For 4-channel arrays, zero-copy is used. For 3-channel arrays, the data is converted to RGBA format with alpha=255 (requires allocation). To enable zero-copy for RGB arrays, use Image.add_alpha() first.
Parameters
array
(np.ndarray): NumPy array with shape (rows, cols, 3) or (rows, cols, 4) and dtype uint8. Must be C-contiguous.
Raises
TypeError
: If array is None or has wrong dtypeValueError
: If array has wrong shape or is not C-contiguous
Notes
The array must be C-contiguous. If your array is not C-contiguous (e.g., from slicing or transposing), use np.ascontiguousarray() first:
arr = np.ascontiguousarray(arr)
img = Image.from_numpy(arr)
Examples
arr = np.zeros((100, 200, 3), dtype=np.uint8)
img = Image.from_numpy(arr)
print(img.rows, img.cols)
# Output: 100 200
Add alpha channel to a 3-channel RGB numpy array.
This is useful for enabling zero-copy when creating Images from RGB arrays.
Parameters
array
(np.ndarray): NumPy array with shape (rows, cols, 3) and dtype uint8alpha
(int, optional): Alpha value to use for all pixels (default: 255)
Examples
rgb_arr = np.zeros((100, 200, 3), dtype=np.uint8)
rgba_arr = Image.add_alpha(rgb_arr)
print(rgba_arr.shape)
# Output: (100, 200, 4)
img = Image.from_numpy(rgba_arr) # Zero-copy creation
Convert the image to a NumPy array (zero-copy when possible).
Parameters
include_alpha
(bool, optional): If True (default), returns array with shape (rows, cols, 4). If False, returns array with shape (rows, cols, 3).
Examples
img = Image.load("photo.png")
arr_rgba = img.to_numpy() # Include alpha
arr_rgb = img.to_numpy(include_alpha=False) # RGB only
print(arr_rgba.shape, arr_rgb.shape)
# Output: (512, 768, 4) (512, 768, 3)
Save the image to a PNG file.
Parameters
path
(str): Path where the PNG file will be saved. Must have .png extension.
Raises
ValueError
: If the file does not have .png extensionMemoryError
: If allocation fails during savePermissionError
: If write permission is deniedFileNotFoundError
: If the directory does not exist
Examples
img = Image.load("input.png")
img.save("output.png")
Resize the image to the specified size.
Parameters
size
(float or tuple[int, int]):- If float: scale factor (e.g., 0.5 for half size, 2.0 for double size)
- If tuple: target dimensions as (rows, cols)
method
(InterpolationMethod
, optional): Interpolation method to use. Default isInterpolationMethod.BILINEAR
.
Resize image to fit within the specified size while preserving aspect ratio.
The image is scaled to fit within the target dimensions and centered with black borders (letterboxing) to maintain the original aspect ratio.
Parameters
size
(int or tuple[int, int]):- If int: creates a square output of size x size
- If tuple: target dimensions as (rows, cols)
method
(InterpolationMethod
, optional): Interpolation method to use. Default isInterpolationMethod.BILINEAR
.
Create a Canvas object for drawing operations on this image.
Examples
img = Image.load("photo.png")
canvas = img.canvas()
canvas.fill((255, 0, 0)) # Fill with red
canvas.draw_line((0, 0), (100, 100), (0, 255, 0)) # Draw green line
Interpolation methods for image resizing
Canvas for drawing operations on images.
Create a Canvas for drawing operations on an Image.
A Canvas provides drawing methods to modify the pixels of an Image. The Canvas maintains a reference to the parent Image to prevent it from being garbage collected while drawing operations are in progress.
Parameters
image
(Image): The Image object to draw on. Must be initialized with dimensions.
Examples
# Create an image and get its canvas
img = Image(100, 100, Rgb(255, 255, 255))
canvas = Canvas(img)
# Draw on the canvas
canvas.fill(Rgb(0, 0, 0))
canvas.draw_circle((50, 50), 20, Rgb(255, 0, 0))
Notes
- The Canvas holds a reference to the parent Image
- All drawing operations modify the original Image pixels
- Use Image.canvas() method as a convenient way to create a Canvas
Fill the entire canvas with a color.
Parameters
color
(int, tuple or color object): Color to fill the canvas with. Can be:
Examples
img = Image.load("photo.png")
canvas = img.canvas()
canvas.fill(128) # Fill with gray
canvas.fill((255, 0, 0)) # Fill with red
canvas.fill(Rgb(0, 255, 0)) # Fill with green using Rgb object
Draw a line between two points.
Parameters
p1
(tuple[float, float]): Starting point coordinates (x, y)p2
(tuple[float, float]): Ending point coordinates (x, y)color
(int, tuple or color object): Color of the line.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a rectangle outline.
Parameters
rect
(Rectangle): Rectangle object defining the boundscolor
(int, tuple or color object): Color of the rectangle.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Fill a rectangle area.
Parameters
rect
(Rectangle): Rectangle object defining the boundscolor
(int, tuple or color object): Fill color.mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a polygon outline.
Parameters
points
(list[tuple[float, float]]): List of (x, y) coordinates forming the polygoncolor
(int, tuple or color object): Color of the polygon.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Fill a polygon area.
Parameters
points
(list[tuple[float, float]]): List of (x, y) coordinates forming the polygoncolor
(int, tuple or color object): Fill color.mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a circle outline.
Parameters
center
(tuple[float, float]): Center coordinates (x, y)radius
(float): Circle radiuscolor
(int, tuple or color object): Color of the circle.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Fill a circle area.
Parameters
center
(tuple[float, float]): Center coordinates (x, y)radius
(float): Circle radiuscolor
(int, tuple or color object): Fill color.mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a quadratic Bézier curve.
Parameters
p0
(tuple[float, float]): Start point (x, y)p1
(tuple[float, float]): Control point (x, y)p2
(tuple[float, float]): End point (x, y)color
(int, tuple or color object): Color of the curve.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a cubic Bézier curve.
Parameters
p0
(tuple[float, float]): Start point (x, y)p1
(tuple[float, float]): First control point (x, y)p2
(tuple[float, float]): Second control point (x, y)p3
(tuple[float, float]): End point (x, y)color
(int, tuple or color object): Color of the curve.width
(int, optional): Line width in pixels (default: 1)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw a smooth spline through polygon points.
Parameters
points
(list[tuple[float, float]]): List of (x, y) coordinates to interpolate throughcolor
(int, tuple or color object): Color of the spline.width
(int, optional): Line width in pixels (default: 1)tension
(float, optional): Spline tension (0.0 = angular, 0.5 = smooth, default: 0.5)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Fill a smooth spline area through polygon points.
Parameters
points
(list[tuple[float, float]]): List of (x, y) coordinates to interpolate throughcolor
(int, tuple or color object): Fill color.tension
(float, optional): Spline tension (0.0 = angular, 0.5 = smooth, default: 0.5)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Draw text on the canvas.
Parameters
text
(str): Text to drawposition
(tuple[float, float]): Position coordinates (x, y)font
(BitmapFont): Font object to use for renderingcolor
(int, tuple or color object): Text color.scale
(float, optional): Text scale factor (default: 1.0)mode
(DrawMode
, optional): Drawing mode:DrawMode.FAST
orDrawMode.SOFT
(default:DrawMode.FAST
)
Rendering quality mode for drawing operations
A rectangle defined by its left, top, right, and bottom coordinates.
Initialize a Rectangle with specified coordinates.
Creates a rectangle from its bounding coordinates. The rectangle is defined by four values: left (x-min), top (y-min), right (x-max), and bottom (y-max).
Parameters
left
(float): Left edge x-coordinate (minimum x)top
(float): Top edge y-coordinate (minimum y)right
(float): Right edge x-coordinate (maximum x)bottom
(float): Bottom edge y-coordinate (maximum y)
Examples
# Create a rectangle from (10, 20) to (110, 70)
rect = Rectangle(10, 20, 110, 70)
print(rect.width) # 100
print(rect.height) # 50
# Create a square
square = Rectangle(0, 0, 50, 50)
Notes
- The constructor validates that right >= left and bottom >= top
- Use Rectangle.init_center() for center-based construction
- Coordinates follow image convention: origin at top-left, y increases downward
Create a Rectangle from center coordinates.
Parameters
x
(float): Center x coordinatey
(float): Center y coordinatewidth
(float): Rectangle widthheight
(float): Rectangle height
Examples
# Create a 100x50 rectangle centered at (50, 50)
rect = Rectangle.init_center(50, 50, 100, 50)
# This creates Rectangle(0, 25, 100, 75)
Check if the rectangle is ill-formed (empty).
A rectangle is considered empty if its left >= right or top >= bottom.
Examples
rect1 = Rectangle(0, 0, 100, 100)
print(rect1.is_empty()) # False
rect2 = Rectangle(100, 100, 0, 0) # Invalid: right < left
print(rect2.is_empty()) # True
Calculate the area of the rectangle.
Examples
rect = Rectangle(0, 0, 100, 50)
print(rect.area()) # 5000.0
Check if a point is inside the rectangle.
Parameters
x
(float): X coordinate to checky
(float): Y coordinate to check
Examples
rect = Rectangle(0, 0, 100, 100)
print(rect.contains(50, 50)) # True
print(rect.contains(150, 50)) # False
Create a new rectangle expanded by the given amount.
Parameters
amount
(float): Amount to expand each border by
Examples
rect = Rectangle(50, 50, 100, 100)
grown = rect.grow(10)
# Creates Rectangle(40, 40, 110, 110)
Create a new rectangle shrunk by the given amount.
Parameters
amount
(float): Amount to shrink each border by
Examples
rect = Rectangle(40, 40, 110, 110)
shrunk = rect.shrink(10)
# Creates Rectangle(50, 50, 100, 100)
Calculate the intersection of this rectangle with another.
Parameters
other
(Rectangle): The other rectangle to intersect with
Examples
rect1 = Rectangle(0, 0, 100, 100)
rect2 = Rectangle(50, 50, 150, 150)
intersection = rect1.intersect(rect2)
# Returns Rectangle(50, 50, 100, 100)
rect3 = Rectangle(200, 200, 250, 250)
result = rect1.intersect(rect3) # Returns None (no overlap)
Bitmap font for text rendering
Feature Distribution Matching for image style transfer.
Initialize a new FeatureDistributionMatching instance.
Creates a new FDM instance that can be used to transfer color distributions between images. The instance maintains internal state for efficient batch processing of multiple images with the same target distribution.
Examples
# Create an FDM instance
fdm = FeatureDistributionMatching()
# Single image transformation
source = Image.load("portrait.png")
target = Image.load("sunset.png")
fdm.match(source, target) # source is modified in-place
source.save("portrait_sunset.png")
# Batch processing with same style
style = Image.load("style_reference.png")
fdm.set_target(style)
for filename in image_files:
img = Image.load(filename)
fdm.set_source(img)
fdm.update()
img.save(f"styled_{filename}")
Notes
- The algorithm matches mean and covariance of pixel distributions
- Target statistics are computed once and can be reused for multiple sources
- See: https://facebookresearch.github.io/dino/blog/
Set the target image whose distribution will be matched.
This method computes and stores the target distribution statistics (mean and covariance) for reuse across multiple source images. This is more efficient than recomputing the statistics for each image when applying the same style to multiple images.
Parameters
image
(Image
): Target image providing the color distribution to match
Examples
fdm = FeatureDistributionMatching()
target = Image.load("sunset.png")
fdm.set_target(target)
Set the source image to be transformed.
The source image will be modified in-place when update() is called.
Parameters
image
(Image
): Source image to be modified
Examples
fdm = FeatureDistributionMatching()
source = Image.load("portrait.png")
fdm.set_source(source)
Set both source and target images and apply the transformation.
This is a convenience method that combines set_source(), set_target(), and update() into a single call. The source image is modified in-place.
Parameters
source
(Image
): Source image to be modifiedtarget
(Image
): Target image providing the color distribution to match
Examples
fdm = FeatureDistributionMatching()
source = Image.load("portrait.png")
target = Image.load("sunset.png")
fdm.match(source, target) # source is now modified
source.save("portrait_sunset.png")
Apply the feature distribution matching transformation.
This method modifies the source image in-place to match the target distribution. Both source and target must be set before calling this method.
Raises
RuntimeError
: If source or target has not been set
Examples
fdm = FeatureDistributionMatching()
fdm.set_target(target)
fdm.set_source(source)
fdm.update() # source is now modified
Batch processing
fdm.set_target(style_image)
for img in images:
fdm.set_source(img)
fdm.update() # Each img is modified in-place
Convex hull computation using Graham's scan algorithm.
Initialize a new ConvexHull instance.
Creates a new ConvexHull instance that can compute the convex hull of 2D point sets using Graham's scan algorithm. The algorithm has O(n log n) time complexity where n is the number of input points.
Examples
# Create a ConvexHull instance
hull = ConvexHull()
# Find convex hull of points
points = [(0, 0), (1, 1), (2, 2), (3, 1), (4, 0), (2, 4), (1, 3)]
result = hull.find(points)
# Returns: [(0.0, 0.0), (1.0, 3.0), (2.0, 4.0), (4.0, 0.0)]
Notes
- Returns vertices in clockwise order
- Returns None for degenerate cases (e.g., all points collinear)
- Requires at least 3 points for a valid hull
Find the convex hull of a set of 2D points.
Returns the vertices of the convex hull in clockwise order as a list of (x, y) tuples, or None if the hull is degenerate (e.g., all points are collinear).
Parameters
points
(list[tuple[float, float]]): List of (x, y) coordinate pairs. At least 3 points are required.
Examples
hull = ConvexHull()
points = [(0, 0), (1, 1), (2, 2), (3, 1), (4, 0), (2, 4), (1, 3)]
result = hull.find(points)
# Returns: [(0.0, 0.0), (1.0, 3.0), (2.0, 4.0), (4.0, 0.0)]
RGB color in sRGB colorspace with components in range 0-255
RGBA color with alpha channel, components in range 0-255
HSV (Hue-Saturation-Value) color representation
HSL (Hue-Saturation-Lightness) color representation
CIELAB color space representation
CIE 1931 XYZ color space representation
Oklab perceptual color space representation
Oklch perceptual color space in cylindrical coordinates
CIE LCH color space representation (cylindrical Lab)
LMS color space representing Long, Medium, Short wavelength cone responses
XYB color space used in JPEG XL image compression
YCbCr color space used in JPEG and video encoding