Image Resizing on Client Side

Eegee edited this page Jan 8, 2014 · 17 revisions

Table of Contents

Intro

Plupload supports manipulating images (JPEGs and PNGs) on client-side, which includes downsizing them, dropping their quality (for JPEGs only) and stripping off the meta headers (for JPEGs only as well) - all to make them smaller in size and save the bandwidth.

Might be very handy, when image is uploaded only to become a tiny avatar, etc. Currently it is not suitable for generating high-quality images (see #707), because it is using a default algorithm (apparently a so called nearest neighbor interpolation) for resizing. We are planning to adapt a bilinear interpolation algorithm in the nearest releases.

Lets build up on the code that we wrote for .

Options

resize option is a compound object with some sub-options:

  • width - if image is wider, it will be resized (if not specified, original image width will be used).
  • height - if image is higher, it will be resized (if not specified original image height will be used).
  • crop - whether to crop the image to the exact dimensions, rather than resize proportionally (default false).
  • quality - quality of resulting JPEG (PNGs are not affected) (default 90).
  • preserve_headers - whether to preserve JPEG meta headers (PNGs are not affected), e.g.: Exif, Gps, IPTC, etc (default true).

Enable resizing

To enable resizing on the client-side we need to pass in resize option with new width and height (obviously resize is not the best name for the option, since currently we can only downsize). Because we are building up on code, updated configuration should look something like this:

var uploader = new plupload.Uploader({
    browse_button: 'browse', // this can be an id of a DOM element or the DOM element itself
    url: 'upload.php',
    resize: {
        width: 100,
        height: 100 
    }
});

Plupload will take the larger side of the image and decrease it to fit the specified dimensions. The other side will be resized proportionally.

It is worth to mention that having resize option in configuration doesn't mean that Plupload will be constrained to images only (there's another option for that). It simply means that if Plupload will encounter an image in the queue it will try to process it prior to uploading (if it meets the requirements), according to the specified settings. All other file types will be uploaded as usual.

Crop to exact dimensions

By default image will be resized proportionally, using the larger side as maximum. If you want to crop an image to fit the exact dimensions, you need to set the crop sub-option to true (default false):

resize: {
    width: 100,
    height: 100,
    crop: true
}

Configuration like this will make sure that image will be center-cropped to 100x100 before it is actually uploaded.

Decrease quality JPEGs only

quality sub-option can be used with other resizing options or without them, since sometimes it might be required to decrease the images size without changing its dimensions. Hence it can be:

resize: {
    width: 100,
    height: 100,
    crop: true,
    quality: 70
}

as well as simply:

resize: {
    quality: 70
}

It is worth to mention once more that this is applicable only to JPEGs, since PNG is lossless format and doesn't understand quality gradations.

Strip meta headers JPEGs only

It is normal for JPEGs to have meta headers inside: Exif, Gps, IPTC, etc. Usually you would want them to survive the resizing operation and that's what happens by default. But when you do not care about exif and such and all you need is the smallest possible file size, you might want them to be removed:

resize: {
    preserve_headers: false
}

You might save some additional bytes with this. If meta headers contain Orientation tag, JPEG will be auto-rotated accordingly.

Limitations

Obviously client-side and specifically browser environment cannot be as powerful (not yet at least) as the server-side might be. So somewhere there must be a limitation on the resolution that might be handled in the browsers or their add-ons. We assume it to be 6500 by 6500 pixels (about 42MP). I say assume, because there's no way to figure out the actual top line or detect when browser (or its add-on) runs out of memory - if this happens it simply hangs (the best case). So we came up with the safe margin, where browser can still reliably operate (read - breathe) and if either side of the image is larger than that margin, Plupload will simply bail out and upload the image as is, without any tampering.