modx icon
29th
Apr 10

Auto Resize Images with MODx (Plugin)

Posted Thursday 29th April 2010
Needs Testing
This plugin has only been briefly tested. Please provide feedback.
The Auto Document Image Resizer plugin automatically resizes images placed inside documents (pages). It finds all images that have pixels specified and compares it the actual size of the image. If the size is greater or smaller than those in the img element it will resample (rescale/resize) producing a clearer and smoother image.

The images are stored in the cache (assets/cache) after the initial processing which helps improve performance whilst automatically keeping images up-to-date.

I wrote this as I can’t expect clients to manually resize images so this attempts to do it for them. There is, however, an exception right now. The image must have the intended width or height specified. For example the HTML must look like;

1
<img src="someimage.png" width="200" height="50" />

The TinyMCE image editor allows you to do this on the second tab (and even scales the image comparatively). This will need to be resolved eventually but server-side DOM editing is pretty limited for some obvious reasons.

Automatic Image Resize MODx

Installation

Use the script at your own risk. As stated it hasn’t been thoroughly tested yet (and has only been alive a few hours).

To install it

  • copy the source code (also available at the bottom of this page).
  • Log into the MODx Manager and navigate to Elements > Manage Elements.
  • Under “Manage Elements” click the Plugins tab and then click New Plugin.
  • Paste the code into the textarea under “Plugin code (php)”.
  • Give the plugin a name then click the System Events tab.
  • Tick the OnWebPagePrerender option and then save.
  • The plugin should be installed and active now.

Auto Resize Plugin Source

Feel free to use this how you please, edit it etc. Also feedback and suggestions are welcome.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
*	Auto Document Image Resizer (Resampler) for MODx
*	Retrives all document (page) images prior to rendering. 
*	If the image dimensions do not match it will resample a new image to fit the image attributes specified in the HTML.
*	This aims to prevent the pixelated and distorted output that large images heavily scaled result in.
*	It will also improve on load time.
 
*	Resampled images are cached in the /assets/cache/ directory.
*	Requires the PHP GD Graphics Library to process the images.
*
*	Version 0.2 - Test version - Quicky written and limited testing
*	Licensed under LGPL.
*
*	Author: Daniel Gibbs
*	Website: www.danielgibbs.net
*
*	Inspired by the Auto Image Resizer by Nathan Hill and Adam Crownoble. 
*	header('Content-type: image/jpeg');
*/
 
# ini_set('display_errors', '1');
# ini_set('error_reporting ', 'E_ALL | E_STRICT');
ini_set("memory_limit", "256M");
 
$quality = 100; 	// The image quality (0-100)
 
if($modx->Event->name == "OnWebPagePrerender") {
	$output = $modx->documentOutput;
	$dom = new DOMDocument();
	@$dom->loadHTML($output);
 
	$images = $dom->getElementsByTagName("img");
 
	foreach($images as $image) {
		// Get DOM attributes
		$width = $image->getAttribute("width");
		$height = $image->getAttribute("height");
		$style = $image->getAttribute("style");
		$source = $image->getAttribute("src");
 
		// File information
		$filename = basename($source);
		$fileinfo = pathinfo($source);
		$filetype = $fileinfo['extension'];
 
		$cachepath = $modx->config['base_path']."assets/cache/";
		$cachepath_url = $modx->config['base_url']."assets/cache/";
 
		// Find width and/or height from inline style
		if ($style) {
				preg_match("/width:(.*\w)px\;/", $style, $return);
				if($return[1]) $width = cleanValue($return[1]);
 
				preg_match("/height:(.*\w)px\;/", $style, $return);
				if($return[1]) $height = cleanValue($return[1]);
		}
 
		// Check the values valid (i.e. pixels not percentages) and move on
		if (is_numeric($width) && is_numeric($height) && !file_exists($cachepath.$filename)) {
			$path = $modx->config['base_path'].$source;
 
 			$fh = @fopen($path, "r");
 
			if ($fh !== false) {
				fclose($fh);
 
				// Get information on the original image 
				list($originalwidth, $originalheight) = getimagesize($path);
 
				// Check the images are different in size and doesn't already exist in the cache
				if ($originalwidth != $width || $originalheight != $height && !file_exists($cachepath.$filename)) {
						$imageprocess = imagecreatetruecolor($width, $height);
 
						switch (strtolower($filetype)) {
							case "jpg": $canvas = imagecreatefromjpeg($path); 
								break;
							case "jpeg": $canvas = imagecreatefromjpeg($path); 
								break;
							case "gif": $canvas = imagecreatefromgif($path); 
								break;
							case "png": $canvas = imagecreatefrompng($path); 
								break;
						}
 
						imagecopyresampled($imageprocess, $canvas, 0, 0, 0, 0, $width, $height, $originalwidth, $originalheight);
 
						// The output path
						$writepath = $cachepath.$filename;
 
						// Save new file
						switch (strtolower($filetype)) {
							case "jpg": imagejpeg($imageprocess, $writepath, $quality); 
								break;
							case "jpeg": imagejpeg($imageprocess, $writepath, $quality); 
								break;
							case "gif": imagegif($imageprocess, $writepath, $quality); 
								break;
							case "png": imagepng($imageprocess, $writepath, $quality); 
								break;
						}
 
						// Destroy the processed image
						imagedestroy($imageprocess);
 
 
						// Replace the src to the new image location
						$image->setAttribute("src", $cachepath_url.$filename);
					}
			}
		}
 
		// Image exists in cache, replace src attribute
        if (is_numeric($width) && is_numeric($height) && file_exists($cachepath.$filename)) {
        	$image->setAttribute("src", $cachepath_url.$filename);
		}
	}
 
	$modx->documentOutput = $dom->saveHTML();
}
 
