Elixir Phoenix models with images part#2

This article is second part of Elixir Phoenix models with images. Last time I described how we can save and manage our images. Today we want to get and cache resized copies for our images.

Resize image

First of all let’s find some tool that can resize images for us. I checked awesome elixir packages but didn’t find some great tool to get thumbs. Although I found mogrify lib that can help us a lot. This is a wrapper for image magic mogrify CLI tool. And actually this is what we need to build our own helper that can get a thumbs for our images.

Add {:mogrify, “~> 0.4.0”} to your deps. And add this simple helper.

If we will need some more functionality we will extend it but so far this is all I need.

Image mime and size

Last time we learned how to save image from URL. We also want to save uploaded image. This is quite simple (File.copy {uploaded image file}). But we also want to get image mime and size. In order to to this I added another helper that can do this. To get file size we can use File.stat function. But there’s no built in tools in elixir to get mime – but we can use file linux tool to get file info. Here’s what I eventually got.

Updates to image model

Last time we’ve added parent_id column to image model. We did it in advance by providing the ability to add resized copies for original images. So my idea is simple in order to get resized image with width = 500 and height 300 I execute a query

SELECT * FROM image where parent_id = {origina image ID} and width = 500 and height = 300

Let’s see what we need to change.

We resize image with Image helper and save it with defined parent_id. Simple 🙂

Now let’s add some functionality to our model helper that we can reuse in our various models. We want to add a method that will save uploaded image.

check out save_uploaded_image. We define image type by module name App.Module1.Module2.CompanyCatalog => company_catalog. Then we save image Image.create_from_file and assigned received image.id to our model. Now in our controller we can add following code to save user avatar.

user = if user_params["avatar"] do
  User.save_uploaded_image(user, user_params["avatar"], :avatar_id)
else
  user
end

Final step

Finally we want to add view helper that will be a wrapper around HasImageHelper.get_image_url.

Now we can use this helper in our view classes use App.Helpers.ViewHelpers and then in our template we can easily get resized image
<img src="<%= image_url(@user, :avatar_id, width: 250, height: 250)%>" />

If you have any questions our suggestions – please comment.

Leave a Reply

Your email address will not be published. Required fields are marked *