How Stream Built Cabin Quickly with imgix

One of imgix's most powerful benefits is the ease of setting up the service and serving better images right away. This is true whether you're serving images directly to your customers or building a platform for others to use. One of our customers, Stream, demonstrated this in their tutorial about building a demo app called Cabin in React with their feed service.

Here's how they did it, in their own words. (This is part 5 in their series.)


Cabin–React & Redux Example App–imgix

For our image hosting and real-time processing, we are using imgix to serve our photo uploads and manipulate them on the fly.

imgix Servers

As the imgix website states, "This is not ImageMagick running on EC2. This is way better."

Indeed. Choosing imgix is choosing an easy way to adding ultra fast image rendering, CDN hosting, as well as intelligent caching. Nice. Companies like Zillow, Kickstarter, Eventbrite, and Lyft are using imgix—and it's incredibly easy for you to do so as well. It was breeze for us to implement in our React app. Follow along with me to see how easy it is to implement imgix in your application.


Overview

Here is what you will be learning in this post of the series:

  • Getting Set Up
  • Server Side
  • Client Side
  • Image Adjustments
  • More Awesome Features

Getting Set Up

Let's go through the simple steps of getting set up with imgix.

  1. First things first: Go ahead and sign up for an imgix account.

  2. Next, create a Source.

    Add a Source screen


    A Source is a place where your images will be uploaded initially. Your Source could be a web folder, but in this case, we are going to go with Amazon S3. For information on setting up AWS and an S3 bucket—click here.

  3. Finish up by adding your AWS credentials and S3 information—more information here.


Server Side

Have a look at api/config.js.

Since we're uploading to S3 and not imgix directly, you will simply see an object for your S3 credentials. The cool thing is, imgix will keep in sync with our S3 bucket.

s3: {
  key: [S3 Key],
  secret: [S3 Secret],
  bucket: 'stream-cabin',
  },

Photo Upload Process

Our photo upload process looks like:

  • Upload to Amazon S3 via the knox client
  • Add geocode information with the help of Mapbox
  • Insert the information into our MySQL database
  • Add to Algolia Search index
  • Push to the appropriate Stream feeds

Take a look at the code for the S3 upload via knox—in the api/routes/uploads.js file.

// async waterfall (see: https://github.com/caolan/async)
  async.waterfall([

  // upload file to amazon s3
  function(cb) {

  // initialize knox client
  var knoxClient = knox.createClient({
  key: config.s3.key,
  secret: config.s3.secret,
  bucket: config.s3.bucket
  });

  // send put via knox
  knoxClient.putFile(file.image.path, 'uploads/' + data.filename, {
  'Content-Type': file.image.type,
  'x-amz-acl': 'public-read'
  }, function(err, result) {

  if (err || result.statusCode != 200) {
  cb(err);
  }

  cb(null);

  });

  },

And that's the only code we need to handle our imgix integration on the server. imgix will handle the rest—keeping in sync with our S3 bucket.


Client Side

If you thought our server-side setup was simple—it's even easier on the client. Our image manipulation happens right in our image src tag inside of a React component.

Before we take a dive into the React component, let's look at app/config.js.

imgix: {
  baseUrl: 'https://react-example-app.imgix.net/uploads',
  },

In the case of imgix, we aren't adding any API keys—just the base URL we will be referencing in our PhotoItem React component. If you don't know your base URL—check it out on your Source page.

Take a look at app/modules/components/PhotoList/PhotoItem.js.

class PhotoItem extends Component {
    render() {
    return (
      <li>
        <Link to={`/photos/${this.props.id}`}>
          <img src={`${config.imgix.baseUrl}/${this.props.filename}?auto=enhance&amp;w=200&amp;h=200&amp;fit=crop&amp;fm=png&amp;dpr=2`} className="full-width" />
        </Link>
        <PhotoFooter {...this.props} onLike={this.props.onLike} />
      </li>
      )
    }
  }

Image Adjustments

One awesome thing about imgix is the Image API. As you can see from the code in the section above, we are making our image adjustments through the URL-based API:

?auto=enhance&w=200&h=200&fit=crop&fm=png&dpr=2

Let's break this down, feature by feature:

Auto

The auto parameter allows imgix to make certain types of adjustments and optimizations automatically.

enhance

When auto is set to enhance, the image is adjusted using the distribution of highlights, midtones, and shadows across all three channels—red, green, and blue (RGB). Overall, the enhancement gives images a more vibrant appearance.

Image Size

w=200

Sets the width to 200 pixels. You can also set size to a proportion of the original by using a range between 0.0 and 1.0.

h=200

Sets the height to 200 pixels. You can also set size to a proportion of the original by using a range between 0.0 and 1.0.

Resize Fit Mode

The fit parameter controls how the output image is fit to its target dimensions.

clip

Resizes the image to fit within the width and height boundaries without cropping or distorting the image.

Output Format

The fm output format to convert the image to. Valid options are gif, jp2, jpg, json, jxr, pjpg, mp4, png, png8, png32, and webp.

Device Pixel Ratio

Control the output density of your image.

The device pixel ratio (dpr) is used to easily convert between device independent pixels and device pixels. This makes it possible to display images at the correct pixel density on a variety of devices such as Apple Retina displays and Android devices. You must specify a width, a height, or both for this parameter to work. The default is 1. The maximum value that can be set for dpr is 8.


More Awesome Image API Features

imgix has a variety of functionality you can add to your app that goes way beyond what we have done so far.

Instagram-Like Filters

blend example

Want to incorporate Instagram-like filters into your application? It's as easy as making any image adjustment. Check out this great tutorial on dynamically blending images.

Go ahead and open up the imgix Image API documentation to see what other cool things can be do on-the-fly with imgix. Need more convincing? Check out this case study.


Conclusion

Using imgix, we were able to setup an advanced image resizing and processing micro service in just a few hours.


Cross-posted at cabin.getstream.io—you can see the rest of Stream's Cabin tutorial and demo there. The full source code is available on GitHub.

Stay up to date with our blog for the latest imgix news, features, and posts.