Skip to content

Instantly share code, notes, and snippets.

@dlueth
Created July 18, 2013 08:06
Show Gist options
  • Save dlueth/6027586 to your computer and use it in GitHub Desktop.
Save dlueth/6027586 to your computer and use it in GitHub Desktop.
Assets for Qoopido.js shrinkimage showing how to convert images to .shrunk files via PHP and how to include it in your .htaccess
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>
<?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();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment