Created
July 18, 2013 08:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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