1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-01-17 11:08:14 +01:00
2020-01-15 16:51:39 +01:00

1198 lines
30 KiB
PHP

<?php
/**
* Resize and crop images on the fly, store generated images in a cache.
*
* @author Mikael Roos mos@dbwebb.se
* @example http://dbwebb.se/opensource/cimage
* @link https://github.com/mosbth/cimage
*
*/
/**
* Custom exception handler.
*/
set_exception_handler(function ($exception) {
errorPage(
"<p><b>img.php: Uncaught exception:</b> <p>"
. $exception->getMessage()
. "</p><pre>"
. $exception->getTraceAsString()
. "</pre>",
500
);
});
/**
* Get configuration options from file, if the file exists, else use $config
* if its defined or create an empty $config.
*/
$configFile = __DIR__.'/'.basename(__FILE__, '.php').'_config.php';
if (is_file($configFile)) {
$config = require $configFile;
} elseif (!isset($config)) {
$config = array();
}
// Make CIMAGE_DEBUG false by default, if not already defined
if (!defined("CIMAGE_DEBUG")) {
define("CIMAGE_DEBUG", false);
}
/**
* Setup the autoloader, but not when using a bundle.
*/
if (!defined("CIMAGE_BUNDLE")) {
if (!isset($config["autoloader"])) {
die("CImage: Missing autoloader.");
}
require $config["autoloader"];
}
/**
* verbose, v - do a verbose dump of what happens
* vf - do verbose dump to file
*/
$verbose = getDefined(array('verbose', 'v'), true, false);
$verboseFile = getDefined('vf', true, false);
verbose("img.php version = " . CIMAGE_VERSION);
/**
* status - do a verbose dump of the configuration
*/
$status = getDefined('status', true, false);
/**
* Set mode as strict, production or development.
* Default is production environment.
*/
$mode = getConfig('mode', 'production');
// Settings for any mode
set_time_limit(20);
ini_set('gd.jpeg_ignore_warning', 1);
if (!extension_loaded('gd')) {
errorPage("Extension gd is not loaded.", 500);
}
// Specific settings for each mode
if ($mode == 'strict') {
error_reporting(0);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
$verbose = false;
$status = false;
$verboseFile = false;
} elseif ($mode == 'production') {
error_reporting(-1);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
$verbose = false;
$status = false;
$verboseFile = false;
} elseif ($mode == 'development') {
error_reporting(-1);
ini_set('display_errors', 1);
ini_set('log_errors', 0);
$verboseFile = false;
} elseif ($mode == 'test') {
error_reporting(-1);
ini_set('display_errors', 1);
ini_set('log_errors', 0);
} else {
errorPage("Unknown mode: $mode", 500);
}
verbose("mode = $mode");
verbose("error log = " . ini_get('error_log'));
/**
* Set default timezone if not set or if its set in the config-file.
*/
$defaultTimezone = getConfig('default_timezone', null);
if ($defaultTimezone) {
date_default_timezone_set($defaultTimezone);
} elseif (!ini_get('default_timezone')) {
date_default_timezone_set('UTC');
}
/**
* Check if passwords are configured, used and match.
* Options decide themself if they require passwords to be used.
*/
$pwdConfig = getConfig('password', false);
$pwdAlways = getConfig('password_always', false);
$pwdType = getConfig('password_type', 'text');
$pwd = get(array('password', 'pwd'), null);
// Check if passwords match, if configured to use passwords
$passwordMatch = null;
if ($pwd) {
switch ($pwdType) {
case 'md5':
$passwordMatch = ($pwdConfig === md5($pwd));
break;
case 'hash':
$passwordMatch = password_verify($pwd, $pwdConfig);
break;
case 'text':
$passwordMatch = ($pwdConfig === $pwd);
break;
default:
$passwordMatch = false;
}
}
if ($pwdAlways && $passwordMatch !== true) {
errorPage("Password required and does not match or exists.", 403);
}
verbose("password match = $passwordMatch");
/**
* Prevent hotlinking, leeching, of images by controlling who access them
* from where.
*
*/
$allowHotlinking = getConfig('allow_hotlinking', true);
$hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
$refererHost = parse_url($referer, PHP_URL_HOST);
if (!$allowHotlinking) {
if ($passwordMatch) {
; // Always allow when password match
verbose("Hotlinking since passwordmatch");
} elseif ($passwordMatch === false) {
errorPage("Hotlinking/leeching not allowed when password missmatch.", 403);
} elseif (!$referer) {
errorPage("Hotlinking/leeching not allowed and referer is missing.", 403);
} elseif (strcmp($serverName, $refererHost) == 0) {
; // Allow when serverName matches refererHost
verbose("Hotlinking disallowed but serverName matches refererHost.");
} elseif (!empty($hotlinkingWhitelist)) {
$whitelist = new CWhitelist();
$allowedByWhitelist = $whitelist->check($refererHost, $hotlinkingWhitelist);
if ($allowedByWhitelist) {
verbose("Hotlinking/leeching allowed by whitelist.");
} else {
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.", 403);
}
} else {
errorPage("Hotlinking/leeching not allowed.", 403);
}
}
verbose("allow_hotlinking = $allowHotlinking");
verbose("referer = $referer");
verbose("referer host = $refererHost");
/**
* Create the class for the image.
*/
$CImage = getConfig('CImage', 'CImage');
$img = new $CImage();
$img->setVerbose($verbose || $verboseFile);
/**
* Get the cachepath from config.
*/
$CCache = getConfig('CCache', 'CCache');
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
$cache = new $CCache();
$cache->setDir($cachePath);
/**
* 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");
/**
* Prepare fast track cache for swriting cache items.
*/
$fastTrackCache = "fasttrack";
$allowFastTrackCache = getConfig('fast_track_allow', false);
$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache');
$ftc = new $CFastTrackCache();
$ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache))
->enable($allowFastTrackCache)
->setFilename(array('no-cache', 'nc'));
$img->injectDependency("fastTrackCache", $ftc);
/**
* Load and output images from fast track cache, if items are available
* in cache.
*/
if ($useCache && $allowFastTrackCache) {
if (CIMAGE_DEBUG) {
trace("img.php fast track cache enabled and used");
}
$ftc->output();
}
/**
* Allow or disallow remote download of images from other servers.
* Passwords apply if used.
*
*/
$allowRemote = getConfig('remote_allow', false);
if ($allowRemote && $passwordMatch !== false) {
$cacheRemote = $cache->getPathToSubdir("remote");
$pattern = getConfig('remote_pattern', null);
$img->setRemoteDownload($allowRemote, $cacheRemote, $pattern);
$whitelist = getConfig('remote_whitelist', null);
$img->setRemoteHostWhitelist($whitelist);
}
/**
* shortcut, sc - extend arguments with a constant value, defined
* in config-file.
*/
$shortcut = get(array('shortcut', 'sc'), null);
$shortcutConfig = getConfig('shortcut', array(
'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
));
verbose("shortcut = $shortcut");
if (isset($shortcut)
&& isset($shortcutConfig[$shortcut])) {
parse_str($shortcutConfig[$shortcut], $get);
verbose("shortcut-constant = {$shortcutConfig[$shortcut]}");
$_GET = array_merge($_GET, $get);
}
/**
* src - the source image file.
*/
$srcImage = urldecode(get('src'))
or errorPage('Must set src-attribute.', 404);
// Get settings for src-alt as backup image
$srcAltImage = urldecode(get('src-alt', null));
$srcAltConfig = getConfig('src_alt', null);
if (empty($srcAltImage)) {
$srcAltImage = $srcAltConfig;
}
// Check for valid/invalid characters
$imagePath = getConfig('image_path', __DIR__ . '/img/');
$imagePathConstraint = getConfig('image_path_constraint', true);
$validFilename = getConfig('valid_filename', '#^[a-z0-9A-Z-/_ \.:]+$#');
// Source is remote
$remoteSource = false;
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Source filename contains invalid characters.', 404);
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
$remoteSource = true;
} else {
// Check if file exists on disk or try using src-alt
$pathToImage = realpath($imagePath . $srcImage);
if (!is_file($pathToImage) && !empty($srcAltImage)) {
// Try using the src-alt instead
$srcImage = $srcAltImage;
$pathToImage = realpath($imagePath . $srcImage);
preg_match($validFilename, $srcImage)
or errorPage('Source (alt) filename contains invalid characters.', 404);
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Check if src-alt is the dummy image
$dummyImage = true;
}
}
if (!$dummyImage) {
is_file($pathToImage)
or errorPage(
'Source image is not a valid file, check the filename and that a
matching file exists on the filesystem.',
404
);
}
}
if ($imagePathConstraint && !$dummyImage && !$remoteSource) {
// Check that the image is a file below the directory 'image_path'.
$imageDir = realpath($imagePath);
substr_compare($imageDir, $pathToImage, 0, strlen($imageDir)) == 0
or errorPage(
'Security constraint: Source image is not below the directory "image_path"
as specified in the config file img_config.php.',
404
);
}
verbose("src = $srcImage");
/**
* Manage size constants from config file, use constants to replace values
* for width and height.
*/
$sizeConstant = getConfig('size_constant', function () {
// Set sizes to map constant to value, easier to use with width or height
$sizes = array(
'w1' => 613,
'w2' => 630,
);
// Add grid column width, 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;
});
$sizes = call_user_func($sizeConstant);
/**
* width, w - set target width, affecting the resulting image width, height and resize options
*/
$newWidth = get(array('width', 'w'));
$maxWidth = getConfig('max_width', 2000);
// Check to replace predefined size
if (isset($sizes[$newWidth])) {
$newWidth = $sizes[$newWidth];
}
// Support width as % of original width
if ($newWidth && $newWidth[strlen($newWidth)-1] == '%') {
is_numeric(substr($newWidth, 0, -1))
or errorPage('Width % not numeric.', 404);
} else {
is_null($newWidth)
or ($newWidth > 10 && $newWidth <= $maxWidth)
or errorPage('Width out of range.', 404);
}
verbose("new width = $newWidth");
/**
* height, h - set target height, affecting the resulting image width, height and resize options
*/
$newHeight = get(array('height', 'h'));
$maxHeight = getConfig('max_height', 2000);
// Check to replace predefined size
if (isset($sizes[$newHeight])) {
$newHeight = $sizes[$newHeight];
}
// height
if ($newHeight && $newHeight[strlen($newHeight)-1] == '%') {
is_numeric(substr($newHeight, 0, -1))
or errorPage('Height % out of range.', 404);
} else {
is_null($newHeight)
or ($newHeight > 10 && $newHeight <= $maxHeight)
or errorPage('Height out of range.', 404);
}
verbose("new height = $newHeight");
/**
* aspect-ratio, ar - affecting the resulting image width, height and resize options
*/
$aspectRatio = get(array('aspect-ratio', 'ar'));
$aspectRatioConstant = getConfig('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,
);
});
// Check to replace predefined aspect ratio
$aspectRatios = call_user_func($aspectRatioConstant);
$negateAspectRatio = ($aspectRatio && $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', 404);
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");
/**
* Set default background color from config file.
*/
$backgroundColor = getConfig('background_color', null);
if ($backgroundColor) {
$img->setDefaultBackgroundColor($backgroundColor);
verbose("Using default background_color = $backgroundColor");
}
/**
* bgColor - Default background color to use
*/
$bgColor = get(array('bgColor', 'bg-color', 'bgc'), null);
verbose("bgColor = $bgColor");
/**
* Do or do not resample image when resizing.
*/
$resizeStrategy = getDefined(array('no-resample'), true, false);
if ($resizeStrategy) {
$img->setCopyResizeStrategy($img::RESIZE);
verbose("Setting = Resize instead of resample");
}
/**
* fill-to-fit, ff - affecting the resulting image width, height and resize options
*/
$fillToFit = get(array('fill-to-fit', 'ff'), null);
verbose("fill-to-fit = $fillToFit");
if ($fillToFit !== null) {
if (!empty($fillToFit)) {
$bgColor = $fillToFit;
verbose("fillToFit changed bgColor to = $bgColor");
}
$fillToFit = true;
verbose("fill-to-fit (fixed) = $fillToFit");
}
/**
* 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('skip-original', 'so'), false, true);
$useOriginalDefault = getConfig('skip_original', false);
if ($useOriginalDefault === true) {
verbose("skip original is default ON");
$useOriginal = false;
}
verbose("use original = $useOriginal");
/**
* quality, q - set level of quality for jpeg images
*/
$quality = get(array('quality', 'q'));
$qualityDefault = getConfig('jpg_quality', null);
is_null($quality)
or ($quality > 0 and $quality <= 100)
or errorPage('Quality out of range', 404);
if (is_null($quality) && !is_null($qualityDefault)) {
$quality = $qualityDefault;
}
verbose("quality = $quality");
/**
* compress, co - what strategy to use when compressing png images
*/
$compress = get(array('compress', 'co'));
$compressDefault = getConfig('png_compression', null);
is_null($compress)
or ($compress > 0 and $compress <= 9)
or errorPage('Compress out of range', 404);
if (is_null($compress) && !is_null($compressDefault)) {
$compress = $compressDefault;
}
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 $scale <= 400)
or errorPage('Scale out of range', 404);
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");
/**
* rotateBefore - Rotate the image with an angle, before processing
*/
$rotateBefore = get(array('rotateBefore', 'rotate-before', 'rb'));
is_null($rotateBefore)
or ($rotateBefore >= -360 and $rotateBefore <= 360)
or errorPage('RotateBefore out of range', 404);
verbose("rotateBefore = $rotateBefore");
/**
* rotateAfter - Rotate the image with an angle, before processing
*/
$rotateAfter = get(array('rotateAfter', 'rotate-after', 'ra', 'rotate', 'r'));
is_null($rotateAfter)
or ($rotateAfter >= -360 and $rotateAfter <= 360)
or errorPage('RotateBefore out of range', 404);
verbose("rotateAfter = $rotateAfter");
/**
* autoRotate - Auto rotate based on EXIF information
*/
$autoRotate = getDefined(array('autoRotate', 'auto-rotate', 'aro'), true, false);
verbose("autoRotate = $autoRotate");
/**
* 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));
/**
* json - output the image as a JSON object with details on the image.
* ascii - output the image as ASCII art.
*/
$outputFormat = getDefined('json', 'json', null);
$outputFormat = getDefined('ascii', 'ascii', $outputFormat);
verbose("outputformat = $outputFormat");
if ($outputFormat == 'ascii') {
$defaultOptions = getConfig(
'ascii-options',
array(
"characterSet" => 'two',
"scale" => 14,
"luminanceStrategy" => 3,
"customCharacterSet" => null,
)
);
$options = get('ascii');
$options = explode(',', $options);
if (isset($options[0]) && !empty($options[0])) {
$defaultOptions['characterSet'] = $options[0];
}
if (isset($options[1]) && !empty($options[1])) {
$defaultOptions['scale'] = $options[1];
}
if (isset($options[2]) && !empty($options[2])) {
$defaultOptions['luminanceStrategy'] = $options[2];
}
if (count($options) > 3) {
// Last option is custom character string
unset($options[0]);
unset($options[1]);
unset($options[2]);
$characterString = implode($options);
$defaultOptions['customCharacterSet'] = $characterString;
}
$img->setAsciiOptions($defaultOptions);
}
/**
* dpr - change to get larger image to easier support larger dpr, such as retina.
*/
$dpr = get(array('ppi', 'dpr', 'device-pixel-ratio'), 1);
verbose("dpr = $dpr");
/**
* convolve - image convolution as in http://php.net/manual/en/function.imageconvolution.php
*/
$convolve = get('convolve', null);
$convolutionConstant = getConfig('convolution_constant', array());
// Check if the convolve is matching an existing constant
if ($convolve && isset($convolutionConstant)) {
$img->addConvolveExpressions($convolutionConstant);
verbose("convolve constant = " . print_r($convolutionConstant, 1));
}
verbose("convolve = " . print_r($convolve, 1));
/**
* no-upscale, nu - Do not upscale smaller image to larger dimension.
*/
$upscale = getDefined(array('no-upscale', 'nu'), false, true);
verbose("upscale = $upscale");
/**
* Get details for post processing
*/
$postProcessing = getConfig('postprocessing', array(
'png_lossy' => false,
'png_lossy_cmd' => '/usr/local/bin/pngquant --force --output',
'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',
));
/**
* lossy - Do lossy postprocessing, if available.
*/
$lossy = getDefined(array('lossy'), true, null);
verbose("lossy = $lossy");
/**
* alias - Save resulting image to another alias name.
* Password always apply, must be defined.
*/
$alias = get('alias', null);
$aliasPath = getConfig('alias_path', null);
$validAliasname = getConfig('valid_aliasname', '#^[a-z0-9A-Z-_]+$#');
$aliasTarget = null;
if ($alias && $aliasPath && $passwordMatch) {
$aliasTarget = $aliasPath . $alias;
$useCache = false;
is_writable($aliasPath)
or errorPage("Directory for alias is not writable.", 403);
preg_match($validAliasname, $alias)
or errorPage('Filename for alias contains invalid characters. Do not add extension.', 404);
} elseif ($alias) {
errorPage('Alias is not enabled in the config file or password not matching.', 403);
}
verbose("alias = $alias");
/**
* Add cache control HTTP header.
*/
$cacheControl = getConfig('cache_control', null);
if ($cacheControl) {
verbose("cacheControl = $cacheControl");
$img->addHTTPHeader("Cache-Control", $cacheControl);
}
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = $cache->getPathToSubdir("dummy");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Prepare a sRGB version of the image and use it as source image.
*/
$srgbDefault = getConfig('srgb_default', false);
$srgbColorProfile = getConfig('srgb_colorprofile', __DIR__ . '/../icc/sRGB_IEC61966-2-1_black_scaled.icc');
$srgb = getDefined('srgb', true, null);
if ($srgb || $srgbDefault) {
$filename = $img->convert2sRGBColorSpace(
$srcImage,
$imagePath,
$cache->getPathToSubdir("srgb"),
$srgbColorProfile,
$useCache
);
if ($filename) {
$srcImage = $img->getTarget();
$imagePath = null;
verbose("srgb conversion and saved to cache = $srcImage");
} else {
verbose("srgb not op");
}
}
/**
* Display status
*/
if ($status) {
$text = "img.php version = " . CIMAGE_VERSION . "\n";
$text .= "PHP version = " . PHP_VERSION . "\n";
$text .= "Running on: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
$text .= "Allow remote images = $allowRemote\n";
$res = $cache->getStatusOfSubdir("");
$text .= "Cache $res\n";
$res = $cache->getStatusOfSubdir("remote");
$text .= "Cache remote $res\n";
$res = $cache->getStatusOfSubdir("dummy");
$text .= "Cache dummy $res\n";
$res = $cache->getStatusOfSubdir("srgb");
$text .= "Cache srgb $res\n";
$res = $cache->getStatusOfSubdir($fastTrackCache);
$text .= "Cache fasttrack $res\n";
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
$no = extension_loaded('exif') ? null : 'NOT';
$text .= "Extension exif is $no loaded.<br>";
$no = extension_loaded('curl') ? null : 'NOT';
$text .= "Extension curl is $no loaded.<br>";
$no = extension_loaded('imagick') ? null : 'NOT';
$text .= "Extension imagick is $no loaded.<br>";
$no = extension_loaded('gd') ? null : 'NOT';
$text .= "Extension gd is $no loaded.<br>";
$text .= checkExternalCommand("PNG LOSSY", $postProcessing["png_lossy"], $postProcessing["png_lossy_cmd"]);
$text .= checkExternalCommand("PNG FILTER", $postProcessing["png_filter"], $postProcessing["png_filter_cmd"]);
$text .= checkExternalCommand("PNG DEFLATE", $postProcessing["png_deflate"], $postProcessing["png_deflate_cmd"]);
$text .= checkExternalCommand("JPEG OPTIMIZE", $postProcessing["jpeg_optimize"], $postProcessing["jpeg_optimize_cmd"]);
if (!$no) {
$text .= print_r(gd_info(), 1);
}
echo <<<EOD
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CImage status</title>
<pre>$text</pre>
EOD;
exit;
}
/**
* Log verbose details to file
*/
if ($verboseFile) {
$img->setVerboseToFile("$cachePath/log.txt");
}
/**
* Hook after img.php configuration and before processing with CImage
*/
$hookBeforeCImage = getConfig('hook_before_CImage', null);
if (is_callable($hookBeforeCImage)) {
verbose("hookBeforeCImage activated");
$allConfig = $hookBeforeCImage($img, array(
// Options for calculate dimensions
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'aspectRatio' => $aspectRatio,
'keepRatio' => $keepRatio,
'cropToFit' => $cropToFit,
'fillToFit' => $fillToFit,
'crop' => $crop,
'area' => $area,
'upscale' => $upscale,
// Pre-processing, before resizing is done
'scale' => $scale,
'rotateBefore' => $rotateBefore,
'autoRotate' => $autoRotate,
// General processing options
'bgColor' => $bgColor,
// Post-processing, after resizing is done
'palette' => $palette,
'filters' => $filters,
'sharpen' => $sharpen,
'emboss' => $emboss,
'blur' => $blur,
'convolve' => $convolve,
'rotateAfter' => $rotateAfter,
// Output format
'outputFormat' => $outputFormat,
'dpr' => $dpr,
// Other
'postProcessing' => $postProcessing,
'lossy' => $lossy,
));
verbose(print_r($allConfig, 1));
extract($allConfig);
}
/**
* 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']);
unset($query['json']);
$url1 = '?' . htmlentities(urldecode(http_build_query($query)));
$url2 = '?' . urldecode(http_build_query($query));
echo <<<EOD
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CImage verbose output</title>
<style>body{background-color: #ddd}</style>
<a href=$url1><code>$url1</code></a><br>
<img src='{$url1}' />
<pre id="json"></pre>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript">
window.getDetails = function (url, id) {
$.getJSON(url, function(data) {
element = document.getElementById(id);
element.innerHTML = "filename: " + data.filename + "\\nmime type: " + data.mimeType + "\\ncolors: " + data.colors + "\\nsize: " + data.size + "\\nwidth: " + data.width + "\\nheigh: " + data.height + "\\naspect-ratio: " + data.aspectRatio + ( data.pngType ? "\\npng-type: " + data.pngType : '');
});
}
</script>
<script type="text/javascript">window.getDetails("{$url2}&json", "json")</script>
EOD;
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)
->setSource($srcImage, $imagePath)
->setOptions(
array(
// Options for calculate dimensions
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'aspectRatio' => $aspectRatio,
'keepRatio' => $keepRatio,
'cropToFit' => $cropToFit,
'fillToFit' => $fillToFit,
'crop' => $crop,
'area' => $area,
'upscale' => $upscale,
// Pre-processing, before resizing is done
'scale' => $scale,
'rotateBefore' => $rotateBefore,
'autoRotate' => $autoRotate,
// General processing options
'bgColor' => $bgColor,
// Post-processing, after resizing is done
'palette' => $palette,
'filters' => $filters,
'sharpen' => $sharpen,
'emboss' => $emboss,
'blur' => $blur,
'convolve' => $convolve,
'rotateAfter' => $rotateAfter,
// Output format
'outputFormat' => $outputFormat,
'dpr' => $dpr,
// Postprocessing using external tools
'lossy' => $lossy,
)
)
->loadImageDetails()
->initDimensions()
->calculateNewWidthAndHeight()
->setSaveAsExtension($saveAs)
->setJpegQuality($quality)
->setPngCompression($compress)
->useOriginalIfPossible($useOriginal)
->generateFilename($cachePath)
->useCacheIfPossible($useCache)
->load()
->preResize()
->resize()
->postResize()
->setPostProcessingOptions($postProcessing)
->save()
->linkToCacheFile($aliasTarget)
->output();