More Haskell Diagrams: OpenGraph Images
Table of contents
In this blog post, we are continuing to play with Haskell's diagrams library. We will write a literate Haskell program to generate an OpenGraph image.
Motivation
I am told that my Website pages should have OpenGraph images. So, I stopped worrying about not worrying about content, and I started worrying about not having an OpenGraph image.
So, let's do one.
Program
We will use the 3 Haskell packages for this Literate Haskell program like before: diagrams, diagrams-cairo and markdown-unlit.
Let's import a few modules.
import Diagrams.Backend.Cairo
import Diagrams.Prelude
import System.Environment (getArgs)
Now, our entry point what will render an OpenGraph image with size 1200x630
and extension .png
:
main :: IO ()
main = do
dir <- head <$> getArgs
logo <- loadLogo
render dir "og.png" (og "thenegation.com" "by Vehbi Sinan Tunalioglu" logo)
where
render dpath fname = renderCairo (dpath <> "/" <> fname) (mkSizeSpec2D (Just 1200) (Just 630))
This is how we will run our blog post:
runhaskell \
-pgmLmarkdown-unlit \
content/posts/2024-08-12_haskell-diagrams-og.lhs \
static/assets/media/posts/haskell-diagrams-og
Let's load my Website's logo image inside a Diagram B
value. We are scaling the diagram to 24
:
loadLogo :: IO (Diagram B)
loadLogo = do
(Right img) <- loadImageEmb "./static/android-chrome-512x512.png"
pure $ scaleUToX 24 $ image img
Let's create a function to clip a given image in a circle. We will use the clipBy
function to achieve this. Since our square image is scaled to 24
, We are using a circle with a radius of 12
:
mkAvatar :: Diagram B -> Diagram B
mkAvatar =
clipBy (circle 12)
Let's put some large text and then some smaller text under the avatar image to compose our OpenGraph image. Note that we use a canvas of 120x63
, which is proportional to the OpenGraph image size of 1200x630
and play with arbitrary colours:
og :: String -> String -> Diagram B -> Diagram B
og txtB txtS img =
logotype `atop` (rect 120 63 # fc (sRGB24read "#e4e4e7") # lw none)
where
logotype =
center $ vsep 9
[ mkAvatar img
, text txtB # bold # fontSizeL 6 # fc (sRGB24read "#09090b")
, text txtS # fontSizeL 4.27 # fc (sRGB24read "#18181b")
]
That's all! Let's see how PNG image looks like:
Wrap-Up
We have created an OpenGraph image for my Website. The next challange will be to add my blog post title and description to the image dynamically. I am not sure how to do that yet, especially with flowing text.
Subscribe to my newsletter
Read articles from Vehbi Sinan Tunalioglu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vehbi Sinan Tunalioglu
Vehbi Sinan Tunalioglu
My name is Sinan. I am a computer programmer and a life-style entrepreneur. You can check my LinkedIn and GitHub profile pages for more information, and send an email to vst@vsthost.com to contact me. I am re-publishing my technical blog posts on hashnode. My website is available on thenegation.com, and its source code is available on GitHub.