Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Image Memory Fail - solution (sort of)


Go to End


715 Views

Avatar
JonShutt

Community Member, 244 Posts

29 May 2013 at 3:13pm

Hi,

I've always been very frustrated by the way SilverStripe dies quite catastrophically when someone uploads an image that is too 'big'.
I've had so many urgent calls from clients who've uploaded a large image, and can no longer access the admin area, and I have to search for any recently uploaded large image.

Limiting the upload size isn't really a solution, as the jpeg may be very compressed, but still have huge pixel dimensions - therefore require a lot of memory to resize.

So, the solution is to check pixel dimensions, and see if that's greater than the memory allocated to php.

The file in question is framework/filesystem/GD.php

I've added bit more into the "public function __construct($filename = null) " function:

public function __construct($filename = null) {
		// If we're working with image resampling, things could take a while.  Bump up the time-limit
		increase_time_limit_to(300);

		if($filename) {
			// We use getimagesize instead of extension checking, because sometimes extensions are wrong.
			list($width, $height, $type, $attr) = getimagesize($filename);
			
			$memoryRequired = $width * $height * 4; // 4 bytes per pixel
			$memoryAvailable = memory_get_usage();
			if ($memoryRequired > $memoryAvailable) {
				echo "<p>resizing <strong>". $filename. "</strong> requires more memory than is currently available. $memoryRequired / $memoryAvailable.</p>" ;
			} else {
			
				switch($type) {
					case 1: if(function_exists('imagecreatefromgif')) $this->setGD(imagecreatefromgif($filename)); break;
					case 2: if(function_exists('imagecreatefromjpeg')) $this->setGD(imagecreatefromjpeg($filename)); break;
					case 3: if(function_exists('imagecreatefrompng')) {
						$img = imagecreatefrompng($filename);
						imagesavealpha($img, true); // save alphablending setting (important)
						$this->setGD($img);
						break;
					}
				}
			}
		}
		
		$this->quality = self::$default_quality;
		parent::__construct();
	}

The problem now is that the warning looks really messy - and swapping between pages ends up with odd code scattered around.
But at least the admin area doesn't break, and the client can deal with the problem without have to urgently phone me up.

My next mission is to make this error warning feed back in to SilverStripe admin somewhere. Any ideas anyone?