Resizing Images In Elixir with Mogrify
— 2 min read
I've been working on a simple Elixir and Phoenix web app that extracts text found in images and I ran into a problem, people were uploading large images. I only needed images that were around 1200x1200 pixels.
I did some Googling around and I stumbled across Mogrify, a simple Elixir library to process images. Under the hood it uses ImageMagick, a commandline tool for displaying, converting, and editing raster image and vector image files.
Using Mogrify
Mogrify is simple and easy to use and the only requirement is to have ImageMagick installed on your computer. See installation instructions for more info.
-
Add
{:mogrify, "~> 0.5.6"}
to yourmix.exs
file and runmix deps.get
. -
Import it on the module you intend to use it on. Here's how my module looks like:
defmodule ImgToTxt.Utils.Image doimport Mogrify@doc """Resize images given imagePath, width, height, and optional Mogrify opts"""def resize(imagePath, width, height, opts \\ []) do# Continue readingendend -
To resize images you first
open
the file by give it the path to the image. When callingopen
, it should return something like:iex(3)> Mogrify.open("test/assets/test.png")%Mogrify.Image{animated: false,dirty: %{},ext: ".png",format: nil,frame_count: 1,height: nil,operations: [],slug: "img_to_txt/test/assets/test.png",width: nil}Now, let's add that to our function
def resize(imagePath, width, height, opts \\ []) doopen(imagePath)end -
Now that we have our file opened, let's resize it. Mogrify provides the following functions to resize images:
resize
,resize_to_fill
, andresize_to_limit
. I choose theresize_to_limit
because it will resize the image to fit within the specified dimensions while retaining the original aspect ratio. It will also only resize the image if it is larger than the specified dimensions. Let's add that to our function:def resize(imagePath, width, height, opts \\ []) doopen(imagePath)|> resize_to_limit(~s(#{width}x#{height}))end -
The last thing is to save our resized image by using the
save
function. Mogrify will save the image on a temporary file. You can change that by passing in thepath
as an option. See docs for more info. Lets add that to our function:def resize(imagePath, width, height, opts \\ []) doopen(imagePath)|> resize_to_limit(~s(#{width}x#{height}))|> save(opts)end
We are done, I hope this was helpful and feel free to comment.