1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-08-19 14:21:35 +02:00

prepare to tag v0.5

This commit is contained in:
Mikael Roos
2014-02-12 14:45:25 +01:00
parent 7478b12751
commit 20a621bf48
22 changed files with 1916 additions and 1286 deletions

431
webroot/img.php Normal file
View File

@@ -0,0 +1,431 @@
<?php
/**
* Resize images on the fly using CImage, configuration is made in file named.
*
*/
/**
* Default configuration options, can be overridden in own config-file.
*
* @param string $msg to display.
*
* @return void
*/
function errorPage($msg)
{
header("Status: 404 Not Found");
die('img.php say 404: ' . $msg);
}
/**
* Custom exception handler.
*/
set_exception_handler(function($exception) {
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
});
/**
* Get input from query string or return default value if not set.
*
* @param mixed $key as string or array of string values to look for in $_GET.
* @param mixed $default value to return when $key is not set in $_GET.
*
* @return mixed value from $_GET or default value.
*/
function get($key, $default = null)
{
if (is_array($key)) {
foreach ($key as $val) {
if (isset($_GET[$val])) {
return $_GET[$val];
}
}
} elseif (isset($_GET[$key])) {
return $_GET[$key];
}
return $default;
}
/**
* Get input from query string and set to $defined if defined or else $undefined.
*
* @param mixed $key as string or array of string values to look for in $_GET.
* @param mixed $defined value to return when $key is set in $_GET.
* @param mixed $undefined value to return when $key is not set in $_GET.
*
* @return mixed value as $defined or $undefined.
*/
function getDefined($key, $defined, $undefined)
{
return get($key) === null ? $undefined : $defined;
}
/**
* Log when verbose mode, when used without argument it returns the result.
*
* @param string $msg to log.
*
* @return void or array.
*/
function verbose($msg = null)
{
global $verbose;
static $log = array();
if (!$verbose) {
return;
}
if (is_null($msg)) {
return $log;
}
$log[] = $msg;
}
/**
* Default configuration options, can be overridden in own config-file.
*/
$config = array(
);
$configFile = __DIR__.'/'.basename(__FILE__, '.php').'_config.php';
$config = array_merge($config, require $configFile);
call_user_func($config['error_reporting']);
/**
* verbose, v - do a verbose dump of what happens
*/
$verbose = getDefined(array('verbose', 'v'), true, false);
/**
* src - the source image file.
*/
$srcImage = get('src')
or errorPage('Must set src-attribute.');
preg_match('#^[a-z0-9A-Z-/_\.]+$#', $srcImage)
or errorPage('Filename contains invalid characters.');
verbose("src = $srcImage");
/**
* width, w - set target width, affecting the resulting image width, height and resize options
*/
$newWidth = get(array('width', 'w'));
// Check to replace predefined size
$sizes = call_user_func($config['size_constant']);
if (isset($sizes[$newWidth])) {
$newWidth = $sizes[$newWidth];
}
// Support width as % of original width
if ($newWidth[strlen($newWidth)-1] == '%') {
is_numeric(substr($newWidth, 0, -1))
or errorPage('Width % not numeric.');
} else {
is_null($newWidth)
or ($newWidth > 10 && $newWidth <= $config['max_width'])
or errorPage('Width out of range.');
}
verbose("new width = $newWidth");
/**
* height, h - set target height, affecting the resulting image width, height and resize options
*/
$newHeight = get(array('height', 'h'));
// Check to replace predefined size
if (isset($sizes[$newHeight])) {
$newHeight = $sizes[$newHeight];
}
// height
if ($newHeight[strlen($newHeight)-1] == '%') {
is_numeric(substr($newHeight, 0, -1))
or errorPage('Height % out of range.');
} else {
is_null($newHeight)
or ($newHeight > 10 && $newHeight <= $config['max_height'])
or errorPage('Hight out of range.');
}
verbose("new height = $newHeight");
/**
* aspect-ratio, ar - affecting the resulting image width, height and resize options
*/
$aspectRatio = get(array('aspect-ratio', 'ar'));
// Check to replace predefined aspect ratio
$aspectRatios = call_user_func($config['aspect_ratio_constant']);
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
if (isset($aspectRatios[$aspectRatio])) {
$aspectRatio = $aspectRatios[$aspectRatio];
}
if ($negateAspectRatio) {
$aspectRatio = 1 / $aspectRatio;
}
is_null($aspectRatio)
or is_numeric($aspectRatio)
or errorPage('Aspect ratio out of range');
verbose("aspect ratio = $aspectRatio");
/**
* crop-to-fit, cf - affecting the resulting image width, height and resize options
*/
$cropToFit = getDefined(array('crop-to-fit', 'cf'), true, false);
verbose("crop to fit = $cropToFit");
/**
* no-ratio, nr, stretch - affecting the resulting image width, height and resize options
*/
$keepRatio = getDefined(array('no-ratio', 'nr', 'stretch'), false, true);
verbose("keep ratio = $keepRatio");
/**
* crop, c - affecting the resulting image width, height and resize options
*/
$crop = get(array('crop', 'c'));
verbose("crop = $crop");
/**
* area, a - affecting the resulting image width, height and resize options
*/
$area = get(array('area', 'a'));
verbose("area = $area");
/**
* skip-original, so - skip the original image and always process a new image
*/
$useOriginal = getDefined(array('save-as', 'sa'), false, true);
verbose("use original = $useOriginal");
/**
* no-cache, nc - skip the cached version and process and create a new version in cache.
*/
$useCache = getDefined(array('no-cache', 'nc'), false, true);
verbose("use cache = $useCache");
/**
* quality, q - set level of quality for jpeg images
*/
$quality = get(array('quality', 'q'));
is_null($quality)
or ($quality > 0 and $quality <= 100)
or errorPage('Quality out of range');
verbose("quality = $quality");
/**
* compress, co - what strategy to use when compressing png images
*/
$compress = get(array('compress', 'co'));
is_null($compress)
or ($compress > 0 and $compress <= 9)
or errorPage('Compress out of range');
verbose("compress = $compress");
/**
* save-as, sa - what type of image to save
*/
$saveAs = get(array('save-as', 'sa'));
verbose("save as = $saveAs");
/**
* scale, s - Processing option, scale up or down the image prior actual resize
*/
$scale = get(array('scale', 's'));
is_null($scale)
or ($scale >= 0 and $quality <= 400)
or errorPage('Scale out of range');
verbose("scale = $scale");
/**
* palette, p - Processing option, create a palette version of the image
*/
$palette = getDefined(array('palette', 'p'), true, false);
verbose("palette = $palette");
/**
* sharpen - Processing option, post filter for sharpen effect
*/
$sharpen = getDefined('sharpen', true, null);
verbose("sharpen = $sharpen");
/**
* emboss - Processing option, post filter for emboss effect
*/
$emboss = getDefined('emboss', true, null);
verbose("emboss = $emboss");
/**
* blur - Processing option, post filter for blur effect
*/
$blur = getDefined('blur', true, null);
verbose("blur = $blur");
/**
* filter, f, f0-f9 - Processing option, post filter for various effects using imagefilter()
*/
$filters = array();
$filter = get(array('filter', 'f'));
if ($filter) {
$filters[] = $filter;
}
for ($i = 0; $i < 10; $i++) {
$filter = get(array("filter{$i}", "f{$i}"));
if ($filter) {
$filters[] = $filter;
}
}
verbose("filters = " . print_r($filters, 1));
/**
* Display image if verbose mode
*/
if ($verbose) {
$query = array();
parse_str($_SERVER['QUERY_STRING'], $query);
unset($query['verbose']);
unset($query['v']);
unset($query['nocache']);
unset($query['nc']);
$url1 = '?' . http_build_query($query);
$log = htmlentities(print_r(verbose(), 1));
echo <<<EOD
<a href=$url1><code>$url1</code></a><br>
<img src='{$url1}' />
<pre>$log</pre>
EOD;
}
/**
* Create and output the image
*/
require $config['cimage_class'];
$img = new CImage();
$img->setVerbose($verbose)
->setSource($srcImage, $config['image_path'])
->setOptions(
array(
// Options for calculate dimensions
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'aspectRatio' => $aspectRatio,
'keepRatio' => $keepRatio,
'cropToFit' => $cropToFit,
'crop' => $crop,
'area' => $area,
// Pre-processing, before resizing is done
'scale' => $scale,
// Post-processing, after resizing is done
'palette' => $palette,
'filters' => $filters,
'sharpen' => $sharpen,
'emboss' => $emboss,
'blur' => $blur,
)
)
->initDimensions()
->calculateNewWidthAndHeight()
->setSaveAsExtension($saveAs)
->setJpegQuality($quality)
->setPngCompression($compress)
->useOriginalIfPossible($useOriginal)
->generateFilename($config['cache_path'])
->useCacheIfPossible($useCache)
->load()
->preResize()
->resize()
->postResize()
->setPostProcessingOptions($config['postprocessing'])
->save()
->output();

