digital expertise network :: about the guild :: case studies :: contact the guild :: articles :: second life :: tools

Dealing with images in content management systems

Tom Crane
16 January 2006

Navigation: Page 1 | Page 2 | Page 3 | Page 4 | Page 5 | Samples

(Download the source code for this article)

Most web-based content management systems offer a variety of tools to help contributors enter text. When it comes to graphics, content contributors are usually expected to provide web-ready images to the system. This means that either editorial users needs to know about image optimisation and web image formats, or additional staff are required to make web-ready images out of raw materials. This article demonstrates a technical solution to this problem.

The raw images might be from digital cameras, from mobile phones or from scans. These will almost always be far too large, both in pixel dimensions and file size, to be used as web images. In a typical scenario the finished images will need to be constrained to a certain pixel size to fit into whatever templates the site uses. For example, if we look at news stories on the BBC News site we can see that content images are always 203 pixels wide. Where they appear on the home page they must also be 152 pixels high, but when they appear alongside the text of a news story the height of the picture can vary to fit the content. Thumbnails are 66 pixels square. We need some form of user interface that takes a "raw" image as input and allows the non-technical user to generate an appropriately sized image that is both aesthetically pleasing, optimised for the web, and conforms to any arbitrary image dimension rules that we might like to impose. Almost always a raw image will be improved for web use by some judicious cropping.

Many content management systems offer some degree of automation for processing images, usually confined to automatically generating thumbnails from supplied files. While this method is good for showing you what a batch of images contains, it seldom produces a satisfactory "teaser" thumbnail like the ones you might find on a site homepage. Such thumbnails require human intervention.

The solution is an ASP.NET server control that allows the end user to upload an image from the local file system and crop, scale and optimise it to obtain a satisfactory web image. The server control inherits from the new CompositeControl class, which makes it easier to compose new server controls out of existing, simpler controls. This control makes heavy use of JavaScript, DOM and CSS on the client to power the user interface and requires a modern web browser. It will work in Firefox across all platforms, IE6 on Windows and Safari on MacOSX. The control looks like this when used on an aspx page:

<guild:WebImageMaker id="wim_main" runat="server" width="250" BorderStyle="Solid" BorderColor="#c0c0c0" BorderWidth="1px" CancelButtonText="Cancel" ConfirmButtonText="OK" UploadButtonText="upload image..." ImageWidth="203" ImageHeight="*" ImageUrl=" " WorkingDirectory="C:\imagemaker_workingdir" Format="jpg" Quality="High" />

The key attributes here are the last 6. ImageWidth and ImageHeight dictate the dimensions of the web image that the control will create. These properties are actually strings which allow us to enter a "*" character, indicating that we don't mind what one of the dimensions is. At least one of these two properties must evaluate to a positive integer, otherwise the control doesn't have enough information to determine the final image size. ImageUrl is used to allow the control to render a current web image if it is being used to change an existing web image rather than create a new one. WorkingDirectory indicates where the control will save the images it creates. Before you can run this project successfully you'll need to create this directory and grant the process that ASP.NET is using write access to it. The working directory doesn't need to be under the web root. Format and Quality dictate how the control will produce the final web image.

The control looks like this in its "default" condition. No image has been uploaded yet. If the user was changing an existing image then the existing web image (the ImageUrl attribute) would be visible here instead of the default placeholder graphic.

Control in default state

The file selector is a standard WebControls.FileUpload control. The user browses the file system to find an image file to upload, then clicks the "upload file..." button. This might take a while for a large image. Once the form is posted the control's server-side code examines the file to check that it is an image. It also stores the raw image dimensions for later use.

For the user to crop the image, the control must render the image back out to the browser once the file is uploaded so that the user has a "canvas" to work on. However, the uploaded image will often be far too big to fit into the user's browser window, so the control needs to scale the image before rendering it back out as a canvas. This scaling operation is nothing to do with the creation of the final web image – it is solely to generate an appropriately sized canvas for the user to work on. By default the control generates a canvas that is scaled to be 4/5 of either the width or height of the user's browser window, depending on the aspect ratio of the uploaded image. This guarantees that the image will always be visible without scrolling regardless of the size of the user's browser window. Client-side script stores the dimensions of the browser window (the "viewport") in a hidden form field just before the form is submitted.

Canvas

The control renders the canvas (and some accompanying UI) in a DIV that is positioned to appear floating above the control. Although the rendered HTML for this DIV is nested in the control's rendered HTML, the DIV itself needs to occupy as much screen space as possible. We wouldn't have a usable canvas if it had to be confined within the space occupied by the control in its default setting. So client-side script repositions the div appropriately, using CSS absolute positioning and the z-index property to take the canvas div out of the normal flow of the document and allow it to appear floating above the rest of the page.

Floating above the generated canvas is the selection rectangle. This is another DIV, with a dashed border.

selection rectangle

Client side script responds to mouse move events, so that when the pointer is near the edges of the div the cursor changes to a resize icon and when the pointer is over the body of the div the cursor becomes a move icon. The user can move and resize the selection box to select an appropriate crop. When only one of the dimensions (ImageWidth and ImageHeight) is specified the shape of the cropping rectangle is unconstrained – the control will scale the image so that the specified dimension is correct, and the other dimension will end up whatever it needs to be to match the crop selected by the user. If both dimensions are specified then a particular aspect ratio (width/height) needs to be enforced, so client-side script constrains the cropping rectangle to this aspect ratio as the user drags the corners around.

proportional resizing of selection

Once a satisfactory crop has been selected the user presses the "OK" button. Client-side script stores the location and size of the selection rectangle relative to the canvas image, and a postback is initiated. On the server, these client coordinates are transformed into coordinates on the original raw image (the control knows the dimensions of both the original raw image and the canvas it produced for the user to "draw" on). The original raw image is then cropped and scaled, and saved according to the format and quality specified as attributes of the control. The newly created web image is displayed in the control.

finished web image

The control exposes a property that allows a developer to access the created web image (e.g., for storage in a content management system) at a later point.

Two additional features aid usability. A typical scenario where this control might be used is to supply two related pictures for a news story – a main image and a thumbnail. In an editing interface, two instances of the control would be presented, one for the main image and one for the thumbnail. The first might have ImageWidth set to "203" and ImageHeight set to "*", and the thumbnail's control might have both ImageWidth and ImageHeight set to "66". The user will often want to use the same raw image for both web images, with different crops. To avoid the user having to upload the same raw image more than once, the control makes its own thumbnail image of each raw file uploaded (not to be confused with any images that happen to be used as thumbnails somewhere else that a user might create using the control) and stores a key to identify the uploaded image in the user's session. The control examines the session to see if any images have already been uploaded and generates a UI to select an already uploaded image if it finds any. All the user needs to do is click the image to go straight to the canvas, bypassing the potentially lengthy upload process.

thumbnails UI

The other feature accommodates the scenario where the user already has a web-ready image of the correct size. If the control finds that the uploaded image is already correct it will bypass the canvas stage and just save the raw file as the final image file.

Click here to see the control in action.


Navigation: Page 1 | Page 2 | Page 3 | Page 4 | Page 5 | Samples