Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Resize/Shrink Photos for Web Development

0.00/5 (No votes)
27 Oct 2008 1  
Resize/Shrink Photos for Web Development to reduce download time

Introduction

What if we wanted to resize/shrink photos for Web development to reduce download time? Amazingly, tools like Picasa and Windows Photo Gallery lack this feature. Unlike Aaron Sherman's Quick Snip, shrinkpictures.com, and resize.it, our app needs to resize the image interactively. While resizing, we want to see how large the result is and what width and height the resized photo gets. We would also like to use Silverlight, wouldn't we? So here we go.

(You need Microsoft® Silverlight™ Tools for Visual Studio 2008 SP1 (RC1) to run the demo solution.)

Roadblocks

Our app, the ImageShrinker, lets us select a *.jpg or *.png file, view it in original size, resize it with a slider, and save the resulting image to a file (in the same format). Sounds simple, right?

But of course, there are the usual ... roadblocks:

  • The path of the selected file is not available.
    The file selected in the OpenFileDialog does have a name, but not a path. Oh well. weird limitations exist.
  • The original image size is not known.
    I can see the actual size of the image as displayed but not the original size. The System.Drawing namespace with its Image class is not available to help us compute it. Bummer!
  • The resulting image cannot be saved on the client.
    It is understandable that we would not like Silverlight to write to the hard disk, but couldn't there be a control that asks the user for confirmation?

Luckily, there is always the server to come to the rescue! We can have an HttpHandler on the server that calculates the image size for us, using System.Drawing.Image. We access this HttpHandler by means of the very useful WebClient class.

//Using System.Net.WebClient
using (FileStream stream = openFileDialog.File.OpenRead())
{
    byte[] buffer = new byte[currentFile.Length];
    stream.Read(buffer, 0, (int)currentFile.Length);
    string imageData = Convert.ToBase64String(buffer);
    WebClient wc = new WebClient();
    wc.UploadStringCompleted += 
	new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
    wc.UploadStringAsync(new Uri("getsize.ashx", UriKind.Relative), imageData);
}

void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
    string size = e.Result;
    //...
}

Saving the resulting image is a bit more cumbersome. WebClient does not help us here. It can help us send the original image to the server and get a shrunken version back, but then what? We can still not save it. Let's throw in another trick and submit an ASP.NET page that has a hidden field in it that holds the image data. That page would then return the resulting image in its response, causing the browser to prompt us where we want to save the image. To make the postback invisible to our users, we put the ASP.NET page with the hidden field in a hidden iframe.

//Calling JavaScript
object[] paramArray = new object[3];
paramArray[0] = imageData;
paramArray[1] = slider.Value / 1000;
paramArray[2] = tbxFileName.Text;
System.Windows.Browser.HtmlPage.Window.Invoke("echo", paramArray); 

The JavaScript function echo:

function echo(imgData, factor, fileName) {
    var ifr = document.getElementById('ifrSubmit');
    ifr.contentWindow.document.getElementById('hdnImgData').value = imgData;
    ifr.contentWindow.document.getElementById('hdnFactor').value = factor;
    ifr.contentWindow.document.getElementById('hdnFileName').value = fileName;
    ifr.contentWindow.document.getElementById('btnSubmit').click();
}

Wow! We did it! Was it worth the trouble doing this in Silverlight? It's certainly easier in Winforms (solution included in the demo project). But hey, isn't getting around roadblocks much more fun?

Browser Specifics

The app runs great in Internet Explorer (7 and 8 Beta) and Safari. Firefox did fine after a little bit of help using 100% of the browser window height.

In Chrome, the image is not automatically updated; it requires a resize of the window or some scrolling.:( To make the resize work, ImageShrinker scrolls a bit in JavaScript. This is clumsy. When a new image is loaded, it's not displayed (but moving the mouse over the slider helps).

History

  • 23rd October, 2008: Initial version 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here