BIN
webroot/img/ball24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
webroot/img/ball8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
webroot/img/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
webroot/img/higher.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

BIN
webroot/img/kodim04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

BIN
webroot/img/kodim07.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

BIN
webroot/img/kodim08.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 KiB

BIN
webroot/img/kodim13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 KiB

BIN
webroot/img/kodim15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

BIN
webroot/img/kodim22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB

BIN
webroot/img/kodim23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

BIN
webroot/img/kodim24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 KiB

BIN
webroot/img/round24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
webroot/img/round8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
webroot/img/wider.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

98
webroot/img_config.php Normal file
View File

@@ -0,0 +1,98 @@
<?php
/**
* Configuration for img.php, name the config file the same as your img.php and
* append _config. If you are testing out some in imgtest.php then label that
* config-file imgtest_config.php.
*
*/
return array(
/**
* Paths, where are all the stuff I should use?
* Append ending slash on directories.
*/
'cimage_class' => __DIR__.'/../CImage.php',
'image_path' => __DIR__.'/img/',
'cache_path' => __DIR__.'/../cache/',
/**
* Max image dimensions,
*
*/
'max_width' => 2000,
'max_height' => 2000,
/**
* Post processing of images using external tools, set to true or false
* and set command to be executed.
*/
'postprocessing' => array(
'png_filter' => false,
'png_filter_cmd' => '/usr/local/bin/optipng -q',
'png_deflate' => false,
'png_deflate_cmd' => '/usr/local/bin/pngout -q',
'jpeg_optimize' => false,
'jpeg_optimize_cmd' => '/usr/local/bin/jpegtran -copy none -optimize',
),
/**
* Predefined size constants.
*
*/
'size_constant' => function() {
// Set sizes to map constant to value, easier to use with width or height
$sizes = array(
'w1' => 613,
'w2' => 630,
);
// Add column width to $area, useful for use as predefined size for width (or height).
$gridColumnWidth = 30;
$gridGutterWidth = 10;
$gridColumns = 24;
for ($i = 1; $i <= $gridColumns; $i++) {
$sizes['c' . $i] = ($gridColumnWidth + $gridGutterWidth) * $i - $gridGutterWidth;
}
return $sizes;
},
/**
* Predefined aspect ratios.
*
*/
'aspect_ratio_constant' => function() {
return array(
'3:1' => 3/1,
'3:2' => 3/2,
'4:3' => 4/3,
'8:5' => 8/5,
'16:10' => 16/10,
'16:9' => 16/9,
'golden' => 1.618,
);
},
/**
* Set error reporting to match development or production environment
*/
'error_reporting' => function() {
error_reporting(-1);
set_time_limit(20);
},
);