function cleanValue($value) {
		$return = trim(str_replace("px", "", $value));
		return $return;
}
 
// FIN

Bookmark or share this page:

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

Related posts:

  1. MODx – Include Page Content Snippet
  2. Determing Login State (MODx)
  3. Changing MODx Managers Document Tree View Nodes
  4. Image Formats and Saving Images for Websites
  5. MODx – Wayfinder Incorrect Order (menu index)


MSN Contact: contact [at] danielgibbs.net



13 Comments

  1. Buddy 29 April 2010 5:27 am

    Thanks! I’ll be using this for sure, especially for template variables where clients will be uploading their own images.

  2. Gibbs 29 April 2010 11:31 am

    Just a quick update.

    The fclose on line 78 (older versions) shouldn’t be there. MODx will output an error if the file handle fails so remove it. The code and text file have been updated.

  3. Gibbs 5 May 2010 11:59 am

    Another update. The code and text file have been updated.

    I’ve rewritten parts to make it more logical and minimal in the hope I’ll put this out to the MODx community sometime soon. It still needs more testing and I’ll revisit how to improve and extend it shortly.

  4. Paul de Vries 25 May 2010 3:18 pm

    Thanks for the script! It helped me alot figuring out how the plugins works.
    However the DOMDocument modified my XHTML file to a HTML file so it wasn’t W3C valid anymore ( became )

  5. Gibbs 27 May 2010 5:54 pm

    Hi Paul,

    A user has contributed an XHTML class on the DOMDocument documentation over at http://php.net/manual/en/class.domdocument.php. That might help you out.

  6. Punch Rockgroin 24 June 2010 1:14 am

    Tried it out on Revolution, but got “Call to undefined function cleanvalue() on line 58″, even though examining code function references cleanValue. Not sure what that’s all about.

  7. Gibbs 24 June 2010 3:07 pm

    Hi Punch. Did you paste that error exactly? PHP is case sensitive so the V needs to be uppercase in cleanValue. I’ll have a play around later but in the meantime you could try moving the function up before the last closing parenthesis. Cheers

  8. Punch Rockgroin 24 June 2010 5:36 pm

    I left out the exact path to the plugin but it still registers as: “Fatal error: Call to undefined function cleanvalue() in {path}/core/cache/elements/modplugin/9.include.cache.php on line 63″ even after moving it up before the last parenthesis.

    I checked the case sensitivity for both the function and the call and they match.

  9. Punch Rockgroin 24 June 2010 5:38 pm

    No biggie though… With this as a starting point I rolled my own. I appreciate the head start!

  10. Gibbs 24 June 2010 8:02 pm

    Ah ok. It’s good to hear you’re up and running though. I’m still at a loss as to the function being undefined but your feedback is much appreciated.

  11. Gibbs 24 June 2010 8:05 pm

    I’ve just noticed that if you’re using PHP 5+ you might get an error like; imagepng() [function.imagepng]: gd-png: fatal libpng error: zlib error

    If that’s the case change the $quality var to use a scale of 0-9 instead of 0-100.

  12. Artem 18 January 2011 3:13 pm

    I want your plugin to save proportions of pics. Is it possible now?

  13. Alexey 2 March 2011 5:00 pm

    use DirectResize plugin

TrackBack URL

Leave a comment