View Source Vix.Operator (vix v0.33.1)
Provides an intuitive and readable interface for performing image processing operations by overriding common mathematical and relational operators.
This module simplifies complex image processing pipelines by allowing you to use familiar operators, such as +
, -
, *
, /
, and comparison operators (==
, >=
, etc.), directly with images, numbers, and lists of numbers (pixels). It also includes utility functions for logical operations and validation, like all?/2
.
Key Features
- Bitwise Operations: Perform Bitwise Boolean operations such as
&&
,||
, andxor
between images and numbers. - Arithmetic Operations: Use operators such as
+
,-
,*
,/
, and**
to perform pixel-wise operations between images, numbers, or lists of numbers. - Comparison Operations: Compare pixel values using operators like
==
,!=
,<
,<=
,>
, and>=
, returning the result as a new image. - Logical Validation: Check pixel values for truthiness (e.g.,
255
for true,0
for false) usingall?/2
.
Example Usage
defmodule Example do
alias Vix.Vips.Operation
def demo_operations do
# Import only the required operators for readability and clarity
use Vix.Operator, only: [+: 2, -: 2, *: 2, /: 2, ==: 2, all?: 2]
# Create a black image (100x100, 3 bands)
black = Image.build_image!(100, 100, [0, 0, 0])
# Add constant values to pixels
grey1 = black + 125
grey2 = black + [125, 125, 125]
# Pixel-wise addition: [255, 255, 255] + [0, 0, 0]
result_image = white + grey1
# Create a white image
white = Image.build_image!(100, 100, [255, 255, 255])
result = (black + 255) == white
true = all?(result, true)
end
end
Summary
Functions
Performs Bitwise Boolean AND Operation (&&) between Images and numbers, returning the result as an Image.
Performs Power (**) operation between Images, numbers, and lists of numbers (pixels).
Performs Multiplication (*) operation between Images, numbers, and lists of numbers (pixels).
Performs Addition (+) operation between Images, numbers, and lists of numbers (pixels).
Performs Subtraction (-) operation between Images, numbers, and lists of numbers (pixels).
Performs Division (/) operation between Images, numbers, and lists of numbers (pixels).
Performs Not_equal (!=) comparison between Images and numbers, returning the result as an Image.
Performs Less_than (<) comparison between Images and numbers, returning the result as an Image.
Performs Less_than_equal (<=) comparison between Images and numbers, returning the result as an Image.
Performs Equal (==) comparison between Images and numbers, returning the result as an Image.
Performs Greater_than (>) comparison between Images and numbers, returning the result as an Image.
Performs Greater_than_equal (>=) comparison between Images and numbers, returning the result as an Image.
Checks if all of the values are "true" (255) or "false" (0). Useful together with relational operators.
Performs Bitwise Boolean XOR Operation (xor) between Images and numbers, returning the result as an Image.
Performs Bitwise Boolean OR Operation (||) between Images and numbers, returning the result as an Image.
Functions
@spec (Vix.Vips.Image.t() | number() | [number()]) && (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() && term() :: term()
Performs Bitwise Boolean AND Operation (&&) between Images and numbers, returning the result as an Image.
Overview
The operation handles various input combinations:
- Image && Image
- Image && number(s)
- number(s) && Image
- non-Image values (falls back to
Kernel
)
Input Handling
Values are cast up before operations. Float values are converted to integers
Number Inputs
- Single number: Applied to all image bands uniformly
- Number list:
- If list size matches image bands: Each number applies to its respective band
- If list size does not match the image bands: Either the image bands or the list is scaled up to match the other.
Image Inputs
- When both inputs are images: Uses
Operation.boolean!(a, b, :VIPS_OPERATION_BOOLEAN_AND)
Examples
Image && Image Operations
iex> img = Image.build_image!(2, 1, [0, 255, 0]) && Image.build_image!(2, 1, [0, 255, 255])
iex> Image.shape(img)
{2, 1, 3}
iex> Image.to_list!(img)
[[[0, 255, 0], [0, 255, 0]]]
# Identical Images
iex> (Image.build_image!(2, 2, [2, 4, 8]) && Image.build_image!(2, 2, [2, 4, 8])) |> Image.to_list!()
[[[2, 4, 8], [2, 4, 8]], [[2, 4, 8], [2, 4, 8]]]
# Different dimensions
iex> img = Image.build_image!(1, 1, [2]) && Image.build_image!(1, 2, [2, 4, 8])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[2, 0, 0]], [[0, 0, 0]]]
Image && Number Operations
# Single number comparison (applies to all bands)
iex> (Image.build_image!(1, 2, [2, 5, 3]) && 6) |> Image.to_list!()
[[[2, 4, 2]], [[2, 4, 2]]]
# Float Comparison
iex> (Image.build_image!(1, 1, [10]) && 6.0) |> Image.to_list!()
[[[2]]]
# List comparison (band-wise)
iex> (Image.build_image!(1, 1, [2, 2]) && [1, 3]) |> Image.to_list!()
[[[0, 2]]]
Reverse Operations
# Number && Image
iex> (10.0 && Image.build_image!(1, 1, [5])) |> Image.to_list!()
[[[0]]]
# List && Image
iex> ([2, 2] && Image.build_image!(1, 1, [1, 3])) |> Image.to_list!()
[[[0, 2]]]
Kernel Fallback
# When neither argument is an image
iex> false && true
false
@spec (Vix.Vips.Image.t() | number() | [number()]) ** (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec number() ** number() :: number()
Performs Power (**) operation between Images, numbers, and lists of numbers (pixels).
Overview
The operator handles Images, numbers, and lists together with the following rules:
- Single numbers are applied to all image bands
- Lists can be matched with image bands
- Type casting is handled automatically
- When neither argument is an image, delegates to
Kernel.**/2
Behavior
Power Rules
When operating with numbers or lists:
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Bands are scaled up to match each other.
Type Handling
Output Image Band Format:
- Two images: Cast to smallest common format that can hold result
- Image + number:
- Double input → Double output
- otherwise → Float output
Examples
Basic Image Power Operation
# Raising each pixel of a single-band image to the power of another single-band image
iex> img1 = Image.build_image!(2, 2, [2])
iex> img2 = Image.build_image!(2, 2, [3])
iex> result = img1 ** img2
iex> Image.to_list!(result)
[[[8.0], [8.0]], [[8.0], [8.0]]]
# Raising multi-band image pixels to the power of single-band image
iex> multi_band = Image.build_image!(1, 2, [2, 3, 4])
iex> single_band = Image.build_image!(1, 2, [2])
iex> result = multi_band ** single_band
iex> Image.to_list!(result)
[[[4.0, 9.0, 16.0]], [[4.0, 9.0, 16.0]]]
Image and Number Operations
# Raising all bands of an image to a constant power
iex> img = Image.build_image!(1, 1, [3, 4, 5]) ** 2
iex> Image.to_list!(img)
[[[9.0, 16.0, 25.0]]]
# Raising image pixels to a fractional power
iex> img = Image.build_image!(1, 1, [16]) ** 0.5
iex> Image.to_list!(img)
[[[4.0]]]
List Operations
# List matching image bands
iex> img = Image.build_image!(1, 2, [2, 3]) ** [3, 2]
iex> Image.to_list!(img)
[[[8.0, 9.0]], [[8.0, 9.0]]]
# List larger than bands (expands single-band image)
iex> img = Image.build_image!(1, 2, [2]) ** [3, 4, 5]
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[8.0, 16.0, 32.0]], [[8.0, 16.0, 32.0]]]
Reverse Operations
# Number on the left side
iex> img = 2 ** Image.build_image!(1, 2, [3, 4])
iex> Image.to_list!(img)
[[[8.0, 16.0]], [[8.0, 16.0]]]
# List on the left side
iex> img = [2, 3, 4] ** Image.build_image!(1, 2, [2])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[4.0, 9.0, 16.0]], [[4.0, 9.0, 16.0]]]
Type Casting Examples
# Always returns float output
iex> img = Image.build_image!(2, 2, [3]) ** 2
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
Fallback Behavior
# Standard Kernel.** behavior when no images involved
iex> 2 ** 3
8
@spec (Vix.Vips.Image.t() | number() | [number()]) * (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec number() * number() :: number()
Performs Multiplication (*) operation between Images, numbers, and lists of numbers (pixels).
Overview
The operator handles Images, numbers, and lists together with the following rules:
- Single numbers are applied to all image bands
- Lists can be matched with image bands
- Type casting is handled automatically
- When neither argument is an image, delegates to
Kernel.*/2
Behavior
Multiplication Rules
When operating with numbers or lists:
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Bands are scaled up to match each other.
Type Handling
Output Image Band Format:
- Two images: Cast to smallest common format that can hold result
- Image + number:
- Complex input → Complex output
- Double input → Double output
- otherwise → Float output
Examples
Basic Image Multiplication
# Multiplying two single-band images
iex> img1 = Image.build_image!(2, 2, [3])
iex> img2 = Image.build_image!(2, 2, [4])
iex> result = img1 * img2
iex> Image.to_list!(result)
[[[12], [12]], [[12], [12]]]
# Multiplying images with different bands
iex> multi_band = Image.build_image!(1, 2, [2, 3, 4])
iex> single_band = Image.build_image!(1, 2, [5])
iex> result = multi_band * single_band
iex> Image.to_list!(result)
[[[10, 15, 20]], [[10, 15, 20]]]
Image and Number Operations
# Multiplying all bands by a number
iex> img = Image.build_image!(1, 1, [6, 7, 8]) * 3
iex> Image.to_list!(img)
[[[18.0, 21.0, 24.0]]]
# Multiplying by a float (demonstrates type conversion)
iex> img = Image.build_image!(1, 1, [10]) * 2.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
iex> Image.to_list!(img)
[[[25.0]]]
List Operations
# List matching image bands
iex> img = Image.build_image!(1, 2, [2, 3]) * [4, 5]
iex> Image.to_list!(img)
[[[8.0, 15.0]], [[8.0, 15.0]]]
# List larger than bands (expands single-band image)
iex> img = Image.build_image!(1, 2, [3]) * [2, 4, 6]
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[6.0, 12.0, 18.0]], [[6.0, 12.0, 18.0]]]
Reverse Operations
# Number on the left side
iex> img = 10 * Image.build_image!(1, 2, [2, 4])
iex> Image.to_list!(img)
[[[20.0, 40.0]], [[20.0, 40.0]]]
# List on the left side
iex> img = [2, 3, 4] * Image.build_image!(1, 2, [5])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[10.0, 15.0, 20.0]], [[10.0, 15.0, 20.0]]]
Type Casting Examples
# Integer to float conversion
iex> img = Image.build_image!(2, 2, [4]) * 2.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
Fallback Behavior
# Standard Kernel.* behavior when no images involved
iex> 5 * 3
15
@spec (Vix.Vips.Image.t() | number() | [number()]) + (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec number() + number() :: number()
Performs Addition (+) operation between Images, numbers, and lists of numbers (pixels).
Overview
The operator handles Images, numbers, and lists together with the following rules:
- Single numbers are applied to all image bands
- Lists can be matched with image bands
- Type casting is handled automatically
- When neither argument is an image, delegates to
Kernel.+/2
Behavior
Addition Rules
When operating with numbers or lists:
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Bands are scaled up to match each other.
Type Handling
Output Image Band Format:
- Two images: Cast to smallest common format that can hold result
- Image + number:
- Complex input → Complex output
- Double input → Double output
- otherwise → Float output
Examples
Basic Image Addition
# Adding two single-band images
iex> img1 = Image.build_image!(2, 2, [10])
iex> img2 = Image.build_image!(2, 2, [20])
iex> result = img1 + img2
iex> Image.to_list!(result)
[[[30], [30]], [[30], [30]]]
# Adding images with different bands
iex> multi_band = Image.build_image!(1, 2, [10, 20, 30])
iex> single_band = Image.build_image!(1, 2, [5])
iex> result = multi_band + single_band
iex> Image.to_list!(result)
[[[15, 25, 35]], [[15, 25, 35]]]
Image and Number Operations
# Adding a number to all bands
iex> img = Image.build_image!(1, 1, [10, 20, 30]) + 5
iex> Image.to_list!(img)
[[[15.0, 25.0, 35.0]]]
# Adding float (demonstrates type conversion)
iex> img = Image.build_image!(1, 1, [10]) + 5.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
iex> Image.to_list!(img)
[[[15.5]]]
List Operations
# List matching image bands
iex> img = Image.build_image!(1, 2, [10, 20]) + [5, 10]
iex> Image.to_list!(img)
[[[15.0, 30.0]], [[15.0, 30.0]]]
# List larger than bands (expands single-band image)
iex> img = Image.build_image!(1, 2, [10]) + [5, 10, 15]
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[15.0, 20.0, 25.0]], [[15.0, 20.0, 25.0]]]
Reverse Operations
# Number on the left side
iex> img = 5 + Image.build_image!(1, 2, [10, 20])
iex> Image.to_list!(img)
[[[15.0, 25.0]], [[15.0, 25.0]]]
# List on the left side
iex> img = [5, 10, 15] + Image.build_image!(1, 2, [10])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[15.0, 20.0, 25.0]], [[15.0, 20.0, 25.0]]]
Type Casting Examples
# Integer to float conversion
iex> img = Image.build_image!(2, 2, [10]) + 5.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
Fallback Behavior
# Standard Kernel.+ behavior when no images involved
iex> 5 + 10
15
@spec (Vix.Vips.Image.t() | number() | [number()]) - (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec number() - number() :: number()
Performs Subtraction (-) operation between Images, numbers, and lists of numbers (pixels).
Overview
The operator handles Images, numbers, and lists together with the following rules:
- Single numbers are applied to all image bands
- Lists can be matched with image bands
- Type casting is handled automatically
- When neither argument is an image, delegates to
Kernel.-/2
Behavior
Subtraction Rules
When operating with numbers or lists:
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Bands are scaled up to match each other.
Type Handling
Output Image Band Format:
- Two images: Cast to smallest common format that can hold result
- Image + number:
- Complex input → Complex output
- Double input → Double output
- otherwise → Float output
Examples
Basic Image Subtraction
# Subtracting two single-band images
iex> img1 = Image.build_image!(2, 2, [30])
iex> img2 = Image.build_image!(2, 2, [10])
iex> result = img1 - img2
iex> Image.to_list!(result)
[[[20], [20]], [[20], [20]]]
# Subtracting images with different bands
iex> multi_band = Image.build_image!(1, 2, [30, 40, 50])
iex> single_band = Image.build_image!(1, 2, [10])
iex> result = multi_band - single_band
iex> Image.to_list!(result)
[[[20, 30, 40]], [[20, 30, 40]]]
Image and Number Operations
# Subtracting a number from all bands
iex> img = Image.build_image!(1, 1, [50, 60, 70]) - 20
iex> Image.to_list!(img)
[[[30.0, 40.0, 50.0]]]
# Subtracting a float (demonstrates type conversion)
iex> img = Image.build_image!(1, 1, [50]) - 15.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
iex> Image.to_list!(img)
[[[34.5]]]
List Operations
# List matching image bands
iex> img = Image.build_image!(1, 2, [30, 50]) - [10, 20]
iex> Image.to_list!(img)
[[[20.0, 30.0]], [[20.0, 30.0]]]
# List larger than bands (expands single-band image)
iex> img = Image.build_image!(1, 2, [30]) - [5, 10, 15]
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[25.0, 20.0, 15.0]], [[25.0, 20.0, 15.0]]]
Reverse Operations
# Number on the left side
iex> img = 100 - Image.build_image!(1, 2, [30, 50])
iex> Image.to_list!(img)
[[[70.0, 50.0]], [[70.0, 50.0]]]
# List on the left side
iex> img = [50, 60, 70] - Image.build_image!(1, 2, [20])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[30.0, 40.0, 50.0]], [[30.0, 40.0, 50.0]]]
Type Casting Examples
# Integer to float conversion
iex> img = Image.build_image!(2, 2, [30]) - 10.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
Fallback Behavior
# Standard Kernel.- behavior when no images involved
iex> 50 - 20
30
@spec (Vix.Vips.Image.t() | number() | [number()]) / (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec number() / number() :: number()
Performs Division (/) operation between Images, numbers, and lists of numbers (pixels).
Overview
The operator handles Images, numbers, and lists together with the following rules:
- Single numbers are applied to all image bands
- Lists can be matched with image bands
- Type casting is handled automatically
- When neither argument is an image, delegates to
Kernel.//2
Behavior
Division Rules
When operating with numbers or lists:
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Bands are scaled up to match each other.
Type Handling
Output Image Band Format:
- Two images: Cast to smallest common format that can hold result
- Image + number:
- Complex input → Complex output
- Double input → Double output
- otherwise → Float output
Examples
Basic Image Division
# Dividing two single-band images
iex> img1 = Image.build_image!(2, 2, [20])
iex> img2 = Image.build_image!(2, 2, [4])
iex> result = img1 / img2
iex> Image.to_list!(result)
[[[5.0], [5.0]], [[5.0], [5.0]]]
# Dividing images with different bands
iex> multi_band = Image.build_image!(1, 2, [20, 30, 40])
iex> single_band = Image.build_image!(1, 2, [10])
iex> result = multi_band / single_band
iex> Image.to_list!(result)
[[[2.0, 3.0, 4.0]], [[2.0, 3.0, 4.0]]]
# Dividing two images where the divisor contains zero.
# Vix detects division by zero, and sets those pixels to zero in
# the output, without any error or warning.
iex> img1 = Image.build_image!(2, 2, [20])
iex> img2 = Image.build_image!(2, 2, [0])
iex> result = img1 / img2
iex> Image.to_list!(result)
[[[0.0], [0.0]], [[0.0], [0.0]]]
Image and Number Operations
# Dividing all bands by a number
iex> img = Image.build_image!(1, 1, [30, 60, 90]) / 10
iex> Image.to_list!(img)
[[[3.0, 6.0, 9.0]]]
# Dividing by a float (demonstrates type conversion)
iex> img = Image.build_image!(1, 1, [25]) / 2.5
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
iex> Image.to_list!(img)
[[[10.0]]]
List Operations
# List matching image bands
iex> img = Image.build_image!(1, 2, [40, 60]) / [4, 6]
iex> Image.to_list!(img)
[[[10.0, 10.0]], [[10.0, 10.0]]]
# List larger than bands (expands single-band image)
iex> img = Image.build_image!(1, 2, [30]) / [3, 6, 5]
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[10.0, 5.0, 6.0]], [[10.0, 5.0, 6.0]]]
Reverse Operations
# Number on the left side
iex> img = 100 / Image.build_image!(1, 2, [5, 10])
iex> Image.to_list!(img)
[[[20.0, 10.0]], [[20.0, 10.0]]]
# List on the left side
iex> img = [100, 200, 300] / Image.build_image!(1, 2, [10])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[10.0, 20.0, 30.0]], [[10.0, 20.0, 30.0]]]
Type Casting Examples
# Integer to float conversion
iex> img = Image.build_image!(2, 2, [25]) / 2
iex> Image.format(img)
:VIPS_FORMAT_FLOAT
Fallback Behavior
# Standard Kernel./ behavior when no images involved
iex> 10 / 2
5.0
@spec (Vix.Vips.Image.t() | number() | [number()]) != (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() != term() :: boolean()
Performs Not_equal (!=) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.!=/2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_NOTEQ)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 15]) != Image.build_image!(2, 2, [15, 15])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[255, 0], [255, 0]], [[255, 0], [255, 0]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [5]) != Image.build_image!(2, 2, [10])
iex> all?(img, true)
true
Multi-band Image Operations
# Same values across all bands (should be false)
iex> (Image.build_image!(10, 10, [10, 20, 30]) != Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
false
# Different values between single and multi-band
iex> (Image.build_image!(10, 10, [20]) != Image.build_image!(10, 10, [10, 10, 10])) |> all?(true)
true
# Multi-band vs single-band with matching values
iex> (Image.build_image!(10, 10, [10, 20, 30]) != Image.build_image!(10, 10, [30])) |> all?(true)
false
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [5, 10, 20]) != 5
iex> Image.to_list!(img)
[[[0, 255, 255]], [[0, 255, 255]]]
# Comparing with same value (should be false)
iex> (Image.build_image!(10, 10, [10]) != 10) |> all?(true)
false
# Float comparison with different value
iex> (Image.build_image!(10, 10, [10]) != 20.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) != [10, 10]
iex> Image.to_list!(img)
[[[0, 255]]]
Reverse Comparison
# Float on the left side
iex> (10.0 != Image.build_image!(10, 10, [20])) |> all?(true)
true
# List on the left side
iex> ([10, 20, 30] != Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.!= behavior when no images involved
iex> 4 != 5
true
@spec (Vix.Vips.Image.t() | number() | [number()]) < (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() < term() :: boolean()
Performs Less_than (<) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.</2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_LESS)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 15]) < Image.build_image!(2, 2, [5, 20])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[0, 255], [0, 255]], [[0, 255], [0, 255]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [5]) < Image.build_image!(2, 2, [10])
iex> all?(img, true)
true
Multi-band Image Operations
# Different band count scenarios
iex> (Image.build_image!(10, 10, [10, 20, 30]) < Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
true
iex> (Image.build_image!(10, 10, [10]) < Image.build_image!(10, 10, [5, 10, 20])) |> all?(true)
false
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [1, 10, 20]) < 5
iex> Image.to_list!(img)
[[[255, 0, 0]], [[255, 0, 0]]]
# comparing different types
iex> (Image.build_image!(10, 10, [10]) < 20.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) < [20, 10]
iex> Image.to_list!(img)
[[[255, 0]]]
Reverse Comparison
# Numbers/lists on the left side
iex> (10.0 < Image.build_image!(10, 10, [20])) |> all?(true)
true
iex> ([10, 20, 30] < Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.< behavior when no images involved
iex> 4 < 5
true
@spec (Vix.Vips.Image.t() | number() | [number()]) <= (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() <= term() :: boolean()
Performs Less_than_equal (<=) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.<=/2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_LESSEQ)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 15]) <= Image.build_image!(2, 2, [5, 20])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[0, 255], [0, 255]], [[0, 255], [0, 255]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [5]) <= Image.build_image!(2, 2, [10])
iex> all?(img, true)
true
Multi-band Image Operations
# Different band count scenarios
iex> (Image.build_image!(10, 10, [10, 20, 30]) <= Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
true
iex> (Image.build_image!(10, 10, [20]) <= Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
false
iex> (Image.build_image!(10, 10, [1, 2, 3]) <= Image.build_image!(10, 10, [6])) |> all?(true)
true
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [5, 10, 15]) <= 5
iex> Image.to_list!(img)
[[[255, 0, 0]], [[255, 0, 0]]]
# Comparing with integer
iex> (Image.build_image!(10, 10, [4]) <= 2) |> all?(true)
false
# Comparing with float
iex> (Image.build_image!(10, 10, [4]) <= 4.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) <= [20, 10]
iex> Image.to_list!(img)
[[[255, 0]]]
Reverse Comparison
# Float on the left side
iex> (4.0 <= Image.build_image!(10, 10, [5])) |> all?(true)
true
# List on the left side
iex> ([10, 20, 30] <= Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.<= behavior when no images involved
iex> 4 <= 5
true
@spec (Vix.Vips.Image.t() | number() | [number()]) == (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() == term() :: boolean()
Performs Equal (==) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.==/2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_EQUAL)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 20]) == Image.build_image!(2, 2, [20, 20])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[0, 255], [0, 255]], [[0, 255], [0, 255]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [10]) == Image.build_image!(2, 2, [10])
iex> all?(img, true)
true
Multi-band Image Operations
# Equal values across all bands
iex> (Image.build_image!(10, 10, [10, 20, 30]) == Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
# Single vs multi-band comparison
iex> (Image.build_image!(10, 10, [20]) == Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
false
# Same value across all bands equals single-band image
iex> (Image.build_image!(10, 10, [10, 10, 10]) == Image.build_image!(10, 10, [10])) |> all?(true)
true
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [5, 10, 20]) == 5
iex> Image.to_list!(img)
[[[255, 0, 0]], [[255, 0, 0]]]
# Non-matching comparison
iex> (Image.build_image!(10, 10, [10]) == 5) |> all?(true)
false
# Float comparison (type coercion)
iex> (Image.build_image!(10, 10, [10]) == 10.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) == [10, 10]
iex> Image.to_list!(img)
[[[255, 0]]]
Reverse Comparison
# Float on the left side
iex> (10.0 == Image.build_image!(10, 10, [10])) |> all?(true)
true
# List on the left side
iex> ([10, 20, 30] == Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.== behavior when no images involved
iex> 4 == 4
true
@spec (Vix.Vips.Image.t() | number() | [number()]) > (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() > term() :: boolean()
Performs Greater_than (>) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.>/2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_MORE)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 15]) > Image.build_image!(2, 2, [5, 20])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[255, 0], [255, 0]], [[255, 0], [255, 0]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [10]) > Image.build_image!(2, 2, [5])
iex> all?(img, true)
true
Multi-band Image Operations
# Equal values comparison
iex> (Image.build_image!(10, 10, [10, 20, 30]) > Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
false
# Multi-band vs single-band comparison
iex> (Image.build_image!(10, 10, [10]) > Image.build_image!(10, 10, [20, 30, 40])) |> all?(true)
false
# Comparing with smaller value
iex> (Image.build_image!(10, 10, [10, 20, 30]) > Image.build_image!(10, 10, [5])) |> all?(true)
true
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [5, 15, 25]) > 20
iex> Image.to_list!(img)
[[[0, 0, 255]], [[0, 0, 255]]]
# Comparing with integer
iex> (Image.build_image!(10, 10, [10]) > 20) |> all?(true)
false
# Comparing with float
iex> (Image.build_image!(10, 10, [20]) > 10.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) > [20, 10]
iex> Image.to_list!(img)
[[[0, 255]]]
Reverse Comparison
# Float on the left side
iex> (5.0 > Image.build_image!(10, 10, [4])) |> all?(true)
true
# List on the left side
iex> ([20, 30, 40] > Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.> behavior when no images involved
iex> 5 > 4
true
@spec (Vix.Vips.Image.t() | number() | [number()]) >= (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() >= term() :: boolean()
Performs Greater_than_equal (>=) comparison between Images and numbers, returning the result as an Image.
Overview
The operator compares Images and numbers, with the result being an Image where:
0
representsfalse
255
representstrue
When neither argument is an image, the operation delegates to Kernel.>=/2
.
Behavior
Image Comparison Rules
- Single number: Applied to all image bands
- List matching image bands: Each number maps to corresponding band
- List size does not match bands: Creates multi-band output with either the image bands or the list is scaled up to match the other.
- Two images: Uses
Operation.relational!(a, b, :VIPS_OPERATION_RELATIONAL_MOREEQ)
. Bands are scaled up to match each other.
Type Handling
- Images are cast to the smallest common format before comparison
- Supports mixed numeric types (e.g., integers with floats)
- Works bidirectionally (image < number and number < image)
Examples
Examples
Basic Image Comparison
# Comparing two images
iex> img = Image.build_image!(2, 2, [10, 15]) >= Image.build_image!(2, 2, [5, 20])
iex> Image.shape(img)
{2, 2, 2}
iex> Image.to_list!(img)
[[[255, 0], [255, 0]], [[255, 0], [255, 0]]]
Checking All Pixels
# Using all?/2 to verify if all pixels match condition
iex> img = Image.build_image!(2, 2, [10]) >= Image.build_image!(2, 2, [5])
iex> all?(img, true)
true
Multi-band Image Operations
# Greater values comparison
iex> (Image.build_image!(10, 10, [20, 30, 40]) >= Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
# Equal values comparison
iex> (Image.build_image!(10, 10, [10, 20, 30]) >= Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
# Single vs multi-band comparison
iex> (Image.build_image!(10, 10, [20]) >= Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
false
# Multi vs single-band comparison
iex> (Image.build_image!(10, 10, [10, 20, 30]) >= Image.build_image!(10, 10, [10])) |> all?(true)
true
Image vs. Number Comparison
# Single number compared to all bands
iex> img = Image.build_image!(1, 2, [5, 10, 15]) >= 10
iex> Image.to_list!(img)
[[[0, 255, 255]], [[0, 255, 255]]]
# Comparing with larger number
iex> (Image.build_image!(10, 10, [10]) >= 20) |> all?(true)
false
# Comparing with float
iex> (Image.build_image!(10, 10, [20]) >= 10.0) |> all?(true)
true
# List comparison with bands
iex> img = Image.build_image!(1, 1, [10, 20]) >= [20, 10]
iex> Image.to_list!(img)
[[[0, 255]]]
Reverse Comparison
# Float on the left side
iex> (10.0 >= Image.build_image!(10, 10, [5])) |> all?(true)
true
# List on the left side
iex> ([20, 30, 40] >= Image.build_image!(10, 10, [10, 20, 30])) |> all?(true)
true
Fallback Behavior
# Standard Kernel.>= behavior when no images involved
iex> 5 >= 4
true
@spec all?(Vix.Vips.Image.t(), boolean()) :: boolean()
Checks if all of the values are "true" (255) or "false" (0). Useful together with relational operators.
Examples
Check if two images are equal
iex> all?(Image.build_image!(10, 20, [255, 255, 255]), true)
true
iex> img = (Image.build_image!(10, 20, [50, 100, 150]) == Image.build_image!(10, 20, [50, 100, 150]))
iex> all?(img, true)
true
iex> img = (Image.build_image!(10, 20, [100, 150, 200]) < Image.build_image!(10, 20, [50, 100, 150]))
iex> all?(img, true)
false
iex> all?(img, false)
true
@spec xor( Vix.Vips.Image.t() | number() | [number()], Vix.Vips.Image.t() | number() | [number()] ) :: Vix.Vips.Image.t()
@spec xor(term(), term()) :: term()
Performs Bitwise Boolean XOR Operation (xor) between Images and numbers, returning the result as an Image.
Overview
The operation handles various input combinations:
- Image xor Image
- Image xor number(s)
- number(s) xor Image
Input Handling
Values are cast up before operations. Float values are converted to integers
Number Inputs
- Single number: Applied to all image bands uniformly
- Number list:
- If list size matches image bands: Each number applies to its respective band
- If list size does not match the image bands: Either the image bands or the list is scaled up to match the other.
Image Inputs
- When both inputs are images: Uses
Operation.boolean!(a, b, :VIPS_OPERATION_BOOLEAN_EOR)
Examples
Image XOR Image Operations
iex> img = xor(Image.build_image!(2, 1, [0, 255, 0]), Image.build_image!(2, 1, [0, 255, 255]))
iex> Image.shape(img)
{2, 1, 3}
iex> Image.to_list!(img)
[[[0, 0, 255], [0, 0, 255]]]
# Identical Images
iex> xor(Image.build_image!(2, 2, [2, 4, 8]), Image.build_image!(2, 2, [2, 4, 8])) |> Image.to_list!()
[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]
# Different dimensions
iex> img = xor(Image.build_image!(1, 1, [2]), Image.build_image!(1, 2, [2, 4, 8]))
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[0, 6, 10]], [[2, 4, 8]]]
Image XOR Number Operations
# Single number comparison (applies to all bands)
iex> xor(Image.build_image!(1, 2, [2, 5, 3]), 6) |> Image.to_list!()
[[[4, 3, 5]], [[4, 3, 5]]]
# Float Comparison
iex> xor(Image.build_image!(1, 1, [10]), 6.0) |> Image.to_list!()
[[[12]]]
# List comparison (band-wise)
iex> xor(Image.build_image!(1, 1, [2, 2]), [1, 3]) |> Image.to_list!()
[[[3, 1]]]
Reverse Operations
# Number XOR Image
iex> xor(10.0, Image.build_image!(1, 1, [5])) |> Image.to_list!()
[[[15]]]
# List XOR Image
iex> xor([2, 2], Image.build_image!(1, 1, [1, 3])) |> Image.to_list!()
[[[3, 1]]]
@spec (Vix.Vips.Image.t() | number() | [number()]) || (Vix.Vips.Image.t() | number() | [number()]) :: Vix.Vips.Image.t()
@spec term() || term() :: term()
Performs Bitwise Boolean OR Operation (||) between Images and numbers, returning the result as an Image.
Overview
The operation handles various input combinations:
- Image || Image
- Image || number(s)
- number(s) || Image
- non-Image values (falls back to
Kernel
)
Input Handling
Values are cast up before operations. Float values are converted to integers
Number Inputs
- Single number: Applied to all image bands uniformly
- Number list:
- If list size matches image bands: Each number applies to its respective band
- If list size does not match the image bands: Either the image bands or the list is scaled up to match the other.
Image Inputs
- When both inputs are images: Uses
Operation.boolean!(a, b, :VIPS_OPERATION_BOOLEAN_OR)
Examples
Image || Image Operations
iex> img = Image.build_image!(2, 1, [0, 255, 0]) || Image.build_image!(2, 1, [0, 255, 255])
iex> Image.shape(img)
{2, 1, 3}
iex> Image.to_list!(img)
[[[0, 255, 255], [0, 255, 255]]]
# Identical Images
iex> (Image.build_image!(2, 2, [2, 4, 8]) || Image.build_image!(2, 2, [2, 4, 8])) |> Image.to_list!()
[[[2, 4, 8], [2, 4, 8]], [[2, 4, 8], [2, 4, 8]]]
# Different dimensions
iex> img = Image.build_image!(1, 1, [2]) || Image.build_image!(1, 2, [2, 4, 8])
iex> Image.shape(img)
{1, 2, 3}
iex> Image.to_list!(img)
[[[2, 6, 10]], [[2, 4, 8]]]
Image || Number Operations
# Single number comparison (applies to all bands)
iex> (Image.build_image!(1, 2, [2, 4, 8]) || 4) |> Image.to_list!()
[[[6, 4, 12]], [[6, 4, 12]]]
# Float Comparison
iex> (Image.build_image!(1, 1, [4]) || 2.0) |> Image.to_list!()
[[[6]]]
# List comparison (band-wise)
iex> (Image.build_image!(1, 1, [2, 2]) || [1, 3]) |> Image.to_list!()
[[[3, 3]]]
Reverse Operations
# Number || Image
iex> (4.0 || Image.build_image!(1, 1, [2])) |> Image.to_list!()
[[[6]]]
# List || Image
iex> ([2, 2] || Image.build_image!(1, 1, [1, 3])) |> Image.to_list!()
[[[3, 3]]]
Kernel Fallback
# When neither argument is an image
iex> false || true
true