Creating Pinterest-Style Images

Image Compositing with imgix Animation

Note: New in our series of guest posts, HomeChef software engineer Kevin Lesht describes how he and his team use imgix to create multi-layered images for Pinterest using their existing content.


At Home Chef, a meal delivery service, we’re continuously working to feed our customers not only with great food, but also great content. Each week our menus feature 10 or more meals, and we put a lot of thought into making them great. Our customers appreciate this, and it’s not uncommon for them to share these recipes on social media.

With each recipe featuring high-quality photographs, one social network in particular fits our Home Chef meals especially well—Pinterest. Pinterest maintains a space for users to share image-based content, and Food and Drink occupies one of the largest categories on the site, so it’s the perfect place to highlight Home Chef’s recipes.

As we explored Pinterest, we found that our customers were actively sharing Home Chef recipes on the platform, but there was an immediate problem. The way things were implemented, users were only able to share the final, plated image that we include with each recipe. There was a lot left out—including the fresh ingredients we provide to make those dishes a reality. As a company, we knew we could do better. So we put together a team to figure out a better solution.


Designing the Image

Entering the design phase of the project, members of the Home Chef marketing and design team worked through a collaborative whiteboard session to produce a new and exciting concept for our customers. The result was a design where each recipe’s plated image would be stacked on top of its ingredient images. This would allow users to share an image that provided more insight into the recipe. The design also harmonized well with Pinterest’s focus on more vertically oriented images.

With that, it was on to planning how to realize this vision. Almost immediately, there was a challenge.

The plan was to attach one of these shareable images to each meal in Home Chef’s ever-expanding catalog of recipes, but doing so would be an immense and ongoing engagement. We needed a way to programmatically create these images. Our attention turned to imgix.

We were already using imgix to serve images, so we had the technology in place to create composite images with its suite of parameters. With a solid footing on the direction for our image, and the extensive documentation on parameters provided by imgix, it was time to enter development and test our design.


The First Iteration—Moving into the Sandbox

We’d recently read an imgix blog post that tackled a problem similar to what we were developing, so it was easy to use that as a framework to guide our own implementation. We were able to move quickly into the imgix sandbox to begin prototyping our design.

  • First, we knew that we would need to draw a canvas that could maintain both the plated and ingredient image stacked one on top of the other. To accomplish this, we started by creating a 1×1-pixel transparent GIF, and opened up an imgix tag on it.

  • Next, we passed this imgix tag a width parameter that matched our images’ width, and a height parameter that we set equal to that of the two images stacked on top of each other vertically. Applying these parameters on the 1×1-pixel transparent GIF effectively created an artboard, sized to the content for our composition and ready to accept the images.

To place our image assets onto the canvas and into their appropriate spot, we turned towards manipulating the mark and blend parameters. These properties accept an image, width, height, and positioning attributes, so by passing in an image and explicitly setting the width and height to match the asset dimensions, the image occupies the full range of its place on the canvas.

  • Following this pattern, we set the watermark parameter to the recipe’s plated image, with a position of top, left, and a width and height that matched the asset’s dimensions. This placed the first visual onto the canvas.

  • For the ingredient image, we set this asset as the blend parameter with a position of bottom, left, and a width and height that matched the asset’s dimensions. We also set the blend mode to bm=normal so that it behaves like a watermark.

With the recipe’s plated and ingredient images in place, we had successfully captured the project’s objective!

def pinterest_meal_image
  $imgix_social_client.path("images/s.gif").to_url(
    w: 600,
    h: 805,
    fit: "crop",
    mark: "images/plated_image.jpg",
    markw: 600,
    markh: 400,
    markx: 0,
    marky: 0,
    markfit: "crop",
    blend: "images/ingredient_image.jpg",
    bw: 600,
    bh: 400,
    ba: "bottom,left",
    bm: "normal",
    bf: "crop").html_safe
end

The Second Iteration—How Far Can We Go?

