Generating Open Graph social media images

A Ruby Open Graph image generator using Tinify and RMagick

I wrote an Open Graph social media image generator a few years ago in Ruby which has proven itself to be useful time and time again so I thought some other folk might find it useful! I’ll not go into too much explanation into how it works (I wrote it a few years ago and it confused me even then a bit!).

Heads up: you will need a TinyPNG key for this to work.

I created a Ruby project consisting of the following files/folders:

img/                           # this directory holds image templates
.gitignore                     # ignores .env
.env                           # ignored in .gitignore
Gemfile                        # holds Gems
tosbourn_image_generator.rb    # the file which the Ruby script lives in

First off our img directory, for us this holds some image templates or backgrounds for our social media sharing images. This image should be 1024 × 512 pixels. This is an example of one of our images:

Open Graph background image

We then use the Ruby script detailed below to superimpose text on the top of the image.

We add our .env file to the .gitignore file.

In the .env file we have our TinyPNG key which we call from the Ruby script.

The Gemfile contains the following:

source "https://rubygems.org"

ruby "2.4.1"

gem "rmagick"
gem "dotenv"
gem "tinify"

You will need Imagemagick for rmagick: brew install imagemagick

So onto the fun stuff, the image manipulation!

require 'RMagick'
require 'dotenv/load'
require 'tinify'
include Magick

def word_wrap(line)
  return line if line.length <= 26
  line.gsub(/(.{1,26})(\s+|$)/, "\\1\n").strip
end

def og_create(my_text)
  background_image = Dir.glob('img/*').sample
  image = Magick::Image.read(background_image).first

  create = Magick::Draw.new
  position = 0

  create.annotate(image, 0, 0, 3, 0, word_wrap(my_text)) do
    self.font = 'ArialUnicode'
    self.pointsize = 75
    self.font_weight = BoldWeight
    self.fill = 'white'
    self.gravity = CenterGravity
  end

  file_name = my_text.dup
  file_name.downcase!
  file_name.strip!
  file_name.gsub!(/[^a-z0-9\s-]/, '') # Remove non-word characters
  file_name.gsub!(/\s+/, '-')         # Convert whitespaces to dashes
  file_name.gsub!(/-\z/, '')          # Remove trailing dashes
  file_name.gsub!(/-+/, '-')          # get rid of double-dashes
  image.write("../tosbourn.com/img/#{file_name}.png")

  Tinify.key = ENV['TINYPNG_KEY']
  Tinify.from_file("../tosbourn.com/img/#{file_name}.png").to_file("../tosbourn.com/img/#{file_name}.png")
end

og_create(ARGV[0])

The word_wrap method stops text overflowing past the ends of the image.

The og_create method takes a random image from our img directory, sets the font, size, gravity and colour. It then uses Tinify to write the image to a directory on my machine (the repo for this websites codebase).

To call this script, all I have to do is be in the project in my terminal and type ruby tosbourn_image_generator.rb "The name of my article" and it will create an Open Graph image for any article I’m writing. I just pop the reference to this in the front matter for my article, which I then use to populate the meta data of the article page.

This is the result of using the above script:

Example of Open Graph script result


Recent posts View all

Ruby

Forcing a Rails database column to be not null

How you can force a table column to always have something in it with Rails

Writing Marketing

We've deleted an article's worth of unhelpful words

We've improved several pages across our site by removing words that add no value, and often detract from the article.