jQuery Plugin for ImageEngine

jQuery Plugin for ImageEngine

ImageEngine is an image resizing tool particularly suited for web mobile scenarios where it can significantly reduce the image payload of and improve the load time of views. ImageEngine works as a plain and smart Content Delivery Network (CDN). It sits in between your server application and the client browser and replaces the host server when it comes to serving some, or all, of the images of the web view.

In this article, we’ll see how to encapsulate the functionality of the ImageEngine in a jQuery plugin.

An Executive Summary of ImageEngine

Because a picture is always worth a thousand words, here’s how ImageEngine works in a classic web site.

ImageEngine jquery plugin

The browser requests the content of a URL and the web site returns some markup that may include references to images. Next, the browser places additional requests for each of the referenced images. If the URL of images refer to endpoints in the ImageEngine server, then ImageEngine will get the bits of the image from the referenced server and cache it as if it were a plain simple content delivery network.

ImageEngine, however, is not a plain simple CDN and has a significant advantage over all of them: it understands the capabilities of the requesting devices and can serve properly re-sized images and keep them cached for the later use.

The ImageEngine is a tool to reduce the network traffic generated by images. It is not limited to mobile web scenarios, but it surely shines when used in the context of mobile views. By serving images through ImageEngine a web site may guarantee that smaller images are served to non-desktop devices. The list of plus is a bit longer though:

  • You can serve properly resized images to non-desktop devices
  • You can serve images resized as you indicate to just any device
  • You can use ImageEngine as an online resizer tool with a URL-based programmatic interface
  • ImageEngine serves as a CDN and can be expanded to scale as you need
  • ImageEngine reduces the burden of the creating and maintaining multiple versions of the same image to speed up load time on devices

The full documentation of ImageEngine is available in our docs section. Also noteworthy is that ImageEngine is ready for HTTP2 and Client Hints—the emerging proposal for browsers to send information about the preferred size of images to the web server. Client Hints consists of a bunch of miscellaneous HTTP headers that ImageEngine understands today. (For more information on Client Hints, check out Using Client Hints and Image Optimization.)

Motivation for a jQuery Plugin

To use ImageEngine, you must edit the URL of the images you refer in your HTML views. The pattern must be the following:

<img src="[prefix]/[absolute URL of the image]" />

The prefix token is the name of the ImageEngine server. The absolute URL token refers to the absolute URL path of the image you want to display through the IMG element. ImageEngine acts as a proxy and downloads and caches the image for you. This requires that you tweak your image URLs a bit. Here’s a realistic one:

<img src="//image-engine-server/http://www.expoware.org/images/autumn.jpg">

Without ImageEngine, the same HTML element will likely be written in a more portable way, as below:

<img src="/images/autumn.jpg">

At the same time, the ImageEngine server name and the current host origin can be added programmatically to the URL. This can happen in either of two ways: server-side or client-side. The details of the server-side approach depend on the specific platform you target, whether Java, PHP or ASP.NET. On the client side, instead, there’s only one possible approach: using JavaScript and possibly a jQuery plugin. The benefit of using a jQuery plugin is just that you keep writing portable code based on relative URLs and the plugin takes care of turning them into ImageEngine compatible URLs on the fly.

Using such an ImageEngine plugin is particularly beneficial if the referenced images are originally stored on the same server as the rest of the application. However, the plugin would still abstract you away from the details of linking in the ImageEngine server.

Skeleton of an ImageEngine jQuery Plugin

Any jQuery plugin is typically built around the following core template.

$.fn.yourPlugin = function() {
 // Some logic here
 ...
 return this;
 }

It’s way too simple; and even a bit simplistic. According to http://learn.jquery.com/plugins a much better starting template is the following:

if (!jQuery)
 throw new Error("ImageEngine plugin requires jQuery");
