kip

kip

ex_cldr Core Team

Image is an image processing library for Elixir. It is based upon the fabulous vix library that provides a libvips wrapper for Elixir.

Image is intended to provide well-documented, performant and reliable common image processing functions in an idiomatic Elixir functional style. It operates at a layer above the very comprehensive set of functions in Vix and libvips.

In a very simple image resizing benchmark, Image is approximately 2 to 3 times faster than Mogrify and uses about 5 times less memory.

Since Image is based upon Vix and libvips it is performant, concurrent, pipelining and has a low memory footprint.

In this first release it focuses on resizing, cropping, masking, corner rounding, circular cropping, metadata extract, metadata minimisation. It also includes some simple functions to make it easy to resize and compress images for many well-known social media platforms at the correct size.

In the next two releases, Image will:

  • Provide streamed image processing. That will allow an image to be streamed from a file, or from S3 or from any Elixir stream or enumerable, process the image and then stream its output - including to chunked responses for HTTP applications.
  • Provide bi-directional Integration with Nx that will efficiently share memory buffers and make it even simpler to involve image processing in ML applications.

Simple examples

Resize to fit

Image.resize/3 Image.resize(image, 200, crop: :none)

Resize to fill

Image.resize/3 Image.resize(image, 200, crop: :attention)

Crop image

Image.crop/5 Image.crop!(image, 550, 320, 200, 200)

Rounded corners

Image.rounded/2 image |> Image.resize!(200, crop: :attention) |> Image.rounded!()

Avatar (circular mask, remove most metadata, crop to a subject of interest)

Image.avatar/3 Image.avatar(image, 200)

Showing Posts 1 to 10

webuhu

webuhu

Wonderful. :yellow_heart:
Mind to tag within the repository for the ex_doc source links and links on Hex.

kip

kip OP

ex_cldr Core Team

Whoops, sorry about that. Done!

jeroenvisser101

jeroenvisser101

Hey Kip, this is awesome! In addition to streaming, to ‘streamline’ the API, will you also add functions to load images from Memory, and will the S3-thing be a behaviour so other backends (such as GCS) can be added as well?

PS. Have you considered applying for GitHub Sponsors? I would love to sponsor you there as I use many (or even all) of your libraries, and would love to help even if in a small way! If you do, let me know :wink:

mayel

mayel

This looks great! I’ve been using imagemagick via Mogrify so far and while I’d like to use vips, I would prefer having the option to shell out rather than using the NIF when dealing with user-uploaded images (for the reasons you point out in your readme). Is this something you would consider adding to the library?

AndrewDryga

AndrewDryga

@kip does it support overlays (drawing an image on top of another one), transparency, and writing a text on an image?

Exadra37

Exadra37

Something like shown in the animation in the home page of:

kip

kip OP

ex_cldr Core Team

vix and libvips support everything you can think of, possibly even making you coffee in the morning. Text overlays are definitely on the list of features to expose. I’ve been working on what the right API should look like - feedback welcome. In the Vix readme there is an example of rendering a text overlay (see below).

# render text as image
# see https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text for more details
{:ok, {text, _}} = Operation.text(~s(<b>Vix</b> is <span foreground="red">awesome!</span>), dpi: 300, rgba: true)
# add text to an image
{:ok, img_with_text} = Operation.composite2(img, text, :VIPS_BLEND_MODE_OVER, x: 50, y: 20)

@mayel, I understand the concern, and this is of course a benefit of using mogrify. Nevertheless, shelling out doesn’t resolve the issue of maliciously crafted images, and there is a long history of CVEs. So while you avoid a crash in mogrify bringing down the BEAM, there are other issues. Its a tradeoff. Image, which depends on Vix, is firmly wedded to libvips as a NIF. I am going to try some experiments in running Image in its own BEAM node but that’s as far as it will go. I have to note that so far the stability has been excellent - only crashing when I made a poorly written addition to the NIF (which @akash-akya promptly fixed).

kip

kip OP

ex_cldr Core Team

@jeroenvisser101, the streaming API will do exactly what you want. @akash-akya has an experimental branch with the NIF implementation that basically means that image streaming can consume any Enumerable and as an output can produce an Enumerable.

This is fabulous for taking an S3 image, transforming it, and sending it as a chunked image in an HTTP request. There are many other use cases, but I think that one is high on the list of valuable capabilities.

Which is why it will be part of the Image 0.2 release in a week or so.

If you’re interested you can take a look at these tests in Vix.

kip

kip OP

ex_cldr Core Team

A couple of addition thoughts on the overall imaging pipeline strategy. What appeals to me about a library based upon libvips is that it is fast, has a small memory footprint and has really good concurrency support. These alone are for me enough to accept the potential issues with a NIF-based solution.

When you also have:

  • An architecture in libvips that is very friendly for a NIF implementation. This because only references are ever passed from Elixir-land to NIF-land so no large memory copies.
  • An internal streaming architecture in libvips that means transformation evaluation is only done at the point at which an image is rendered (either by writing to a file or sending to a client for example). Its very efficient.
  • Really strong support from @jcupitt, who is active, engaged and responsive
  • The ability to do all the transformation in memory, with streamed data

Then I think libvips with Vix is a really strong platform - as long as the concerns relevant to any NIF-based solution are recognised. Its analogous a little bit to Nx, the benefits outweigh the risks for a number of use cases.

AndrewDryga

AndrewDryga

We are processing a ton of images with internal service that works on top of graphicsmagick but we faced many issues with it (like it can corrupt its internal miff format during text-based transforms). We have a workaround for those but libvips is also an option so I was asking if the library supports that, so maybe we can run an experiment replacing gm with vix. We don’t need external services.

Where Next? Top

Trending in Announcing Top

wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
fuelen
Hi all! I want to present a small library which provides a mix task for generating an Entity-Relationship Diagram for Ecto schemas. You...
New
anuaralfetahe
Hello Published a new library - ProcessHub! ProcessHub is a library designed to manage process distribution within the Elixir cluster. ...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New
sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New
akoutmos
@hugobarauna, Dr. Dimitrios Koutmos (my brother) and I (Alex Koutmos) have been hard at work on writing a book on how you can use Elixir ...
New
pferriby
Introductory paragraph I’ll be looking for a keen junior or someone that has a couple of years experience in the real world (so you’ve be...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews