Sapan Diwakar

Software developer

Follow me on Twitter Check out my code on GitHub View some of my designs on Dribbble Take a look at my Linked In profile

Resizing images using Appcelerator Titanium

While building an app with Titanium, I came across the need to display several images in a grid. This works fine if the images are quite small. But for large images, it makes no sense to try to show the full resolution version of the images in a grid which would show only a very small version of the image. But, since we were downloading the images which were uploaded by the users, we had no control over the size of the images that we were going to get. It was therefore, our responsibility to scale these images on the device. The Titanium imagefactory module takes out a lot of work required at this stage by providing convenient functions for resizing the images. Here's a small piece of code that resizes the images using Ti.imagefactory module.

// Read the image as a blob
var blobOfImage = imageFile.read();

// Put it in a imageView, since It wont let me get height from a blob for some reason
var imageView1 = Titanium.UI.createImageView({  
    image: blobOfImage,
    width: 'auto',
    height: 'auto'
});

// This is the important part, toImage this view and you get the height and width of this image
// For some reason we cant get this from a Blob in SDK 2.1.1.GA
var heightOfImage = imageView1.toImage().height;  
var widthOfImage = imageView1.toImage().width;

var aspectRatio =  heightOfImage / widthOfImage;

if (widthOfImage > 640) {  
    var newWidth = 640;
    var newHieght = newWidth*aspectRatio;
    Ti.API.info('Resizing image from ' + widthOfImage + ', ' + heightOfImage + ' to ' + newWidth + ', ' + newHieght);
    var smallImage = ImageFactory.imageAsResized(blobOfImage, {
            width: newWidth,
            height: newHieght,
            quality: ImageFactory.QUALITY_MEDIUM
    });
    Ti.API.info('Got small image. Writing to file.')
    imageFile.write(smallImage);
    Ti.API.info('Finished writing small image to file.')
}

This works pretty well as long as the image is small enough so that it doesn't violate the memory constraints. But with the images coming in from the users, this wasn't something we could rely on. An approach that we had to resort to for larger images involved sending the images over the network to an external server that then resized the images on the server. We built a web service on out own servers to avoid sending out the images to an external service to resize as we already had images on our servers.

Ti.API.info('Querying server for resized image.');

// Get resized image from server.
var c = Titanium.Network.createHTTPClient({  
    timeout : 1000000  
});

c.onload = function() {  
    Ti.API.info('Donwloaded resized image from server.');
};

c.onerror = function(e) {  
    Ti.API.info('Failed to download resized image from server.');
    Ti.API.info(e);
};

// open the client
c.open('GET', url);  
c.setFile(imageFile); // Downloads the resized image to this file.

// send the data
c.send();