Algorithmia Blog

Smart Autogeneration of Thumbnails Banners, and Socials with Content Aware Resize

Earlier this week, we introduced media/ContentAwareResize, a microservice which crops images to any size… while ensuring that the important parts do not get removed! It does so by detecting important content (faces, etc) and centering the crop on these components, so you don’t accidentally remove your friend’s head when generating a banner image.

How can we wrap this service into a nice, usable tool? Since Algorithmia’s microservices are language-agnostic, meaning that they can be called from just about any programming language (including JavaScript), we can easily write a simple webpage to generate images in a variety of useful sizes, so that we can quickly create banners, thumbnails, and social-share versions of our photos.

Step 1: get an API Key

If you don’t already have an Algorithmia account, head to algorithmia.com/signup and get 5,000 free credits each month!

Next, go to algorithmia.com/user#credentials and copy your API key (the strange-looking text starting with “sim”). We will use this in Step 3.

Step 2: create a basic webpage

For now, we’ll create a simple HTML file called “content-aware-resize.htm” on our local machine (if we ever move this to a publicly-accessible host, we’ll want to use a slightly more secure API key… see the note at the end of this walkthrough).

It’ll be super-ugly until we add some nice styling, but for now, let’s just get the basics down:

<script src="https://algorithmia.com/v1/clients/js/algorithmia-0.2.0.js" type="text/javascript"></script>
<script src="content-aware-resize.js" type="text/javascript"></script>
<h3>Image:</h3>
<input type="text" size="80" id="img_url" value="https://upload.wikimedia.org/wikipedia/commons/f/f7/Hickory_Golfer.jpg" />
<h3>Automatically resize:</h3>
<input type="submit" value="Thumbnail 150x150" onclick="resize(150,150,'thumb')" /> <a download="thumb.png" id="thumb">Download</a><br/>
<input type="submit" value="Banner 1200x300" onclick="resize(1200,300,'banner')" /> <a download="banner.png" id="banner">Download</a>

The first two lines import the Algorithmia JavaScript Client library, and the code we’ll be writing in Step 3 below.

Then, we simply have an input box to collect the URL of any publicly-accessible image we want to resize, and buttons to call a resize() function. Also note that the “Download” links have no HREF… they don’t link to anything. We’ll address that in the resize() function as well.

Step 3: write the JavaScript

Using the Algorithmia JavaScript Client is pretty easy. Feel free to read through the full documentation, but for now there’s just one key line:

var algo = Algorithmia.client("your_api_key").algo("algo://media/ContentAwareResize/0.1.3");

Replace “your_api_key” with the API Key you copied in Step 1 above. This line creates a client instance and prepares it to call version 0.1.3 of the media/ContentAwareResize microservice.

Place this line in a file called “content-aware-resize.js”. Now we’ll add our resize() function and, inside it, call the microservice:

var resize = function(width, height, anchorId) {
  var input = {
     "image": document.getElementById("img_url").value,
     "height": height,
     "width": width,
     "binarize": true
  };
  algo.pipe(input).then(function(response) {
    document.getElementById(anchorId).href = response.result;
  });
};

Pretty simple, right? But lets go through line-by-line:

Algorithmia microservices take JSON, so we can define the input to the service by just creating a JavaScript Object. Looking at the algorithm definition, we can see that it requires three parameters: the URL of the image, and the height & width to which it should be resized. In addition, the optional parameter “binarize” indicates that it should return the image as a base-64 encoded string, which can be directly embedded in HTML.

Next, we call algo.pipe and hand it our input. This fires off the microservice and returns a promise. If you’ve never used promises, all you need to know is that .then() takes a function (“callback”) which will be called once the service is done running.

Inside the callback function, we grab the “result” property of the response: this contains the base64-encoded, resized image. Remember those empty “Download” links in Step 2? By setting their HREF property to the base64 string we got back from the microservice, we now make those links live: clicking them will cause the browser to “download” the encoded image as a file.

Boom, done: we now have a webpage into which we can paste an image URL, click a button, and get back a download link to the resized image. And we know that this new image will be properly centered around the most important content… it is a content-aware, intelligent resize, not merely an automatic crop-to-fit.

Original image

1200×300 banner

150×150 thumbnail

Since Algorithmia’s microservices all use the same basic client interface, we can easily swap out the algorithm name media/ContentAwareResize/0.1.3 to perform a variety of other image-transformation functions, such as Automatic Colorization or Image Styling, without significantly changing our boilerplate HTML & JavaScript.

One last note: the default API key you copied in Step 1 is for you, and you alone. If you plan on publicly hosting this code, go back to algorithmia.com/user#credentials and click “new simple key”. Under “Algorithm access”, delete “algo://*” and add “algo://media/ContentAwareResize”. Also make sure to uncheck “native clients” and check “web browser”, then fill in “Restrict referrer hostname” with the domain name of your website. Save and copy this new key… it is safe to use publicly, since it can only be used to call specific algorithms, and only from your own website.

That’s it! I’ve further enhanced the demo to show a “loading” message while the microservice is running, and to include a “manual” resize mode where users can enter a specific height and width. Grab the complete code below or from the GitHub repo. Have fun!

content-aware-resize.htm

<html>
<head>
    <script src="https://algorithmia.com/v1/clients/js/algorithmia-0.2.0.js" type="text/javascript"></script>
    <script src="content-aware-resize.js" type="text/javascript"></script>
</head>
<body>
    <h3>Image:</h3>
    <input type="text" size="80" id="img_url" value="https://upload.wikimedia.org/wikipedia/commons/f/f7/Hickory_Golfer.jpg" />
    <h3>Automatically resize:</h3>
    <input type="submit" value="Thumbnail 150x150" onclick="resize(150,150,'thumb')" /> <a download="thumb.png" id="thumb"></a><br/>
    <input type="submit" value="Banner 1200x300" onclick="resize(1200,300,'banner')" /> <a download="banner.png" id="banner"></a><br/>
    <input type="submit" value="Twitter 1024x512" onclick="resize(1024,512,'tw')" /> <a download="tw.png" id="tw"></a><br/>
    <input type="submit" value="Facebook 1200x628" onclick="resize(1200,628,'fb')" /> <a download="fb.png" id="fb"></a>
    <h3>Manually resize image:</h3>
    Width: <input type="number" style="width:4em" id="width" value="150" /><br />
    Height: <input type="number" style="width:4em" id="height" value="300" /><br /><br />
    <button onclick="resizeManual()">manual resize</button> <a download="manual.png" id="manual"></a>
</body>
</html>

content-aware-resize.js

var algo = Algorithmia.client("your_api_key").algo("algo://media/ContentAwareResize/0.1.3"); //
var geid = function(id) {return document.getElementById(id);}

var resize = function(width, height, anchorId) {
  var anchor = geid(anchorId);
  anchor.innerText = "Loading...";
  var input = {
     "image": geid("img_url").value,
     "height": height,
     "width": width,
     "binarize": true
  };
  algo.pipe(input).then(function(response) {
    anchor.innerText = response.error?response.error.message:"Download";
    anchor.href = response.result;
  });
};

var resizeManual = function() {
  resize(parseInt(geid('height').value), parseInt(geid('height').value), 'manual');
};