How to use PHP's built-in DOMDocument class to proportionally scale images to a desired width.
I'm currently working on a mobile website which uses dotMobi's DeviceAtlas webservice, but unfortunately this uses JSON functions not introduced until PHP 5.3 and the server the mobile site is running from is still on 5.2.0.
The DeviceAtlas code is being used to get the specific capabilities of mobile devices from a JSON document supplied by dotMobi, from which I can access the device width, allowing me to re-generate and cache images that are perfectly adapted to meet the device being used to browse the mobile site.
Rather than hacking my code to bits to allow it to use a standalone implementation of JSON, I've instead done a very rough hack (just to tide me over while I'm waiting for the upgrade to PHP 5.3) which simply scales images down by proportionally adjusting the dimensions in the image width and height tags.
DOMDocument()
To find the width and height of all images embedded in the HTML stored in my CMS, I'm using the DOMDocument class, which is built into PHP. Here's my little function:
function scaleImages($html,$new_width){
$dom = new DOMDocument();
$dom->loadHTML($html);
$dom->preserveWhiteSpace = false;
// Scan HTML string and examine img tags
$images = $dom->getElementsByTagName('img');
foreach ($images as $image) {
// Get sizes of elements via width and height attributes
$src = $image->getAttribute('src');
$width = $image->getAttribute('width');
$height = $image->getAttribute('height');
// Calculate proportional scaling
$scale_factor = $new_width/$width;
$new_height = floor($height * $scale_factor);
// Set new attributes
$image->setAttribute("width", "$new_width");
$image->setAttribute("height", "$new_height");
}
// Return the HTML string with the new element sizes
$html = $dom->saveHTML();
return $html;
}
How it works
The loadHTML method of DOMDocument is used to take the string of HTML containing the full image tags, then we extract all of the image tags using the getElementsByTagName function.
Then, it's simply a case of looping over the images, getting the source, image and width, calculating the new width from the device width variable and writing the new height and width attributes back to the image tag, then saving the HTML and returning the chunk to the CMS code to print the extracted chunk with the images proportionally scaled down.
Obviously, it's a hack, but it does do the job quite effectively, for now.
评论