Building the oomsifyer

[This article was first published on Clean Code, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Today I will show you a quick hack (OK it took me like 4 hours during my travels today yesterday and today),
on how to add a dancing banana to any picture.

Now, you might be thinking… Really, why would you add a dancing banana to
a picture, but I don’t have time for that kind of negativity in my life.

Why oomsifier?

Jeroen Ooms is one of those crazy productive people in the R world. The way he
wraps c++ libraries into packages makes you think his middle name is c-plus-plus.

At the Sat-R-day in budapest in 2016 (?) Jeroen demonstrated the magick library.
You can now control images from inside R using dark magic and the bindings to
the magick library. In honor of this work and because I needed a cool name,
I will demonstrate THE OOMSIFYER.

Solving the life long dream of people all around the world … of adding dancing banana gifs to pictures…

If you are like me, you would have thought this would be really easy, but you would be wrong.

First the function then the explanation and some stuff that took me waaay too long
to find out.

The function

banana <- image_read("images/banana.gif") # this assumes you have a project with the folder /images/ inside.

add_banana <- function(image, offset = NULL, debug = FALSE){
    image_in <- magick::image_read(image)
    banana <- image_read("images/banana.gif") # 365w 360 h
    image_info <- image_info(image_in)
    if("gif" %in% image_info$format ){stop("gifs are to difficult for  me now")}
    # scale banana to correct size:
    # take smallest dimension.
    target_height <- min(image_info$width, image_info$height)
    # scale banana to 1/3 of the size
    scaling <-  (target_height /3)
    front <- image_scale(banana, scaling)
    # place in lower right corner
    # offset is width and hieight minus dimensions picutre?
    scaled_dims <- image_info(front)
    x_c <- image_info$width - scaled_dims$width
    y_c <- image_info$height - scaled_dims$height
    offset_value <- ifelse(is.null(offset), paste0("+",x_c,"+",y_c), offset)
    if(debug) print(offset_value)
    frames <- lapply(as.list(front), function(x) image_composite(image_in, x, offset = offset_value))

    result <- image_animate(image_join(frames), fps = 10)

So what can it do?

This function takes an image, f.i. a ggplot2 image that you saved to disk, and adds the dancing banana gif to the bottom right corner.

ggplot with banana example

I had to combine information from the magick vignette and an earlier blogpost about magick in R.

Things I learned:

  • the magick package returns image information as a data frame
  • a gif is a succesion of images (frames)
  • a normal picture is a single frame
  • to combine a gif and a single frame you have to have exactly as much frames of your original picture as the number of frames in the gif
  • for every frame you have to merge the gif and image with each other into a composite image
  • the offset is the number of pixels from the left of the frame and from the top of the frame. I wanted to put the dancing banana at the bottom right of the picture AND I wanted to scale the banana so that it would take over the entire image so the offset needed to be responsive to both scaling and the input dimensions
  • the practical dev has many silly o-reilly like book covers that I find hilarious

spss picture

In a the following posts I might turn this function into an API, stay tuned!

Building the oomsifyer was originally published by at Clean Code on November 28, 2017.

To leave a comment for the author, please follow the link and comment on their blog: Clean Code. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)