Server-side image resizing has often been a sticky topic when it comes to building CMS powered websites, and it is something I have encountered a lot during my years of building websites on WordPress. I thought it would be a good idea to write-up my findings and also the “solution” we have come up with to solve problems we found along the way.
What surprises me most about image resizing / scaling is how people (clients mainly) often don’t understand the problems and decisions involved in using images on a content management website. So much so, I wanted to outline some of the basic issues.
Aspect Ratio is the most difficult issue with images, it’s not a technical problem – it’s just a misunderstanding of how images fit onto a canvas. I have often tried to explain to a client that 4:3 ratio images literally cannot fit in a canvas that is 5:2. Period.
Lets work with the following image as the “original”.
The red border here represents the canvas; no problems here because the canvas is the same aspect ratio as the image. Now, if we want to display this image in a square canvas, we have 2 options.
In Option 1 we have resized the image down to the size of the canvas until the smallest side reaches the edges of the canvas, then the remaining image outside the canvas is chopped off. Problem is: we just lost Australasia, half of America, China, Japan etc. this is known as zoom crop or adaptive resize.
In Option 2 we have resized the images until the largest size reaches the edge of the canvas. This will ensure the whole image is kept on the canvas – but it also means our image has a lot of white space on the top and bottom. When displaying thumbnails in a list, or images have a border, this can look far from ideal.
There is no fix here. We can either crop the parts of the image that don’t fit into the canvas’ aspect ratio (but this will mean losing potentially important parts on the image), or we can resize the image to fit inside the canvas, but it will not fill the canvas.
At this point, you are probably thinking “well, that’s ok – some images can be cropped (the ones where retaining all of the image information is not needed), and we will resize the other ones to fit inside the canvas”. The problem is that this is for dynamic websites, where the developer does not control the images, there needs to be a system in place to handle any type of image.
Now what you are probably thinking is “dude, WordPress has a crop feature built-in, just let the authors choose what the cropped thumbnails look like”. That works, but only if you have one aspect ratio for post images throughout your whole site. Many of the projects we work on involve a lot more dynamic displaying of images than that. For example, an image uploaded for a post on Digital Trends is shown in many different sizes / aspect ratios. On the homepage it’s shown as a `150 x 150` thumbnail, in the feature carousel it’s shown at `640 x 320`, the carousel thumbnail is slightly different again – and in the future redesigns it would be shown at completely different aspect ratios.
Asking an editor to crop 6 variants of one image is not going to happen. Especially when you tell them they have to go back and update 30,000 images because you are now showing them in an iPad app at a 9:2 ratio. What we really need is a way for the authors to specify where the important portion of the image is, and all our cropping / scaling / resizing can be orientated around that. Think of it more as saying “where is the focal point, and we will do the leg work” as opposed to saying “give me the 12 variants of this image”. Now we have a way to give the images areas meaning, we can choose the best resizing method based on that information.
Enter WP Thumb, if you haven’t read the post “Introducing WP Thumb” I suggest you do. WP Thumb is our Image Resizing WordPress plugin. Amongst many other things, it lets the image uploader specify the “anchor” (or focal point) of an image. When it comes to displaying the images at a different aspect ratio we can use this information to best resize the image.
The important thing to notice here is that the author is not choosing to crop the image. By selecting the top center radio button, they are saying that is the focal point. If the image were shown in a square it would not be a close up of the figures face, it would be the same as the original. However, if the image was shown in a very wide aspect ratio, it would appear more like the example image above i.e. a section across the head.
Lets take the following image as an example.
In the following images, the left image has been resized using a default adaptive-resize, whereas the examples on the right have the “top,center” position (as if the author had selected the head region as the focal point).
The left image (where we have used “default” cropping) doesn’t work so well if it’s shown in aspect ratios that’s not close to the original. The images below demonstrate this problem even further. The image on the left is pretty much useless (unless it happened to be a story about a mans crotch) because the author selected the “important” part of the image, the right-hand photo still makes sense.
All of this is fine for photos. Photos are where (generally) you want to be doing an adaptive resize function – photos look best when they are filling the canvas, blocks of white on the top/bottom or left/right make it look fairly ugly. However, let’s try the same but using a logo rather than a photo.
The top image is the original Google logo, you can see from the two images below – no matter what point we set as the “anchor” point, the image is not coherent. To display this logo in a square box, it needs to be shrunk down and not cropped at all. Sure, you could resize it, put it in a square container and set the background colour of the container to white and “done”. Well… no, because firstly – all uploaded images won’t have a white background and secondly: you will have to code for the possibility of any image not being the exact dimensions, and so will any 3rd party developer; such as the poor iOS developer who just asked for `100 x 100` images, but you just confused things by giving him a load of `100 x 37`, `56 x 100` [etc] images to work with.
Re-enter WP Thumb. We have built an argument into WP Thumb called background-fill: solid. This will automatically fill the excess canvas space with the background colour of the image. You will be thinking “ugh, don’t go there, trying to estimate image colours is a world of pain”. Well, you would be kind of right – if you want it to work for every image. The key here is that WP Thumb only does it if it’s reliable. If an image is surrounded by black pixels, it will fill the excess space with black. If it’s surrounded with blue pixels, it will do the same. If this isn’t an option (for example it is a photo with thousands of different colours around the edge, it will fall back to adaptive resize. All this is doing is improving this where possible. If it makes 20% of the logos or cut-out images authors are uploading – that’s great and we will fall back to adaptive resize including the “crop from position” technique.
Below are some example of WP Thumb’s background-fill option at work. The important thing to note is that all the following images are that actual size, they are not a narrow image in a html container. Background-fill is adding the extra pixels to the image itself.
To re-iterate, background-filling images will not work in every case – but if it can catch 20% of images then it’s certainly not a bad thing. The great thing is, all of this can be automated with WP Thumb; but this isn’t about the technical documentation, it’s about making good “catch-all” rules for images on large dynamic driven websites. We have taken the steps to implement the technical aspect, and created (and open sourced) WP Thumb, we haven’t done anything new but we have integrated it very closely into WordPress and it’s functions.