Yes, it’s the most Easterful time of the year again. For some of us a sacred time, for others mainly an egg-eating period and some just enjoy the extra day of spare time. In case you have some time available for some good egg searching business, but no-one seems willing to hide them for you this year, here’s an alteRnative. Hide them yourself using R and have a nice easteR holiday! As you go, you also get to know the very nice image processing package: magick.

Let’s start by collecting some images where we can hide our eggs.

easterScenes <- c(
    'https://www.godupdates.com/wp-content/uploads/2018/03/Easter_LastSupper_GU2018.jpg',
    'https://image.cnbcfm.com/api/v1/image/105764024-1551270113306gettyimages-1127697101.jpeg',
    'https://images.pexels.com/photos/33152/european-rabbits-bunnies-grass-wildlife.jpg'
    )

library(magick)

# read images and put in a vector
images = c(image_read(easterScenes))
#show all images, next to eachother
image_append(image_scale(images, "x200"))

And we – obviously – also need some eggs.

easterEggs <- c(
    'https://cdn.pixabay.com/photo/2017/02/04/20/28/easter-2038263_960_720.png',
    'https://cdn.pixabay.com/photo/2016/12/15/11/41/easter-1908690_960_720.png',
    'https://cdn.pixabay.com/photo/2017/03/28/09/56/easter-egg-2181493_960_720.png',
    'https://cdn.pixabay.com/photo/2019/01/29/13/49/egg-3962420_960_720.png',
    'https://cdn.pixabay.com/photo/2018/02/25/09/44/easter-3180067_960_720.png'
)

# read images and put in a vector
images = c(image_trim(image_read(easterEggs)))
#show all images, next to eachother
image_append(image_scale(images,"x100"))

Excellent, we have some scenes and some eggs, let’s create a function to make hiding our eggs easy. We’ll take advantage of some other functions from the great image processing package magick.

library(magick)
library(dplyr)

hideEggs <- function(sceneUrl,nEggs=nEggs,eggPositions,eggSize=0.04){
    # read scene
    easterScene <- image_read(sceneUrl)
    # resize picture to 800 width (keep aspect ratio)
    easterScene <- image_scale(easterScene, "800x")
    sceneWidth <- as.numeric(image_info(easterScene)['width'])
    sceneHeight <- as.numeric(image_info(easterScene)['height'])
    # collect some eggs (sample with replacement in the basket ;))
    nEggs = nEggs
    eggUrls = sample(easterEggs,nEggs,replace = TRUE)

    easterSceneEggs <- easterScene

    for (eggn in 1:nEggs){
        eggUrl = eggUrls[eggn]
        # get egg, resize, rotate and put on canvas!
        egg <- image_read(eggUrl)
        # resize egg to 5% of canvas height (keep aspect ratio)
        egg <- image_scale(egg,paste0("x",round(eggSize*sceneWidth)))
        # remove background
        egg <- image_background(egg,"none")
        # rotate egg between -90 and 90 degrees
        eggRotation <- runif(1,-90,90)
        egg <- image_rotate(egg,eggRotation)
        #set x and y position (as specified in list or else random)
        if (!missing(eggPositions)){
            xpos <- eggPositions[[eggn]][1]*sceneWidth
        } else {
            xpos <- runif(1,0,sceneWidth)
        }
        if (!missing(eggPositions)){
            ypos <- eggPositions[[eggn]][2]*sceneHeight
        } else {
            ypos <- runif(1,0,sceneHeight)
        }
        #add egg to canvas
        easterSceneEggs <- image_composite(easterSceneEggs, egg, offset = paste0("+",xpos,"+",ypos))
    }
    return(easterSceneEggs)
}

Yeah, we’ve hidden 5 eggs near these happy easter bunnies. Can you spot them in a few seconds??

# let's hide 5 eggs among our easter bunnies
hideEggs(sceneUrl = easterScenes[2],nEggs = 5)

These guys also seem to enjoy our little game. Finally, let’s make a somewhat more challenging version, you can share it with your relatives, wishing them a nice easter holiday.

# think where to hide...
eggPositions = list(c(0.1,0.95),c(0.03,0.6),c(0.4,0.65),c(0.5,0.67),c(0.465,0.31),
                    c(0.6,0.4),c(0.7,0.7),c(0.6,0.66),c(0.8,0.94),c(0.97,0.71))

#... and hide! we'll use smaller eggs to make it a bit more challenging.
easterCard <- hideEggs(sceneUrl = easterScenes[1],nEggs = length(eggPositions),
         eggPositions = eggPositions,
         eggSize = 0.02)

# let's add some wishes to our easter card...

easterCard %>% 
    image_annotate("Happy Easter!!!", size = 36, color = "yellow",  location = "+270+16") %>%
    image_annotate("Can you spot the 10 hidden eggs?", size = 18, color = "white",  location = "+250+60")

In case your audience can’t figure out where you hid the eggs, magick lets you animate your pictures.

# specify easterScene with and without the eggs and specify number of frames
frames <- image_morph(c(easterCard, image_scale(image_read(easterScenes[1]),"800x")), frames = 10)
image_animate(frames)

For much more you can do with magick, see the vignette.

That’s it, have yourself a merry little easter egg!

This article was first published on GitHub.

this article is written by

Jurriaan Nagelkerke
j.nagelkerke@cmotions.nl