View Source Vix.Vips.Image (vix v0.33.0)

Primary module for reading and writing image and image metadata.

This module allows you to read, write, manipulate and analyze images efficiently using the powerful libvips image processing library. It offers operations like loading images, accessing metadata, and extracting image bands.

Basic Usage

# Load an image from file
{:ok, image} = Image.new_from_file("path/to/image.jpg")

# Create a new RGB image
{:ok, blank} = Image.build_image(width, height, [0, 0, 0])

Access Syntax (Image Slicing)

The module implements Elixir's Access behavior, providing an intuitive way to slice and extract image data across three dimensions: width, height, and bands (color channels).

Band Extraction

Access individual color bands using integer indices:

# Get the red channel from an RGB image
red_channel = image[0]

# Get the alpha channel (last band) from an RGBA image
alpha = image[-1]

Band Ranges

Extract multiple consecutive bands using ranges:

# Get red and green channels from RGB
red_green = image[0..1]

# Get all channels.
all_channels = image[0..-1//1]
# Same as `all_channels = image`

Dimensional Slicing

Slice images across multiple dimensions using lists of the form [width, height, bands]:

# Get a 100x100 pixel square from the top-left corner
top_left = image[[0..99, 0..99]]

# Get the bottom-right 50x50 pixel square
bottom_right = image[[-50..-1, -50..-1]]

# Get the bottom-right 50x50 pixel square, and only green channel
bottom_right = image[[-50..-1, -50..-1, 1]]

Named Dimension Access

Use keyword lists for more explicit dimension specification:

# Get first 200 pixels in width, maintaining full height and bands
slice = image[[width: 0..199]]

# Get specific height range with all bands
middle = image[[height: 100..299]]

# Extract specific band
green = image[[band: 1]]

# Get a 100x100 pixel square from the top-left corner, and only red-green channels
bottom_right = image[[width: 0..99, height: 0..99, band: 0..1]]

See Vix.Vips.Operation for available image processing operations.

Summary

Types

t()

Represents an instance of VipsImage

Functions

Get "bands" of the image

Creates a new image with specified dimensions and background values.

Creates a new image with specified dimensions and background values.

Get "coding" of the image

Extracts a band from an image using Access syntax.

Get "filename" of the image

Get "format" of the image

Returns the pixel value for the passed position

Same as get_pixel/3. Returns the pixel value on success or raise the error.

Return a boolean indicating if an image has an alpha band.

Get all image header field names.

Get image header value.

Get image header value as string.

Get all image header data as map. Headers includes metadata such as image height, width, bands.

Get "height" of the image

Get "interpretation" of the image

Get "mode" of the image

Mutate an image in-place. You have to pass a function which takes MutableImage as argument. Inside the callback function, you can call functions which modify the image, such as setting or removing metadata. See Vix.Vips.MutableImage

Get "n-pages" of the image

Creates a new image from raw pixel data with zero-copy performance.

Creates a new image from formatted binary data (like JPEG, PNG, etc.).

Creates a new image by lazily reading from an Enumerable source.

Opens an image file for reading and returns a Vix.Vips.Image.t/0 struct.

Creates a new image by cloning dimensions and properties from an existing image, filling all bands with specified values.

Make a VipsImage from 1D or 2D list.

Make a VipsImage which, when written to, will create a temporary file on disc.

Get "offset" of the image

Get "orientation" of the image

Get "page-height" of the image

Get "scale" of the image

Returns 3 element tuple representing {width, height, number_of_bands}

Returns list of supported extension for saving the image.

Converts an Image to a nested list.

Same as to_list!/1 but raises error instead of returning it.

Get "width" of the image

Extracts raw pixel data from a VIPS image as a binary term.

Converts a VIPS image to a binary representation in the specified format.

Writes a VIPS image to a file in the format determined by the file extension.

Creates a Stream that lazily writes image data in the specified format.

Extracts raw pixel data from a VIPS image as a Vix.Tensor structure.

Get "xoffset" of the image

Get "xres" of the image

Get "yoffset" of the image

Get "yres" of the image

Types

t()

@type t() :: %Vix.Vips.Image{ref: reference()}

Represents an instance of VipsImage

Functions

bands(image)

@spec bands(t()) :: pos_integer() | no_return()

Get "bands" of the image

More details

See libvips docs for more details regarding bands function

build_image(width, height, background \\ [0, 0, 0], opts \\ [])

@spec build_image(
  pos_integer(),
  pos_integer(),
  [number()],
  opts :: [
    interpretation: Vix.Vips.Operation.vips_interpretation() | :auto,
    format: Vix.Vips.Operation.vips_band_format() | :auto
  ]
) :: {:ok, t()} | {:error, term()}

Creates a new image with specified dimensions and background values.

Takes width, height, and a list of background values to create a new image. The background values determine both the number of bands and initial pixel values.

Parameters

  • width - Width of the image in pixels (positive integer)
  • height - Height of the image in pixels (positive integer)
  • background - List of numbers representing initial pixel values for each band. Defaults to [0, 0, 0]
  • opts - Keyword list of options

Options

  • :interpretation - Color space interpretation. Can be a valid vips_interpretation or :auto. When :auto, determined by number of bands:

    • 1 band -> :VIPS_INTERPRETATION_B_W
    • 3 bands -> :VIPS_INTERPRETATION_RGB
    • 4 bands -> :VIPS_INTERPRETATION_sRGB
    • other -> :VIPS_INTERPRETATION_MULTIBAND
  • :format - Pixel value format. Can be a valid vips_format or :auto. When :auto, determined by value ranges. For example:

    • 0-255 -> :VIPS_FORMAT_UCHAR
    • decimal values -> :VIPS_FORMAT_DOUBLE
    • larger integers -> :VIPS_FORMAT_INT

Examples

iex> {:ok, %Image{ref: _} = img} = Image.build_image(1, 2, [10])
iex> Image.to_list(img)
{:ok, [[[10]], [[10]]]}
iex> Image.shape(img)
{1, 2, 1}

Sets the interpretation based on the bands

iex> {:ok, img} = Image.build_image(1, 2, [10])
iex> Image.interpretation(img)
:VIPS_INTERPRETATION_B_W
iex> {:ok, img} = Image.build_image(10, 10, [10, 10, 10])
iex> Image.interpretation(img)
:VIPS_INTERPRETATION_RGB
iex> {:ok, img} = Image.build_image(10, 10, [10, 10, 10, 10])
iex> Image.interpretation(img)
:VIPS_INTERPRETATION_sRGB
iex> {:ok, img} = Image.build_image(10, 10, [10, 10, 10, 10], interpretation: :VIPS_INTERPRETATION_MULTIBAND)
iex> Image.interpretation(img)
:VIPS_INTERPRETATION_MULTIBAND

Sets the band format based on the values

iex> {:ok, img} = Image.build_image(1, 2, [10, 9, 220])
iex> Image.format(img)
:VIPS_FORMAT_UCHAR
iex> {:ok, img} = Image.build_image(10, 10, [10, -120, 200])
iex> Image.format(img)
:VIPS_FORMAT_SHORT
iex> {:ok, img} = Image.build_image(10, 10, [10, -120, 1.0])
iex> Image.format(img)
:VIPS_FORMAT_DOUBLE
iex> {:ok, img} = Image.build_image(10, 10, [10, -40000, 39])
iex> Image.format(img)
:VIPS_FORMAT_INT
iex> {:ok, img} = Image.build_image(10, 10, [10, -80, 10], format: :VIPS_FORMAT_CHAR)
iex> Image.format(img)
:VIPS_FORMAT_CHAR

build_image!(width, height, background \\ [0, 0, 0])

@spec build_image!(pos_integer(), pos_integer(), [number()]) :: t() | no_return()

Creates a new image with specified dimensions and background values.

Similar to build_image/4 but raises Image.Error on failure instead of returning error tuple.

Examples

iex> img = Image.build_image!(1, 2, [10])
iex> Image.to_list(img)
{:ok, [[[10]], [[10]]]}
iex> Image.shape(img)
{1, 2, 1}

See build_image/4 for detailed documentation.

coding(image)

@spec coding(t()) :: Vix.Vips.Operation.vips_coding() | no_return()

Get "coding" of the image

More details

See libvips docs for more details regarding coding function

fetch(image, band)

Extracts a band from an image using Access syntax.

This function implements the Access behaviour for images, enabling array-like syntax for extracting bands and slices. See the module documentation for detailed examples of Access syntax usage.

Parameters

  • image - The source image
  • band - Integer index, Range, or list specifying what to extract

Returns

  • {:ok, image} with extracted data
  • Raises ArgumentError for invalid access patterns

Access is read-only - get_and_update/3 and pop/2 are not supported.

Examples

# Get red channel
{:ok, red} = Image.fetch(rgb_image, 0)

# Get first two channels
{:ok, rg} = Image.fetch(rgb_image, 0..1)

# Get 100x100 region from top-left
{:ok, region} = Image.fetch(image, [0..99, 0..99])

# Get specific height range
{:ok, slice} = Image.fetch(image, [height: 100..199])

See Vix.Vips.Image module docs for more details

filename(image)

@spec filename(t()) :: String.t() | no_return()

Get "filename" of the image

More details

See libvips docs for more details regarding filename function

format(image)

Get "format" of the image

More details

See libvips docs for more details regarding format function

get_pixel(image, x, y)

@spec get_pixel(t(), x :: non_neg_integer(), y :: non_neg_integer()) ::
  {:ok, [term()]} | {:error, term()}

Returns the pixel value for the passed position

Pixel value is a list of numbers. Size of the list depends on the number of bands in the image and number type will depend on the band format (see: Vix.Vips.Operation.vips_band_format/0).

For example for RGBA image with unsigned char band format the return value will be a list of integer of size 4.

This function is similar to Vix.Vips.Operation.getpoint/3, getpoint always returns the value as float but get_pixel returns based on the image band format.

Caution

Loop through lot of pixels using get_pixel can be expensive. Use extract_area or Access syntax (slicing) instead

get_pixel!(image, x, y)

@spec get_pixel!(t(), x :: non_neg_integer(), y :: non_neg_integer()) ::
  [term()] | no_return()

Same as get_pixel/3. Returns the pixel value on success or raise the error.

has_alpha?(image)

@spec has_alpha?(t()) :: boolean() | no_return()

Return a boolean indicating if an image has an alpha band.

Example

  {:ok, im} = Image.new_from_file("puppies.jpg")

  has_alpha? = Image.has_alpha?(im)

header_field_names(image)

@spec header_field_names(t()) :: {:ok, [String.t()]} | {:error, term()}

Get all image header field names.

See https://libvips.github.io/libvips/API/current/libvips-header.html#vips-image-get-fields for more details

header_value(image, name)

@spec header_value(t(), String.t()) ::
  {:ok, integer() | float() | String.t() | binary() | list() | atom()}
  | {:error, term()}

Get image header value.

This is a generic function to get header value.

Casts the value to appropriate type. Returned value can be integer, float, string, binary, list. Use Vix.Vips.Image.header_value_as_string/2 to get string representation of any header value.

{:ok, width} = Image.header_value(vips_image, "width")

header_value_as_string(image, name)

@spec header_value_as_string(t(), String.t()) :: {:ok, String.t()} | {:error, term()}

Get image header value as string.

This is generic method to get string representation of a header value. If value is VipsBlob, then it returns base64 encoded data.

See: https://libvips.github.io/libvips/API/current/libvips-header.html#vips-image-get-as-string

headers(image)

@spec headers(t()) :: %{
  width: pos_integer() | nil,
  height: pos_integer() | nil,
  bands: pos_integer() | nil,
  xres: float() | nil,
  yres: float() | nil,
  xoffset: integer() | nil,
  yoffset: integer() | nil,
  filename: String.t() | nil,
  mode: String.t() | nil,
  scale: float() | nil,
  offset: float() | nil,
  "page-height": integer() | nil,
  "n-pages": integer() | nil,
  orientation: integer() | nil,
  interpretation: Vix.Vips.Operation.vips_interpretation() | nil,
  coding: Vix.Vips.Operation.vips_coding() | nil,
  format: Vix.Vips.Operation.vips_band_format() | nil
}

Get all image header data as map. Headers includes metadata such as image height, width, bands.

If a header does not exists then value for that header will be set to nil.

See https://libvips.github.io/libvips/API/current/libvips-header.html for more details.

height(image)

@spec height(t()) :: pos_integer() | no_return()

Get "height" of the image

More details

See libvips docs for more details regarding height function

interpretation(image)

@spec interpretation(t()) :: Vix.Vips.Operation.vips_interpretation() | no_return()

Get "interpretation" of the image

More details

See libvips docs for more details regarding interpretation function

mode(image)

@spec mode(t()) :: String.t() | no_return()

Get "mode" of the image

More details

See libvips docs for more details regarding mode function

mutate(image, callback)

@spec mutate(t(), (Vix.Vips.MutableImage.t() -> any())) ::
  {:ok, t()} | {:ok, {t(), any()}} | {:error, term()}

Mutate an image in-place. You have to pass a function which takes MutableImage as argument. Inside the callback function, you can call functions which modify the image, such as setting or removing metadata. See Vix.Vips.MutableImage

Return value of the callback must be one of:

  • The mutated image passed to the callback or
  • :ok or
  • {:ok, some_result}

Call returns updated image.

Example

  {:ok, im} = Image.new_from_file("puppies.jpg")

  {:ok, new_im} =
    Image.mutate(im, fn mut_image ->
      :ok = MutableImage.update(mut_image, "orientation", 0)
      :ok = MutableImage.set(mut_image, "new-field", :gint, 0)
    end)

n_pages(image)

@spec n_pages(t()) :: integer() | no_return()

Get "n-pages" of the image

More details

See libvips docs for more details regarding n_pages function

new_from_binary(bin, width, height, bands, band_format)

@spec new_from_binary(
  binary(),
  pos_integer(),
  pos_integer(),
  pos_integer(),
  Vix.Vips.Operation.vips_band_format()
) :: {:ok, t()} | {:error, term()}

Creates a new image from raw pixel data with zero-copy performance.

This function wraps raw pixel data without copying, making it highly efficient for integrating with other imaging libraries or processing pipelines. It's particularly useful when working with raw pixel data from libraries like eVision or Nx.

Parameters

  • bin - Binary containing raw pixel data in left-to-right, top-to-bottom order
  • width - Image width in pixels
  • height - Image height in pixels
  • bands - Number of bands per pixel (e.g., 3 for RGB, 4 for RGBA)
  • band_format - Format of each band (typically :VIPS_FORMAT_UCHAR)

Endianness Requirements

The binary data MUST be in native endianness. When using bitstring syntax, always specify the native modifier:

# Correct - using native endianness
<<r::native-integer-size(8), g::native-integer-size(8), b::native-integer-size(8)>>

# Incorrect - default big endian
<<r::integer-size(8), g::integer-size(8), b::integer-size(8)>>

See Elixir docs for more details.

Examples

Creating an RGB image from raw pixel data

pixels = <<
  255, 0, 0,    # Red pixel
  0, 255, 0,    # Green pixel
  0, 0, 255     # Blue pixel
>>
{:ok, image} = Image.new_from_binary(pixels, 3, 1, 3, :VIPS_FORMAT_UCHAR)

Working with grayscale data:

gray_data = <<128, 64, 32, 16>>  # 4 gray pixels
{:ok, gray_image} = Image.new_from_binary(gray_data, 4, 1, 1, :VIPS_FORMAT_UCHAR)

Creating an RGB image from raw pixel data:

pixel_data = get_rgb_pixels() # Binary of RGB values
{:ok, image} = Image.new_from_binary(pixel_data, 640, 480, 3, :VIPS_FORMAT_UCHAR)

For loading formatted binary (JPEG, PNG, etc) see new_from_buffer/2.

new_from_buffer(bin, opts \\ [])

@spec new_from_buffer(
  binary(),
  keyword()
) :: {:ok, t()} | {:error, term()}

Creates a new image from formatted binary data (like JPEG, PNG, etc.).

This function attempts to automatically detect the image format from the binary data. It's particularly useful when working with image data from network requests, databases, or other binary sources.

Parameters

  • bin - Binary data containing a formatted image (JPEG, PNG, etc.)
  • opts - Format-specific loading options (same as new_from_file/2)

Examples

Basic usage with binary data:

{:ok, image} = Image.new_from_buffer(jpeg_binary)

Loading with specific options:

{:ok, image} = Image.new_from_buffer(jpeg_binary, shrink: 2)

Working with HTTP responses:

{:ok, response} = HTTPClient.get("https://example.com/image.jpg")
{:ok, image} = Image.new_from_buffer(response.body)

Format-Specific Loading

For known formats, you can use specific loaders from Vix.Vips.Operation:

{:ok, image} = Vix.Vips.Operation.jpegload_buffer(jpeg_binary, access: :VIPS_ACCESS_SEQUENTIAL)

new_from_enum(enum, opts \\ [])

@spec new_from_enum(Enumerable.t(), String.t() | keyword()) ::
  {:ok, t()} | {:error, term()}

Creates a new image by lazily reading from an Enumerable source.

This function is ideal for processing large images without loading the entire file into memory. It detects the image format from the initial bytes and reads remaining data on-demand.

Parameters

  • enum - An Enumerable producing image data (e.g., File.stream!, HTTP chunks)
  • opts - Optional keyword list of format-specific options. To be backward compatible it also accepts options as a string in "[name=value,...]" format for the time being.

Examples

Reading from a file stream:

{:ok, image} =
  File.stream!("large_photo.jpg", [], 65_536)
  |> Image.new_from_enum()

Reading from a file with options:

{:ok, image} =
  File.stream!("large_photo.jpg", [], 65_536)
  |> Image.new_from_enum(shrink: 2)

Processing S3 stream:

{:ok, image} =
  ExAws.S3.download_file("bucket", "image.jpg")
  |> Stream.map(&process_chunk/1)
  |> Image.new_from_enum()

Format Options

To see format-specific options, check Operation module.

new_from_file(path)

new_from_file(path, opts)

(since 0.31.0)
@spec new_from_file(
  String.t(),
  keyword()
) :: {:ok, t()} | {:error, term()}

Opens an image file for reading and returns a Vix.Vips.Image.t/0 struct.

This function provides a high-level interface to load images from many format depending on the libraries installed.

Options

The opts parameter accepts format-specific loading options. Each format supports different options which can be found in the Operation module documentation.

Examples

# Basic usage:
{:ok, %Image{} = image} = Image.new_from_file("photo.jpg")

# Loading with options (downsampling by factor of 2):
{:ok, image} = Image.new_from_file("large_photo.jpg", shrink: 2)

# Loading a specific page from a multi-page TIFF
{:ok, page} = Image.new_from_file("document.tiff", page: 1)

# Loading a PNG with specific options:
{:ok, image} = Image.new_from_file("transparent.png", access: :VIPS_ACCESS_SEQUENTIAL)

To see all available options for a specific format, you can check the corresponding loader function. For example, Vix.Vips.Operation.jpegload/2 documents all JPEG-specific options.

Performance Notes

The loading process is optimized - only the image header is initially loaded into memory. Pixel data is decompressed on-demand when accessed, making this operation memory-efficient for large images.

Advanced Usage

For more control over the loading process, consider using format-specific loaders from Vix.Vips.Operation. For example:

# Using specific JPEG loader
{:ok, image} = Vix.Vips.Operation.jpegload("photo.jpg", access: :VIPS_ACCESS_SEQUENTIAL)

new_from_image(image, value)

@spec new_from_image(t(), [number()]) :: {:ok, t()} | {:error, term()}

Creates a new image by cloning dimensions and properties from an existing image, filling all bands with specified values.

The new image inherits the following properties from the source image:

  • Width and height
  • Format and color interpretation
  • Resolution
  • Offset

Parameters

  • image - Source image to clone properties from
  • value - List of numbers representing values for each band

Examples

Create a solid red image with same dimensions as source:

{:ok, red_image} = Image.new_from_image(source_image, [255, 0, 0])

Create a semi-transparent overlay:

{:ok, overlay} = Image.new_from_image(source_image, [0, 0, 0, 128])

new_from_list(list, optional \\ [])

@spec new_from_list(
  [[number()]] | [number()] | Range.t(),
  keyword()
) :: {:ok, t()} | {:error, term()}

Make a VipsImage from 1D or 2D list.

If list is a single dimension then an image of height 1 will be with list content as values.

If list is 2D then 2D image will be created.

Output image will always be a one band image with double format.

# 1D list
{:ok, img2} = Image.new_from_list([0, 1, 0])

# 2D list
{:ok, img} = Image.new_from_list([[0, 1, 0], [1, 1, 1], [0, 1, 0]])

Optional

  • scale - Default: 1
  • offset - Default: 0

new_matrix_from_array(width, height, list, optional \\ [])

@spec new_matrix_from_array(integer(), integer(), [list()], keyword()) ::
  {:ok, t()} | {:error, term()}

Make a VipsImage from 2D list.

This is a convenience function makes an image which is a matrix: a one-band VIPS_FORMAT_DOUBLE image held in memory. Useful for vips operations such as conv.

{:ok, mask} = Image.new_matrix_from_array(3, 3, [[0, 1, 0], [1, 1, 1], [0, 1, 0]])

Optional

  • scale - Default: 1
  • offset - Default: 0

new_temp_file(format)

@spec new_temp_file(String.t()) :: {:ok, t()} | {:error, term()}

Make a VipsImage which, when written to, will create a temporary file on disc.

The file will be automatically deleted when the image is destroyed. format is something like "%s.v" for a vips file.

The file is created in the temporary directory. This is set with the environment variable TMPDIR. If this is not set, then on Unix systems, vips will default to /tmp. On Windows, vips uses GetTempPath() to find the temporary directory.

vips_image = Image.new_temp_file("%s.v")

offset(image)

@spec offset(t()) :: float() | no_return()

Get "offset" of the image

More details

See libvips docs for more details regarding offset function

orientation(image)

@spec orientation(t()) :: integer() | no_return()

Get "orientation" of the image

More details

See libvips docs for more details regarding orientation function

page_height(image)

@spec page_height(t()) :: integer() | no_return()

Get "page-height" of the image

More details

See libvips docs for more details regarding page_height function

scale(image)

@spec scale(t()) :: float() | no_return()

Get "scale" of the image

More details

See libvips docs for more details regarding scale function

shape(image)

@spec shape(t()) :: {pos_integer(), pos_integer(), pos_integer()}

Returns 3 element tuple representing {width, height, number_of_bands}

Examples

iex> img = Image.build_image!(100, 200, [1, 2, 3])
iex> Image.shape(img)
{100, 200, 3}

supported_saver_suffixes()

@spec supported_saver_suffixes() :: {:ok, [String.t()]} | {:error, term()}

Returns list of supported extension for saving the image.

Supported suffix can be used to save image in a particular format. See write_to_file/2.

Note that the image format supported for saving the image and the format supported for loading image might be different. For example SVG format can be loaded but can not be saved.

to_list(image)

@spec to_list(t()) :: {:ok, [[[number()]]]} | {:error, term()}

Converts an Image to a nested list.

Returns a nested list of the shape height x width x band. For example for an image with height 10, width 5, and 3 bands returned value will be a list of length 10 (height), with each element will be a list of length 5 (height), and each element inside that will be a list of length 3 (bands).

Caution

This is meant to be used for very small images such as histograms, and matrix. Depending on the image size it can generate and return a large list leading to performance issues.

histogram =
  Vix.Vips.Operation.black!(10, 50)
  |> Vix.Vips.Operation.hist_find!()

list = Vix.Vips.Image.to_list(histogram)

to_list!(image)

@spec to_list!(t()) :: [[[number()]]] | no_return()

Same as to_list!/1 but raises error instead of returning it.

width(image)

@spec width(t()) :: pos_integer() | no_return()

Get "width" of the image

More details

See libvips docs for more details regarding width function

write_to_binary(image)

@spec write_to_binary(t()) :: {:ok, binary()} | {:error, term()}

Extracts raw pixel data from a VIPS image as a binary term.

This is a lower-level alternative to write_to_tensor/1 that returns only the raw binary data without the associated metadata. It's primarily intended for cases where you already know the image dimensions and format.

Warning

It's recommended to use write_to_tensor/1 instead of this function unless you have a specific need for the raw binary data and already know:

  • Image dimensions (height × width)
  • Number of bands
  • Pixel data format
  • Data layout and organization

Examples

Extracting raw binary data:

{:ok, binary_data} = Image.write_to_binary(image)

write_to_buffer(image, suffix)

write_to_buffer(image, suffix, opts)

(since 0.32.0)
@spec write_to_buffer(t(), String.t(), keyword()) ::
  {:ok, binary()} | {:error, term()}

Converts a VIPS image to a binary representation in the specified format.

This function is similar to write_to_file/3 but returns the encoded image as a binary instead of writing to a file. This is particularly useful for web applications or when working with in-memory image processing pipelines.

Parameters

  • image - The source Vix.Vips.Image.t/0 to convert
  • suffix - Format extension (e.g., ".jpg", ".png")
  • opts - Format-specific encoding options

Examples

Basic conversion to different formats:

# Convert to JPEG binary
{:ok, jpeg_binary} = Image.write_to_buffer(image, ".jpg")

# Convert to PNG binary
{:ok, png_binary} = Image.write_to_buffer(image, ".png")

Converting with quality settings:

# JPEG with 90% quality
{:ok, jpeg_binary} = Image.write_to_buffer(image, ".jpg", Q: 90)

# PNG with maximum compression
{:ok, png_binary} = Image.write_to_buffer(image, ".png", compression: 9)

Web application example:

def show_image(conn, %{"id" => id}) do
  image = MyApp.get_image!(id)
  {:ok, binary} = Image.write_to_buffer(image, ".jpg", Q: 85)

  conn
  |> put_resp_content_type("image/jpeg")
  |> send_resp(200, binary)
end

write_to_file(image, path)

write_to_file(image, path, opts)

(since 0.32.0)
@spec write_to_file(t(), String.t(), keyword()) :: :ok | {:error, term()}

Writes a VIPS image to a file in the format determined by the file extension.

Parameters

  • image - The source Vix.Vips.Image.t/0 to save
  • path - Destination file path (format determined by extension)
  • opts - Format-specific saving options

Format Options

Each format supports different saving options, which can be found in the Operation module documentation.

Examples

Basic usage:

:ok = Image.write_to_file(image, "output.jpg")

Saving with quality settings:

# JPEG with 90% quality
:ok = Image.write_to_file(image, "output.jpg", Q: 90)

# PNG with maximum compression
:ok = Image.write_to_file(image, "output.png", compression: 9)

Saving with multiple options:

# JPEG with quality and metadata stripping
:ok = Image.write_to_file(image, "output.jpg", Q: 90, strip: true)

Advanced Usage

For more control, use format-specific savers from Vix.Vips.Operation:

# Using specific JPEG saver
:ok = Vix.Vips.Operation.jpegsave(image, "output.jpg", Q: 95)

write_to_stream(image, suffix)

write_to_stream(image, suffix, opts)

(since 0.32.0)
@spec write_to_stream(t(), String.t(), keyword()) :: Enumerable.t()

Creates a Stream that lazily writes image data in the specified format.

This function is particularly useful for handling large images or when streaming directly to storage/network without intermediate files.

Parameters

  • image - The source image to stream
  • suffix - Output format suffix. (e.g., ".jpg", ".png")
  • opts - Optional keyword list of format-specific options (e.g., [Q: 90])

Examples

Basic streaming to file:

{:ok, image} = Image.new_from_file("input.jpg")

:ok =
  Image.write_to_stream(image, ".png")
  |> Stream.into(File.stream!("output.png"))
  |> Stream.run()

Streaming with quality options:

:ok =
  Image.write_to_stream(image, ".jpg", Q: 90, strip: true)
  |> Stream.into(File.stream!("output.jpg"))
  |> Stream.run()

Streaming to S3:

:ok =
  Image.write_to_stream(image, ".png")
  |> Stream.each(&upload_chunk_to_s3/1)
  |> Stream.run()

Format Options

Each format supports different saving options. View available options in Operation module.

write_to_tensor(image)

@spec write_to_tensor(t()) :: {:ok, Vix.Tensor.t()} | {:error, term()}

Extracts raw pixel data from a VIPS image as a Vix.Tensor structure.

This function provides access to the underlying pixel data in a format suitable for interoperability with other image processing or machine learning libraries.

Image Structure

VIPS images are three-dimensional arrays with the following dimensions:

  • Width: The horizontal size (up to 2^31 pixels)
  • Height: The vertical size (up to 2^31 pixels)
  • Bands: The number of channels per pixel (e.g., 3 for RGB, 4 for RGBA)

Data Format

VIPS supports 10 different numeric formats for pixel values, ranging from 8-bit unsigned integers to 128-bit double complex numbers. Images are treated as uninterpreted arrays of numbers - there's no inherent difference between different color spaces with the same number of bands (e.g., RGBA vs CMYK).

Performance Notes

Depending on the caching mechanism and image construction, VIPS may need to run all the operations in the pipeline to produce the pixel data.

Endianness Considerations

The binary data in the tensor uses native endianness. When processing this data using bitstring syntax, always specify the native modifier:

# Correct - using native endianness
<<value::native-integer-size(8)>>

# Incorrect - default big endian
<<value::integer-size(8)>>

See Elixir docs for more details.

Examples

Converting an image to a tensor:

{:ok, tensor} = Image.write_to_tensor(rgb_image)
%Vix.Tensor{
  data: <<binary_data>>,
  shape: {height, width, 3},
  names: [:height, :width, :bands],
  type: :u8
} = tensor

xoffset(image)

@spec xoffset(t()) :: integer() | no_return()

Get "xoffset" of the image

More details

See libvips docs for more details regarding xoffset function

xres(image)

@spec xres(t()) :: float() | no_return()

Get "xres" of the image

More details

See libvips docs for more details regarding xres function

yoffset(image)

@spec yoffset(t()) :: integer() | no_return()

Get "yoffset" of the image

More details

See libvips docs for more details regarding yoffset function

yres(image)

@spec yres(t()) :: float() | no_return()

Get "yres" of the image

More details

See libvips docs for more details regarding yres function