Since Jake Wharton’s post on the Thumbor thumbnail server, there has been some buzz about how Thumbor applies to mobile. Serving thumbnails using a minimal amount of front-end space is actually more crucial for mobile apps than for web-apps for a lot of reasons; most of these just have to do with the simple scarcity of network bandwidth to mobile devices.
We have worked with this scarcity before and for most of our projects, we used a home-baked image server built with nodejs and imagemagick. Of course, we also used Amazon’s Cloundfront to do more of the heavy duty caching and serving. Scaling this server has always been a pain, and since Threadless‘ TypeTees app had some interesting thumbnail requirements, it was definitely an opportunity to try using Thumbor to tackle this problem. We came out on the other end with a great experience and a surefire way to continue doing thumbnails for Prolific’s mobile products to come.
Background on TypeTees
TypeTees is a mobile app that lets you create your own t-shirt designs quickly and order them from the printer immediately. Prolific Interactive built TypeTees in partnership with Threadless, who knows t-shirts inside and out (pun intended?), to really make the experience fun. Read more about it and download it here.
Image Workflow & Architecture for TypeTees
- We used our quick RESTful API Generator MABI written in PHP to do the API endpoints. When a user creates a Tee with the mobile app, the print mask for the Tee is sent to the API server.
- The API server saves the mask to an S3 bucket and a reference its URL in the database
- When the mobile app requests a thumbnail URL (e.g. listing featured tees or viewing a user’s own tees), we use the S3 URL, the Cloudfront Host, and 99design’s Phumbor Library to generate secure Thumbor URLs to the app.
- The mobile app can now request the Thumbnail image data directly from Cloudfront, which serves the data from a nearby edge server if the same exact URL has been requested before.
- If the URL has not been requested/cached, Cloudfront passes the request through Thumbor to generate the thumbnail. Thumbor uses S3 as its backing store to create the thumbnails from the print image (see next section).
If you need help setting up 4 and 5, this post should have everything you need: How Yipit Scales Thumbnailing With Thumbor and Cloudfront. It shows how to easily use nginx to set up an internal load balancer for Thumbor.
Why TypeTees Thumbnails are Problematic
The issue with TypeTees Thumbnails is really their source. We generate thumbnails directly from the print image we’re using for the t-shirt manufacturer. The diagram below shows the issue.
You can see here that the TypeTees print image is transparent, large (so your shirts don’t look like crap), and always on the same part of the shirt. The thumbnail centers and enlarges the content so it’s more easily recognizable. The coolest part of using Thumbor for this project was that we could do this whole implementation via its URL system on the fly and just let Cloudfront do the caching. This is how it’s done…
Cool Tricks Using Thumbor URLs
We used the URL builder Phumbor by 99designs to generate signed URLs with all of the filters needed. Here is the breakdown of the functionalities we used:
- To initialize the Phumbor URL builder we use:
1ThumborUrlBuilder::construct($thumborServer, $thumborSecret, $sourceImageURL)
Where $thumborServer is the URL of the server. In our case, we use the Cloudfront URL which proxies to the Thumbor Server. $thumborSecret is used to sign the URL, and $sourceImageURL is used in our case to point to the print image on S3.
- Next we add:
This trims the print image based on its bounding box.
- The next step is:
which scales the image until it fits into the $width and $height, which is the size of the thumbnail we want. This results in:
- Now, we can fill the thumbnail with the color of the t-shirt that it will be printed on using:
1->addFilter('fill', $color, true)
The ‘true’ fills is required if the source image was transparent. The result is:
- The last filter is a custom one that we are working on contributing to Thumbor. There is a core ‘frame’ filter that would do a similar job, but it has some extra functionality of putting a PNG frame around your thumbnail, but we just needed the padding. The builder command for this is:
1->addFilter('pad', $t, $r, $b, $l, $color)
where $t, $r, $b, and $l are the padding numbers that follow a similar pattern as padding in CSS and results in:
- Finally, the
->build();function returns a URL like:
The entire Phumbor statement is:
ThumborUrlBuilder::construct($thumborServer, $thumborSecret, $sourceImageURL)
->addFilter('fill', $color, true)
->addFilter('pad', $t, $r, $b, $l, $color)
I hope this helps you get your mobile apps acting snappier and using less bandwidth! Feel free to let us know if you have any questions about this implementation.