92
webroot/test.php Normal file
View File

@@ -0,0 +1,92 @@
<!doctype html>
<head>
<meta charset='utf-8'/>
<title>Testing img resizing using CImage.php</title>
</head>
<body>
<h1>Testing <code>CImage.php</code> through <code>img.php</code></h1>
<p>You can test any variation of resizing the images through <a href='img.php?src=wider.jpg&amp;w=200&amp;h=200'>img.php?src=wider.jpg&amp;w=200&amp;h=200</a> or <a href='img.php?src=higher.jpg&amp;w=200&amp;h=200'>img.php?src=higher.jpg&amp;w=200&amp;h=200</a></p>
<p>Supported arguments throught the querystring are:</p>
<ul>
<li>h, height: h=200 sets the new height to max 200px.
<li>w, width: w=200 sets the new width to max 200px.
<li>crop-to-fit: set together with both h & w to make the image fit in the box and crop out the rest.
<li>no-ratio: do not keep aspect ratio.
<li>crop: crops an area from the original image, set width, height, start_x and start_y to define the area to crop, for example crop=100,100,10,10.
<li>q, quality: q=70 or quality=70 sets the image quality as value between 0 and 100, default is full quality/100.
<li>f, filter: apply filter to image, f=colorize,0,255,0,0 makes image greener. Supports all filters as defined in <a href='http://php.net/manual/en/function.imagefilter.php'><code>imagefilter()</code></a>
<li>f0-f9: same as f/filter, just add more filters. Applied in order f, f0-f9.
</ul>
<p>Supports <code>.jpg</code>, <code>.png</code> and <code>.gif</code>.</p>
<p>Sourcecode and issues on github: <a href='https://github.com/mosbth/cimage'>https://github.com/mosbth/cimage</a></p>
<p>Copyright 2012, Mikael Roos (mos@dbwebb.se)</p>
<h2>Testcases</h2>
<?php
$testcase = array(
array('text'=>'Original image', 'query'=>''),
array('text'=>'Crop out a rectangle of 100x100, start by position 200x200.', 'query'=>'&crop=100,100,200,200'),
array('text'=>'Crop out a full width rectangle with height of 200, start by position 0x100.', 'query'=>'&crop=0,200,0,100'),
array('text'=>'Max width 200.', 'query'=>'&w=200'),
array('text'=>'Max height 200.', 'query'=>'&h=200'),
array('text'=>'Max width 200 and max height 200.', 'query'=>'&w=200&h=200'),
array('text'=>'No-ratio makes image fit in area of width 200 and height 200.', 'query'=>'&w=200&h=200&no-ratio'),
array('text'=>'Crop to fit in width 200 and height 200.', 'query'=>'&w=200&h=200&crop-to-fit'),
array('text'=>'Crop to fit in width 200 and height 100.', 'query'=>'&w=200&h=100&crop-to-fit'),
array('text'=>'Crop to fit in width 100 and height 200.', 'query'=>'&w=100&h=200&crop-to-fit'),
array('text'=>'Quality 70', 'query'=>'&w=200&h=200&quality=70'),
array('text'=>'Quality 40', 'query'=>'&w=200&h=200&quality=40'),
array('text'=>'Quality 10', 'query'=>'&w=200&h=200&quality=10'),
array('text'=>'Filter: Negate', 'query'=>'&w=200&h=200&f=negate'),
array('text'=>'Filter: Grayscale', 'query'=>'&w=200&h=200&f=grayscale'),
array('text'=>'Filter: Brightness 90', 'query'=>'&w=200&h=200&f=brightness,90'),
array('text'=>'Filter: Contrast 50', 'query'=>'&w=200&h=200&f=contrast,50'),
array('text'=>'Filter: Colorize 0,255,0,0', 'query'=>'&w=200&h=200&f=colorize,0,255,0,0'),
array('text'=>'Filter: Edge detect', 'query'=>'&w=200&h=200&f=edgedetect'),
array('text'=>'Filter: Emboss', 'query'=>'&w=200&h=200&f=emboss'),
array('text'=>'Filter: Gaussian blur', 'query'=>'&w=200&h=200&f=gaussian_blur'),
array('text'=>'Filter: Selective blur', 'query'=>'&w=200&h=200&f=selective_blur'),
array('text'=>'Filter: Mean removal', 'query'=>'&w=200&h=200&f=mean_removal'),
array('text'=>'Filter: Smooth 2', 'query'=>'&w=200&h=200&f=smooth,2'),
array('text'=>'Filter: Pixelate 10,10', 'query'=>'&w=200&h=200&f=pixelate,10,10'),
array('text'=>'Multiple filter: Negate, Grayscale and Pixelate 10,10', 'query'=>'&w=200&h=200&&f=negate&f0=grayscale&f1=pixelate,10,10'),
array('text'=>'Crop with width & height and crop-to-fit with quality and filter', 'query'=>'&crop=100,100,100,100&w=200&h=200&crop-to-fit&q=70&f0=grayscale'),
);
?>
<h3>Test case with image <code>wider.jpg</code></h3>
<table>
<caption>Test case with image <code>wider.jpg</code></caption>
<thead><tr><th>Testcase:</th><th>Result:</th></tr></thead>
<tbody>
<?php
foreach($testcase as $key => $val) {
$url = "img.php?src=wider.jpg{$val['query']}";
echo "<tr><td id=w$key><a href=#w$key>$key</a></br>{$val['text']}</br><code><a href='$url'>".htmlentities($url)."</a></code></td><td><img src='$url' /></td></tr>";
}
?>
</tbody>
</table>
<h3>Test case with image <code>higher.jpg</code></h3>
<table>
<caption>Test case with image <code>higher.jpg</code></caption>
<thead><tr><th>Testcase:</th><th>Result:</th></tr></thead>
<tbody>
<?php
foreach($testcase as $key => $val) {
$url = "img.php?src=higher.jpg{$val['query']}";
echo "<tr><td id=h$key><a href=#h$key>$key</a></br>{$val['text']}</br><code><a href='$url'>".htmlentities($url)."</a></code></td><td><img src='$url' /></td></tr>";
}
?>
</tbody>
</table>
</body>
</html>