Overlap an image over a QR code using Mogrify

Written by Atul Bhosale on January 2, 2020; tagged under elixir

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.

qr_code

If you have any questions or feedback, feel free to drop us a mail at team@codemancers.com.