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(


# 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(

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

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.


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))

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),

#... 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)

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