(function ($) {
 $.fn.imageEngine = function (options) {
  var settings = $.extend({
  // Set default values for plugin options
 }, options);
// Restrict the plugin to process only IMG elements.
 // Implementation here...
 this.filter("img").each(function () {
  ...
 }
 return this;
 };
}(jQuery));

Admittedly, the above template works beautifully for our purposes of speeding up use of the ImageEngine tool. The wrapping immediate function ensures we can freely use the $ symbol in our code ensuring it is bound to the jQuery object thus avoiding any troubles with other libraries that might be working side by side with our plugin in the same host web view. In addition, the plugin only processes IMG elements and ignores every other element that should be picked up by the selector.

The beauty of a jQuery plugin is proportionally direct to its level of customization. Therefore, the more options you provide for developers to customize the behaviour, the better. A common practice in JavaScript is to provide an object set to default values that is overridden during the initialization of the function. The table below lists a few good candidates to become options in our ImageEngine jQuery plugin.

Option Default Description
account “” Gets and sets the account name to use with the ImageEngine backend. The account name is chosen when you sign up to use the service.
addBootstrapResponsive true If set to true, adds the Bootstrap’s img-responsive attribute to the current IMG element.
debug false If set to true, it overrides the alt and title attribute of the current IMG element to reflect the actual URL being used.
format “” If set, determines the format of the image being returned. If not set, ImageEngine will automatically determine the best format. Feasible values are the values supported by the f parameter of the ImageEngine framework.
height “” If set, indicates the desired height in pixel of the resized image. This option matches the h parameter of the ImageEngine framework.
mode “” If set, indicates the desired working mode of the resizing algorithm. Feasible values are the values supported by the m parameter of the ImageEngine framework.
percentage “” If set, indicates the size of the image as a percentage of the screen width. This option matches the pc parameter of the ImageEngine framework.
transparencyColor “” If set, indicates the transparent color to use when the image is resized in letterbox mode.
width “” If set, indicates the desired width in pixel of the resized image.

This option matches the w parameter of the ImageEngine framework.

 

For more information about the various parameters and related feasible values that can be used, you may refer to the documentation. In light of these options, the code of the plugin becomes:

var settings = $.extend({
 addBootstrapResponsive: true,
 debug: false,
 account: "",
 width: "",
 height: "",
 percentage: "",
 mode: "",
 transparencyColor: "",
 format:""
 }, options);

The internal implementation of the plugin is built around the composition of an ImageEngine compatible URL.

this.filter("img").each(function () {
 var computedUrl = "//try.imgeng.in/";
 var img = $(this);
// =========================================================
 // Turn the IMG source into an absolute URL
 var absoluteUrl = img.attr("src");
 var r = new RegExp('^(?:[a-z]+:)?//', 'i');
 if (!r.test(absoluteUrl)) {
 absoluteUrl = window.location.origin + absoluteUrl;
 }
// =========================================================
 // Manage ImageEngine settings
 // Fix account reference
 if (settings.account) {
 computedUrl = "//" + settings.account + ".lite.imgeng.in/";
 }
// width-height || percentage
 if (settings.width || settings.height) {
 if (settings.width) {
 computedUrl += "w_" + settings.width + "/";
 }
 if (settings.height) {
 computedUrl += "h_" + settings.height + "/";
 }
 } else {
 if (settings.percentage) {
 computedUrl += "pc_" + settings.percentage + "/";
 }
 }
// fit mode
 if (settings.mode) {
 computedUrl += "m_" + settings.mode;
 if (settings.mode === "letterbox" && settings.transparencyColor) {
 computedUrl += "_" + settings.transparencyColor;
 }
 computedUrl += "/";
 }
// image format
 if (settings.format) {
 computedUrl += "f_" + settings.format + "/";
 }
// =========================================================
 // Core work
 computedUrl += absoluteUrl;
 img.attr("src", computedUrl);
// =========================================================
 // Further configuration
 if (settings.addBootstrapResponsive) {
 img.addClass("img-responsive");
 }
 if (settings.debug) {
 img.attr("alt", computedUrl);
 img.attr("title", computedUrl);
 }
 });

The ImageEngine URL points to a user-specific server of the form:

//account.lite.imgeng.in/image_url

If parameters are specified they will be added to the URL, as in the example below.

//despos.lite.imgeng.in/w_200/h_200/m_cropbox/http://yourserver/images/cat.jpg

A URL is ultimately a string that carries as much information as possible. It’s no big deal for software to deal with URL strings, but a plugin can significantly simplify things for humans.

Using the jQuery Plugin

A jQuery plugin is a plain JavaScript file that you must reference right after the jQuery file in your web views. Here’s how to use the plugin.

<script type="text/javascript">
 $("img").imageEngine({
 debug: true,
 account: "your-account",
 width: 400,
 height: 400,
 mode: "cropbox",
 transparencyColor: "0000ff"
 });
 </script>

In the simplest case, you need the following:

$("img").imageEngine( {account:"your-account"} );

If you just want to give ImageEngine a try, you could even call it without any parameters. In this case, as shown in the code, the ImageEngine URL is try.lite.imgeng.in which is only used (and recommended) as a test platform.

$("img").imageEngine();

Thanks to the jQuery flexibility, you can even turn into ImageEngine endpoints all images in a web view in a single shot. It all depends on the jQuery selector you use to apply the plugin.

Summary

ImageEngine is based on the WURFL framework for detecting device capabilities. It requires a fairly convoluted URL to work and details of the various options to be deeply learned. With a jQuery plugin, things come a lot easier and enjoyable.

The source code of the ImageEngine jQuery plugin is available on github.

  • Luca Passani

    A comment that someone else will flag soon

  • Scientia Mobile

    This addresses the JQuery use-case.