Blazing fast image processing for Elixir powered by libvips, the same engine that powers sharp.js.
- Building image processing APIs and services
- Generating thumbnails at scale
- Image manipulation in web applications
- Computer vision preprocessing
- Processing large scientific/satellite images
- High Performance: Uses libvips' demand-driven, horizontally threaded architecture
- Memory Efficient: Processes images in chunks, perfect for large files
- Streaming Support: Read/write images without loading them fully into memory
- Rich Ecosystem: Zero-copy integration with Nx and eVision
- Zero Setup: Pre-built binaries for MacOS and Linux platforms included.
- Auto-updating API: New libvips features automatically available
- Comprehensive Documentation: Type specifications and documentation for 300+ operations
Mix.install([
{:vix, "~> 0.23"}
])
alias Vix.Vips.{Image, Operation}
# Create a thumbnail and optimize for web
{:ok, thumb} = Operation.thumbnail("profile.jpg", 300)
:ok = Image.write_to_file(thumb, "thumbnail.jpg", Q: 90, strip: true, interlace: true)
# Reading an image
{:ok, img} = Image.new_from_file("profile.jpg")
# Resize preserving aspect ratio
{:ok, resized} = Operation.resize(img, 0.5) # 50% of original size
# Crop a section
{:ok, cropped} = Operation.crop(img, 100, 100, 500, 500)
# Rotate with white background
{:ok, rotated} = Operation.rotate(img, 90, background: [255, 255, 255])
# Smart thumbnail (preserves important features)
{:ok, thumb} = Operation.thumbnail("large.jpg", 300, size: :VIPS_SIZE_DOWN, crop: :VIPS_INTERESTING_ATTENTION)
# Convert to WebP with quality optimization
:ok = Image.write_to_file(img, "output.webp", Q: 80, effort: 4)
# Create progressive JPEG with metadata stripped
:ok = Image.write_to_file(img, "output.jpg", interlace: true, strip: true, Q: 85)
# Generate multiple formats
:ok = Image.write_to_file(img, "photo.avif", Q: 60)
:ok = Image.write_to_file(img, "photo.webp", Q: 80)
:ok = Image.write_to_file(img, "photo.jpg", Q: 85)
# Blur
{:ok, blurred} = Operation.gaussblur(img, 3.0)
# Sharpen
{:ok, sharp} = Operation.sharpen(img, sigma: 1.0)
# Grayscale
{:ok, bw} = Operation.colourspace(img, :VIPS_INTERPRETATION_B_W)
# Smart thumbnail preserving important features
{:ok, thumb} = Operation.thumbnail(
"large.jpg",
300,
size: :VIPS_SIZE_DOWN, # only downsize, it will just copy if asked to upsize
crop: :VIPS_INTERESTING_ATTENTION
)
# Process image stream on the fly
{:ok, image} =
File.stream!("large_photo.jpg", [], 65_536)
|> Image.new_from_enum()
# use `image` for further operations...
# Stream image to S3
:ok =
Image.write_to_stream(image, ".png")
|> Stream.each(&upload_chunk_to_s3/1)
|> Stream.run()
Libvips very fast and uses very little memory. See the detailed benchmark. Resizing an image is typically 4x-5x faster than using the quickest ImageMagick settings. It can also work with very large images without completely loading them to the memory.
Add Vix to your dependencies:
def deps do
[
{:vix, "~> x.x.x"}
]
end
That's it! Vix includes pre-built binaries for MacOS & Linux.
Want to use your system's libvips? Set before compilation:
export VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS
See libvips installation guide for more details.
- Complete API Documentation
- Interactive Introduction (Livebook)
- Creating Rainbow Effects (Livebook)
- Auto Document Rotation (Livebook)
- Picture Language from SICP (Livebook)
Image is a library which builds on top of Vix.
-
Use Image when you need:
- A more Elixir-friendly API for common operations
- Higher-level operations like Blurhash
- Simple, chainable functions for common operations
-
Use Vix directly when you need:
- Advanced VIPS features and fine-grained control
- Complex image processing pipelines
- Direct libvips performance and capabilities
- Lesser dependencies
Out of the box: JPEG, PNG, WEBP, TIFF, SVG, HEIF, GIF, and more. Need others? Just install libvips with the required libraries!
MIT License - see LICENSE for details.