Recently, I was working on writing a QR code generator using Elixir for one of our clients. There was a requirement to have a logo above the QRCode and it should be in the center, to identify which company's QR code is being scanned. This post is about what I learned about using Mogrify Elixir library to achieve this.
First we need to generate a QR code and store it in a image file.
svgfilepath = Temp.path!(%{suffix: ".svg"})
Poison.encode!(%{data: "Hello world"})
|> QRCode.create(:high)
|> Result.and_then(&QRCode.Svg.save_as(&1, svgfilepath))
I have used the temp library to create a temporary file & qr_code library to generate the QR code. Since I need to generate the QR code out of an elixir map I have used the poison library to encode it to json string.
Using Result.and_then()
method, provided by qr_code
library we can store the QR code in a .svg
file.
To overlap an image over another image we need another elixir library. I came across Mogrify for this. Mogrify uses ImageMagick for image manipulation.
You can install ImageMagick by following the instructions from the official page.
After ImageMagick is installed, we can use Mogrify to overlap the logo over the QR code image.
Going through ImageMagick docs I found that I need to use the
composite
command provided by the library to overlap an image over another.
After going through the Mogrify readme I didn't find any
method which uses the composite
command of Imagemagick. I checked the open issues
on the library. I came across this
issue which points to another
issue mentioned to use image_operator
method since
the library doesn't support the composite
command.
I followed this comment and ImageMagick composite command docs to overlap an image over another.
logo_png = File.cwd!() <> "/logo.png"
pngfilepath = Temp.path!(%{suffix: ".png"})
Mogrify.open(svgfilepath)
|> Mogrify.format("png")
|> Mogrify.save(path: pngfilepath)
File.rm!(svgfilepath)
conversion_command_string = "convert #{pngfilepath} #{logo_png}\
-gravity center -composite -size 500x500"
Mogrify.open(svgfilepath)
|> Mogrify.image_operator(conversion_command_string)
|> Mogrify.create(inplace: true)
After the svg
image is converted to png
format, we can delete the file
using File.rm!()
.
I was able to overlap the logo image on top of the QR code by converting the
svg
QR code image to png
and then overlapping it with the logo image.
Following is the screenshot when the QR code is successfully scanned.