dlueth
7/18/2013 - 8:06 AM

Assets for Qoopido.js shrinkimage showing how to convert images to .shrunk files via PHP and how to include it in your .htaccess

Assets for Qoopido.js shrinkimage showing how to convert images to .shrunk files via PHP and how to include it in your .htaccess

<?php
date_default_timezone_set('Europe/Berlin');
$base = dirname(__FILE__);

if(isset($_GET['file']) && !empty($_GET['file']) && isset($_GET['source']) && !empty($_GET['source'])) {
  $jsonp    = (isset($_GET['jsonp']) && !empty($_GET['jsonp'])) ? true : false;
	$callback = isset($_GET['callback']) && !empty($_GET['callback']) ? $_GET['callback'] : NULL;
	$quality  = (isset($_GET['quality']) && !empty($_GET['quality'])) ? (int) $_GET['quality'] : 80;

	if($jsonp === true && $callback === NULL) {
		throw new Exception('shrinkimage: Callback must be defined');
	}
	
	$targetJson = $base . '/' . $_GET['file'];
	$targetPath = dirname($targetJson);

	if(!is_file($targetJson)) {
		$json = NULL;

		$sourceFile = preg_replace('/^(\w+:\/\/' . preg_quote($_SERVER['HTTP_HOST'], '/') . '\/)/i', $_SERVER['DOCUMENT_ROOT'] . '/', $_GET['source']);
		$sourceName = basename($_GET['source']);

		if(is_file($sourceFile)) {
			if(!is_dir($targetPath)) {
				createDirectory($targetPath);
			}
			
			$colorCache = array(127 => rgb2color(0, 0, 0, 0));
			
			$size   = @getimagesize($sourceFile);
			$width  = $size[0];
			$height = $size[1];
			
			$imageSource = @imagecreatefrompng($sourceFile);
			$imageJpg    = @imagecreatetruecolor($width, $height);
			$imagePng    = @imagecreatetruecolor($width, $height);

			if(@imageistruecolor($imageSource) === false) {
				$imageTemp = @imagecreatetruecolor($width, $height);

				@imagecopy($imageTemp, $imageSource, 0, 0, 0, 0, $width, $height);
				@imagedestroy($imageSource);

				$imageSource = $imageTemp;
			}
			
			@imagealphablending($imageSource, false);
			@imagesavealpha($imageSource, true);
			@imagealphablending($imagePng, false);
			@imagesavealpha($imagePng, true);
				
			@imagefill($imageJpg, 0, 0, rgb2color(127, 127, 127));
			@imagefill($imagePng, 0, 0, $colorCache[127]);
			
			for($x = 0; $x < $width; $x++) {
				for($y = 0; $y < $height; $y++) {
					$color = color2rgb(imagecolorat($imageSource, $x, $y));
						
					if($color['a'] < 127) {
						imagesetpixel($imageJpg, $x, $y, rgb2color($color['r'], $color['g'], $color['b']));
						
						if(!isset($colorCache[$color['a']])) {
							$colorCache[$color['a']] = rgb2color(0, 0, 0, 127 - $color['a']); 
						}
						
						imagesetpixel($imagePng, $x, $y, $colorCache[$color['a']]);
					}
				}
			}
			
			$imageJpg = getImage($imageJpg, 'jpeg', true, $quality);
			$imagePng = getImage($imagePng, 'png', false, 9, PNG_ALL_FILTERS);
			
			$json         = new stdClass();
			$json->size   = @filesize($sourceFile);
			$json->width  = $width;
			$json->height = $height;
			$json->main   = 'data:image/jpeg;base64,' . base64_encode($imageJpg);
			$json->alpha  = 'data:image/png;base64,' . base64_encode($imagePng);
			
			$json = json_encode($json);
			
			@file_put_contents($targetJson, $json, LOCK_EX);
		} else {
			throw new Exception('shrinkimage: Source file "' . $_GET['source'] . '" does not exist');
		}

		$etag = md5_file($targetJson);

		header('ETag: ' . $etag, true);
		header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime($targetJson)) . ' GMT', true, 200);
		header('Vary: Accept, Cache-Control', true);
		header('Cache-control: public, must-revalidate, proxy-revalidate', true);

		switch($jsonp) {
			case true:
				$json = $callback . '(' . $json . ');';
				header('Content-Length: ' . strlen($json));
				header('Content-type: application/javascript');
				echo $json;
				die();
				break;
			default:
				header('Content-Length: ' . strlen($json));
				header('Content-type: application/json');
				echo $json;
				die();
				break;
		}
	} else {
		$headers  = apache_request_headers(); 
		$modified = @filemtime($targetJson);
		$etag     = md5_file($targetJson);

		if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag) {
			header('HTTP/1.1 304 Not Modified', true);
			die();
		}

		if(isset($headers['HTTP_IF_MODIFIED_SINCE']) && (strtotime($headers['HTTP_IF_MODIFIED_SINCE']) >= $modified)) {
			header('HTTP/1.1 304 Not Modified', true);
			die();
		}

		$json = file_get_contents($targetJson);

		header('ETag: ' . $etag, true);
		header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $modified) . ' GMT', true, 200);
		header('Vary: Accept, Cache-Control', true);
		header('Cache-control: public, must-revalidate, proxy-revalidate', true);

		switch($jsonp) {
			case true:
				$json = $callback . '(' . $json . ');';
				header('Content-Length: ' . strlen($json));
				header('Content-type: application/javascript');
				echo $json;
				die();
				break;
			default:
				header('Content-Length: ' . strlen($json));
				header('Content-type: application/json');
				echo $json;
				die();
				break;
		}
	}
}

function rgb2color($r, $g, $b, $a = 0) {
	return ($r << 16) + ($g << 8) + $b + ($a << 24);
}

function color2rgb($color) {
	$return = null;
	
	if(preg_match('/^\d+$/', $color)) {
		$return = array(
			'r' => ($color >> 16) & 0xFF,
			'g' => ($color >> 8) & 0xFF,
			'b' => $color & 0xFF,
			'a' => ($color & 0x7F000000) >> 24,
		);
	}
	
	return $return;
}

function getImage($resource, $type = 'png', $interlace = false, $quality = NULL, $filter = 248) {
	if($interlace === true) {
		@imageinterlace($resource, 1);
	}

	ob_start();
	
	switch($type) {
		case 'png':
			$quality = ($quality === NULL) ? 9 : max(0, min(9, (int) $quality));
			
			@imagepng($resource, NULL, $quality, $filter);
			break;
		case 'jpeg':
			$quality = ($quality === NULL) ? 100 : max(0, min(100, (int) $quality));
			
			@imagejpeg($resource, NULL, $quality);
			break;
	}
		
	return trim(ob_get_clean());
}

function createDirectory($directory) {
	$return = false;

	try {
		$return = @mkdir($directory, 0750, true);
	} catch(Exception $exception) {
		throw new Exception('shrinkimage: Error creating directory "' . $directory . '"');
	}

	return $return;
}

die();
?>
AddType application/json .shrunk
AddType application/javascript .shrunk.jsonp

<IfModule mod_rewrite.c>
  RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.+.q(?:[0-9]+).shrunk)$ shrinkimage.php?file=$1 [QSA,L]
    RewriteRule ^(.+.q(?:[0-9]+).shrunk.jsonp)$ shrinkimage.php?file=$1&jsonp=1 [QSA,L]
</IfModule>

<Ifmodule mod_deflate.c>
	AddOutputFilterByType DEFLATE application/json application/javascript
</IfModule>