View Source Vix.Vips.Image (vix v0.30.0)
Functions for reading and writing images as well as accessing and updating image metadata.
Access syntax (slicing)
Vix images implement Elixir's access syntax. This allows developers to slice images and easily access sub-dimensions and values.
Integer
Access accepts integers. Integers will extract an image band using parameter as index:
#=> {:ok, i} = Image.new_from_file("./test/images/puppies.jpg")
{:ok, %Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153539>}}
#=> i[0]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153540>}
If a negative index is given, it accesses the band from the back:
#=> i[-1]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153540>}
Out of bound access will throw an ArgumentError
exception:
#=> i[-4]
** (ArgumentError) Invalid band requested. Found -4
Range
Access also accepts ranges. Ranges in Elixir are inclusive:
#=> i[0..1]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153641>}
Ranges can receive negative positions and they will read from the back. In such cases, the range step must be explicitly given (on Elixir 1.12 and later) and the right-side of the range must be equal or greater than the left-side:
#=> i[0..-1//1]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153703>}
To slice across multiple dimensions, you can wrap the ranges in a list.
The list will be of the form [with_slice, height_slice, band_slice]
.
# Returns an image that slices a 10x10 pixel square
# from the top left of the image with three bands
#=> i[[0..9, 0..9, 0..3]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153738>}
If number of dimensions are less than 3 then remaining dimensions are returned in full
# If `i` size is 100x100 with 3 bands
#=> i[[0..9, 0..9]] # equivalent to `i[[0..9, 0..9, 0..2]]`
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153740>}
#=> i[[0..9]] # equivalent to `i[[0..9, 0..99, 0..2]]`
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153703>}
Slices can include negative ranges in which case the indexes are calculated from the right and bottom of the image.
# Slices the bottom right 10x10 pixels of the image
# and returns all bands.
#=> i[[-10..-1, -10..-1]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153742>}
Slice can mix integers and ranges
# Slices the bottom right 10x1 pixels of the image
# and returns all bands.
#=> i[[-10..-1, -1]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153742>}
Keyword List
Access also accepts keyword list. Where key can be any of width
,
height
, band
. and value must be an integer
, range
. This is
useful for complex scenarios when you want omit dimensions arbitrary
dimensions.
# Slices an image with height 10 with max width and all bands
#=> i[[height: 0..10]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153742>}
# Slices an image with single band 1
#=> i[[band: 1]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153742>}
# Slices the bottom right 10x10 pixels of the image
# and returns all bands.
#=> i[[width: -10..-1, height: -10..-1]]
%Vix.Vips.Image{ref: #Reference<0.2448791511.2685009949.153742>}
Summary
Functions
Get "bands" of the image
Get "coding" of the image
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
Create a new image from raw pixel data
Create a new image from formatted binary
Create a new image from Enumerable.
Opens path
for reading, returns an instance of Vix.Vips.Image.t/0
Create a new image based on an existing image with each pixel set to value
Make a VipsImage from 1D or 2D list.
Make a VipsImage from 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 list of supported extension for saving the image.
Converts an Image to a nested list.
Get "width" of the image
Returns raw pixel data of the image as binary term
Returns vips_image
as binary based on the format specified by suffix
.
Write vips_image
to a file.
Creates a Stream from Image.
Returns raw pixel data of the image as Vix.Tensor
Get "xoffset" of the image
Get "xres" of the image
Get "yoffset" of the image
Get "yres" of the image
Types
@type t() :: %Vix.Vips.Image{ref: reference()}
Represents an instance of VipsImage
Functions
@spec bands(t()) :: pos_integer() | no_return()
Get "bands" of the image
More details
See libvips docs for more details regarding
bands
function
@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
Get "filename" of the image
More details
See libvips docs for more details regarding
filename
function
@spec format(t()) :: Vix.Vips.Operation.vips_band_format() | no_return()
Get "format" of the image
More details
See libvips docs for more details regarding
format
function
@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. Useextract_area
or Access syntax (slicing) instead
@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.
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)
Get all image header field names.
See https://libvips.github.io/libvips/API/current/libvips-header.html#vips-image-get-fields for more details
@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")
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
@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.
@spec height(t()) :: pos_integer() | no_return()
Get "height" of the image
More details
See libvips docs for more details regarding
height
function
@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
Get "mode" of the image
More details
See libvips docs for more details regarding
mode
function
@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)
Get "n-pages" of the image
More details
See libvips docs for more details regarding
n_pages
function
@spec new_from_binary( binary(), pos_integer(), pos_integer(), pos_integer(), Vix.Vips.Operation.vips_band_format() ) :: {:ok, t()} | {:error, term()}
Create a new image from raw pixel data
Creates an image by wrapping passed raw pixel data. This function does not copy the passed binary, instead it just creates a reference to the binary term (zero-copy). So this function is very efficient.
This function is useful when you are getting raw pixel data from
some other library like
eVision
or
Nx
and want to perform some
operation on it using Vix.
Binary should be sequence of pixel data, for example: RGBRGBRGB. and order should be left-to-right, top-to-bottom.
bands
should be number values which represent the each pixel. For
example: if each pixel is RGB then bands
will be 3. If each pixel
is RGBA then bands
will be 4. band_format
refers to type of
each band. Usually it will be :VIPS_FORMAT_UCHAR
.
bin
should be raw pixel data binary. For loading
formatted binary (JPEG, PNG) see new_from_buffer/2
.
Endianness
Byte order of the data must be in native endianness. This matters
if you are generating or manipulating binary by using bitstring
syntax. By default bitstring treat binary byte order as big
endian
which might not be native. Always use native
specifier to
ensure. See Elixir
docs
for more details.
Create a new image from formatted binary
Create a new image from formatted binary bin
. Binary should be an
image encoded in a format such as JPEG. It tries to recognize the
format by checking the binary.
If you already know the image format of bin
then you can just use
corresponding loader operation function directly from
Vix.Vips.Operation
instead. For example to load jpeg, you can use
Vix.Vips.Operation.jpegload_buffer/2
bin
should be formatted binary (ie. JPEG, PNG etc). For loading
unformatted binary (raw pixel data) see new_from_binary/5
.
Optional param opts
is passed to the image loader. Options
available depend on the file format. You can find all options
available like this:
$ vips jpegload_buffer
Not all loaders support load from buffer, but at least JPEG, PNG and TIFF images will work.
@spec new_from_enum(Enumerable.t(), String.t()) :: {:ok, t()} | {:error, term()}
Create a new image from Enumerable.
Returns an image which will lazily pull data from passed
Enumerable. enum
should be stream of bytes of an encoded image
such as JPEG. This functions recognizes the image format and
metadata by reading starting bytes and wraps passed Enumerable as an
image. Remaining bytes are read on-demand.
Useful when working with big images. Where you don't want to load complete input image data to memory.
{:ok, image} =
File.stream!("puppies.jpg", [], 1024) # or read from s3, web-request
|> Image.new_from_enum()
:ok = Image.write_to_file(image, "puppies.png")
Optional param opts
string is passed to the image loader. It is a string
of the format "[name=value,...]".
Image.new_from_enum(stream, "[shrink=2]")
Will read the stream with downsampling by a factor of two.
The full set of options available depend upon the image format. You can find all options available at the command-line. To see a summary of the available options for the JPEG loader:
$ vips jpegload_source
Opens path
for reading, returns an instance of Vix.Vips.Image.t/0
It can load files in many image formats, including VIPS, TIFF, PNG, JPEG, FITS, Matlab, OpenEXR, CSV, WebP, Radiance, RAW, PPM and others.
Load options may be appended to filename as "[name=value,...]". For example:
Image.new_from_file("fred.jpg[shrink=2]")
Will open "fred.jpg", downsampling by a factor of two.
The full set of options available depend upon the load operation that will be executed. Try something like:
$ vips jpegload
at the command-line to see a summary of the available options for the JPEG loader.
If you want more control over the loader, Use specific format loader
from Vix.Vips.Operation
. For example for jpeg use
Vix.Vips.Operation.jpegload/2
Loading is fast: only enough of the image is loaded to be able to fill out the header. Pixels will only be decompressed when they are needed.
Create a new image based on an existing image with each pixel set to value
Creates a new image with width, height, format, interpretation,
resolution and offset taken from the input image, but with each band
set from value
.
@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
@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
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")
Get "offset" of the image
More details
See libvips docs for more details regarding
offset
function
Get "orientation" of the image
More details
See libvips docs for more details regarding
orientation
function
Get "page-height" of the image
More details
See libvips docs for more details regarding
page_height
function
Get "scale" of the image
More details
See libvips docs for more details regarding
scale
function
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.
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)
@spec width(t()) :: pos_integer() | no_return()
Get "width" of the image
More details
See libvips docs for more details regarding
width
function
Returns raw pixel data of the image as binary term
Please check write_to_tensor
for more details. This function just
returns the data instead of the Vix.Tensor
struct.
Prefer using write_to_tensor
instead of this function. This is
only useful if you already know the details about the returned
binary blob. Such as height, width and bands.
Returns vips_image
as binary based on the format specified by suffix
.
This function is similar to write_to_file
but instead of writing
the output to the file, it returns it as a binary.
Currently only TIFF, JPEG and PNG formats are supported.
Save options may be encoded in the filename. For example:
Image.write_to_buffer(vips_image, ".jpg[Q=90]")
The full set of save options depend on the selected saver. You can get list of available options for the saver
$ vips jpegsave
Write vips_image
to a file.
A saver is selected based on image extension in path
. You can
get list of supported extensions by supported_saver_suffixes/0
.
Save options may be encoded in the filename. For example:
Image.write_to_file(vips_image, "fred.jpg[Q=90]")
The full set of save options depend on the selected saver.
You can check the supported options for a saver by checking
docs for the particular format save function in Operation
module.
For example, for you jpeg, Vix.Vips.Operation.jpegsave/2
.
If you want more control over the saver, Use specific format saver
from Vix.Vips.Operation
. For example for jpeg use
Vix.Vips.Operation.jpegsave/2
@spec write_to_stream(t(), String.t()) :: Enumerable.t()
Creates a Stream from Image.
Returns a Stream which will lazily pull data from passed image.
Useful when working with big images. Where you don't want to keep complete output image in memory.
{:ok, image} = Image.new_from_file("puppies.jpg")
:ok =
Image.write_to_stream(image, ".png")
|> Stream.into(File.stream!("puppies.png")) # or write to S3, web-request
|> Stream.run()
Second param suffix
determines the format of the output
stream. Save options may be appended to the suffix as
"[name=value,...]".
Image.write_to_stream(vips_image, ".jpg[Q=90]")
Options are specific to save operation. You can find out all available options for the save operation at command line. For example:
$ vips jpegsave_target
@spec write_to_tensor(t()) :: {:ok, Vix.Tensor.t()} | {:error, term()}
Returns raw pixel data of the image as Vix.Tensor
VIPS images are three-dimensional arrays, the dimensions being width, height and bands.
Each dimension can be up to 2 ** 31 pixels (or band elements). An image has a format, meaning the machine number type used to represent each value. VIPS supports 10 formats, from 8-bit unsigned integer up to 128-bit double complex.
In VIPS, images are uninterpreted arrays, meaning that from the point of view of most operations, they are just large collections of numbers. There's no difference between an RGBA (RGB with alpha) image and a CMYK image, for example, they are both just four-band images.
This function is intended to support interoperability of image data between different libraries. Since the array is created as a NIF resource it will be correctly garbage collected when the last reference falls out of scope.
Libvips might run all the operations to produce the pixel data depending on the caching mechanism and how image is built.
Endianness
Returned binary term will be in native endianness. By default
bitstring treats byte order as big
endian which might not be
native. Always use native
specifier to ensure. See Elixir
docs
for more details.
Get "xoffset" of the image
More details
See libvips docs for more details regarding
xoffset
function
Get "xres" of the image
More details
See libvips docs for more details regarding
xres
function
Get "yoffset" of the image
More details
See libvips docs for more details regarding
yoffset
function
Get "yres" of the image
More details
See libvips docs for more details regarding
yres
function