Having achieved our initial concept for a stacked Pinterest-style image, the team became curious as to how far we could expand on the design. We wondered if it would be possible to introduce an entirely new middle frame in between the plated and ingredient images. The idea was that we could use this section to provide even more context for the recipe. We decided it would feature a background with the Home Chef logo and title of the meal overlaid. Back to the sandbox.

  • We began by following the same approach as our earlier iteration, and opened an imgix tag on a 1×1-pixel transparent GIF to create a base canvas.

  • Again, we passed this imgix tag a width parameter that matched our images’ width, but this time when defining the height, we added an additional allotment to accommodate the new middle frame. That accomplished, it was easy to use the mark and blend parameters to lay the new interior elements in with the ingredient and plated images.

    • First, we expanded on the usage of the mark parameter from the prior iteration to now maintain a “child” canvas. To form this element, we followed the same practice used to draw the base canvas, and opened an imgix URL on a 1×1-pixel transparent GIF. This effectively created a new imgix image, and a fresh set of parameters specific to the instance.

    • Taking advantage of this nested canvas, a height was defined to support the meal’s plated photo, as well as the new middle frame.

    • The mark parameter was then set to represent the given meal’s plated photo, and styled in the same fashion as was done in the first iteration.

Following the mark, the blend parameter was also expanded to maintain the middle frame through the creation of a new “grand-child” level canvas.

  • To develop this layer, we again followed the same practice of passing in an imgix URL to create a new instance of parameters, and this time drew the canvas with an image of wood paneling to setup the frame’s background.

  • Within this area, the Home Chef logo was passed in as the mark, and overlaid in the center of the pane.

  • Following the logo display, imgix text parameters were configured to style and position the meal title, and close out the open “grand-child” and “child” level canvases.

From this, we returned to the base canvas level.

  • Finishing off the composition, we supplied the meal’s ingredient photo as the blend parameter, with the same positioning attributes of bottom, left captured from the first iteration.

Putting it all together, we’re able to pass in a Home Chef recipe to our method for a dynamically generated image, brand-aligned, and perfectly suited to the Pinterest style.

def pinterest_meal_image
  $imgix_social_client.path("images/s.gif").to_url(
    w: 600,
    h: 1100,
    fit: "crop",
    mark64: $imgix_social_client.path("images/s.gif").to_url(
      w: 600,
      h: 700,
      fit: "crop",
      mark64: "images/plated_image.jpg",
      markw: 600,
      markh: 400,
      markx: 0,
      marky: 0,
      markfit: "crop",
      blend64: $imgix_social_client.path("images/wood_bg.jpg").to_url(
        w: 600,
        h: 300,
        fit: "crop",
        mark64: $imgix_social_client.path("images/homechef_logo.png").to_url,
        markw: 150,
        markh: 110,
        marky: 60,
        markalign: "center",
        markfit: "crop",
        txt64: "Backyard Seafood Boil",
        txtclr: "fff",
        txtsize: 28,
        txtpad: 60,
        txtfont64: "serif,bold",
        txtalign: "center"),
      bw: 600,
      bh: 300,
      ba: "bottom,left",
      bm: "normal",
      bf: "crop"),
    markw: 600,
    markh: 300,
    markx: 0,
    marky: 0,
    markfit: "crop",
    blend64: "images/ingredient_image.jpg",
    bw: 600,
    bh: 400,
    ba: "bottom,left",
    bm: "normal",
    bf: "crop").html_safe
end

Results

Setting out on this project, we wanted to provide our customers with an exciting piece of content for each Home Chef recipe, catered towards sharing on the Pinterest platform. Thanks to imgix, we were not only able to capture our vision for the design, but also do so in a programmatic and sustainable fashion.

Following the launch of this new feature, our team has observed as these Pins gain momentum and spread across the Pinterest platform. Pinterest users are a highly engaged audience, and providing quality, brand-aligned content been a catalyst towards promoting our presence and recognition on the network. We’re very excited with what we’ve been able to achieve, and look forward to continued experiments with imgix to further expand on the content that we’re able to provide to our customers.