1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-08-27 09:34:30 +02:00

Compare commits

..

82 Commits

Author SHA1 Message Date
Mikael Roos
c5de59a754 prepare to tag v0.7.16 2016-08-09 13:02:25 +02:00
Mikael Roos
7ab19d39d6 adding support for pngquant 2016-08-09 13:01:38 +02:00
Mikael Roos
9f6cba9292 changed date of release 2016-08-09 10:21:41 +02:00
Mikael Roos
21e53887b8 prepare to tag v0.7.15 2016-08-09 10:19:49 +02:00
Mikael Roos
66c5a07767 webp partly working 2016-08-09 09:32:02 +02:00
Mikael Roos
bbfd895c4c webp implemented but fail to verify 2016-08-08 16:49:29 +02:00
Mikael Roos
b5de49d601 add debug for test 2016-08-08 16:48:23 +02:00
Mikael Roos
7677fc772f remove debugging 2016-08-08 16:21:36 +02:00
Mikael Roos
3d0b25abe0 test support for webp images 2016-08-08 16:13:51 +02:00
Mikael Roos
1e5de9d225 Added the [Lenna/Lena sample
image](http://www.cs.cmu.edu/~chuck/lennapg/) as tif and created a png,
jpeg and webp version using Imagick convert `convert lena.tif
lena.{png,jpg,webp}`.
2016-08-08 14:42:12 +02:00
Mikael Roos
43cb5b79b2 prepare to tag v0.7.14 2016-08-08 12:20:01 +02:00
Mikael Roos
8e10e9ba5c Re-add removed cache directory. 2016-08-08 12:19:31 +02:00
Mikael Roos
1738680301 Make fast track cache disabled by default in the config file. 2016-08-08 12:19:04 +02:00
Mikael Roos
9b110037b4 prepare to tag v0.7.13 2016-08-08 11:35:12 +02:00
Mikael Roos
9a912e7f01 prepare to merge 2016-08-08 11:33:04 +02:00
Mikael Roos
689865a8b2 even more testing 2016-08-08 11:19:53 +02:00
Mikael Roos
493ed45311 more test 2016-08-08 10:44:27 +02:00
Mikael Roos
72c04632b8 more test 2016-08-08 10:39:11 +02:00
Mikael Roos
b1d0cb1506 prepare to test 2016-08-08 09:29:26 +02:00
Mikael Roos
c637fa23ef test with imgf 2016-07-18 16:38:57 +02:00
Mikael Roos
6cccf5497d added and fixed fast track cache script version 2016-07-18 01:00:55 +02:00
Mikael Roos
0dd562aa61 add really fast track cache script 2016-07-18 00:44:46 +02:00
Mikael Roos
9a0a9429db make debug depend on file exists 2016-07-10 22:57:58 +02:00
Mikael Roos
6118f298ff prepare to test fast track cache 2016-07-10 22:54:11 +02:00
Mikael Roos
32a23894d1 cleanup, removed code comments, codestyle 2016-06-01 10:11:44 +02:00
Mikael Roos
cde8bab6e7 tagging v0.7.12 2016-06-01 09:37:28 +02:00
Mikael Roos
5edbfc9b54 prepare to tag v0.7.12 2016-06-01 09:34:30 +02:00
Mikael Roos
9e9c44c935 Fixed to correctly display image when using a resize strategy without height or width. 2016-06-01 09:31:28 +02:00
Mikael Roos
9088647d3a Fixed background color for option , #144. 2016-06-01 09:30:18 +02:00
Mikael Roos
8ad324b4f5 update readme with latest version number 2016-04-18 16:09:49 +02:00
Mikael Roos
3b16b4b79d prepare to tag v0.7.11 2016-04-18 15:58:39 +02:00
Mikael Roos
4e940164f9 Add option for skip_original to config file to always skip original, #118. 2016-04-18 15:53:55 +02:00
Mikael Roos
1943d6606b update years in license 2016-04-01 11:25:36 +02:00
Mikael Roos
5eebaa66ce update to latest version 2016-04-01 10:32:44 +02:00
Mikael Roos
c5cc0314c2 prepare to tag v0.7.10 2016-04-01 10:30:25 +02:00
Mikael Roos
71816261f2 prepare to merge master 2016-04-01 10:27:33 +02:00
Mikael Roos
a62d7cb6c2 Add backup option for images src-alt, #141. 2016-04-01 10:24:24 +02:00
Mikael Roos
ccbd08949f add for testcase #134 2016-01-26 17:40:10 +01:00
Mikael Roos
6467fcc748 Add require of ext-gd in composer.json, #133. 2016-01-14 16:19:00 +01:00
Mikael Roos
14d22a18e5 Merge pull request #133 from abcdmitry/patch-1
Add GD extension to the composer requiremets
2016-01-14 16:17:43 +01:00
Dmitry Lukashin
6d3687d838 Add PHP extensions to the composer requirements 2016-01-14 16:03:13 +03:00
Mikael Roos
ad8f6c12ee creating bundles 2015-12-07 17:40:00 +01:00
Mikael Roos
ad4930c3ae Fix strict mode only reporting 404 when failure, #127. 2015-12-07 17:39:34 +01:00
Mikael Roos
f250f7dff9 recreating bundles 2015-12-07 16:02:17 +01:00
Mikael Roos
05c11ca9fc refixing new cache management for remote images 2015-12-07 16:01:47 +01:00
Mikael Roos
b069e322e9 create bundles 2015-12-07 15:36:06 +01:00
Mikael Roos
6e0c775ede clear whitespace 2015-12-07 15:35:19 +01:00
Mikael Roos
179469334a bundles to include CCache 2015-12-07 15:31:41 +01:00
Mikael Roos
0b2723feee Strict mode only reporting 404 when failure, #127. 2015-12-07 15:30:34 +01:00
Mikael Roos
c009f423a2 tested cahce with remote 2015-12-07 15:22:52 +01:00
Mikael Roos
79a7fd17d8 improved cache handling for remote, #130 2015-12-07 15:12:20 +01:00
Mikael Roos
3271d165ff add correct version to remote headers, fix #131 2015-12-07 10:09:26 +01:00
Mikael Roos
1dc04e7c53 fix invalid composer.json 2015-12-06 20:45:44 +01:00
Mikael Roos
376a40e538 adding CCache to improve cache handling of dummy and srgb 2015-12-06 19:53:34 +01:00
Mikael Roos
29743b75ec prepare to tag v0.7.8 2015-12-06 12:47:47 +01:00
Mikael Roos
902c0aaef8 generate new bundles 2015-12-06 12:40:54 +01:00
Mikael Roos
6c487c6f34 ignore build dir 2015-12-06 12:38:17 +01:00
Mikael Roos
a1d811a318 Merge branch '078' 2015-12-06 12:37:11 +01:00
Mikael Roos
a205d65ad5 moving to new travis environment 2015-12-06 12:27:54 +01:00
Mikael Roos
22f24cc75a remove whitespace 2015-12-06 12:26:20 +01:00
Mikael Roos
28be266d15 moving to new travis environment 2015-12-06 12:25:22 +01:00
Mikael Roos
044e3e3c66 prepare to test 078 2015-12-06 12:18:33 +01:00
Mikael Roos
c32ae6dace remove whitespace 2015-12-06 12:05:24 +01:00
Mikael Roos
ef397f5c02 Merge branch 'Anatolie-errors' 2015-12-06 11:59:27 +01:00
Mikael Roos
b871dd7f1c update docs/api with phpdoc 2015-12-02 11:05:41 +01:00
Mikael Roos
91ae49b3f3 More examples on dealing with cache through bash bin/cache.bash, #129. 2015-12-02 11:04:42 +01:00
Mikael Roos
8e1318c31e enable code coverage whitelist 2015-12-02 11:02:42 +01:00
Mikael Roos
9c81286efa adding hook for gitter 2015-12-02 11:02:03 +01:00
Anatolie Diordita
d7b34a6488 Updated to reflect changes proposed in issue #127 2015-11-29 15:23:39 -05:00
Mikael Roos
39cee7647e Added Gitter badge to README, #126. 2015-11-25 10:04:24 +01:00
Mikael Roos
b3dd2a7623 Merge pull request #126 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2015-11-25 10:00:44 +01:00
Anatolie Diordita
3c22db4392 Added specific HTTP status messages to each error. 2015-11-24 17:00:53 -05:00
The Gitter Badger
8aea13ba33 Add Gitter badge 2015-11-23 12:57:52 +00:00
Mikael Roos
ccacc9e0c1 Merge pull request #125 from sonyarianto/master
fix the proper download URL
2015-11-18 18:00:36 +01:00
Sony AK
b93d1242db fix the proper download URL 2015-11-18 11:34:22 +07:00
Mikael Roos
f9a4205579 correcting test 2015-10-26 21:09:32 +01:00
Mikael Roos
0efcfd5bc7 add srgb as part of cache filename 2015-10-24 16:42:59 +02:00
Mikael Roos
7a98a44dd4 Added conversion to sRGB using option ?srgb. #120. 2015-10-24 15:43:56 +02:00
Mikael Roos
aedce7021f Added conversion to sRGB using option , partly working, #120 2015-10-23 14:19:46 +02:00
Mikael Roos
1f012ac19e production should be default mode 2015-10-22 16:52:08 +02:00
Mikael Roos
a62425e759 make htacces work in its current environment. 2015-10-22 16:43:16 +02:00
Mikael Roos
3667082f15 update version number 2015-10-21 01:23:23 +02:00
82 changed files with 8400 additions and 2404 deletions

10
.gitignore vendored
View File

@@ -4,3 +4,13 @@ cache/*
# Test
coverage/
coverage.clover
# Composer
composer.lock
vendor
# Build and test
build/
# Mac OS
.DS_Store

View File

@@ -1,13 +1,93 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
- nightly
- "7.0"
sudo: false
git:
submodules: false
addons:
apt:
packages:
#- php-codesniffer
#- phpmd
#- shellcheck
matrix:
allow_failures:
- php: hhvm
- php: nightly
before_script:
# Create a build directory for output
# Store all files in your own bin
#- install --directory build/bin
#- export PATH=$PATH:$PWD/build/bin/
# Install validation tools
#- npm install -g htmlhint csslint jshint jscs jsonlint js-yaml html-minifier@0.8.0 clean-css uglify-js
# Install phpcs
#- curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
#- install --mode 0755 phpcs.phar $PWD/build/bin/phpcs
# Install phpmd
#- wget -c http://static.phpmd.org/php/latest/phpmd.phar
#- install --mode 0755 phpmd.phar $PWD/build/bin/phpmd
script:
# Check versions of validation tools
#- node --version
#- npm --version
#- htmlhint --version
#- csslint --version
#- jscs --version
#- jshint --version
#- phpcs --version
#- phpmd --version
#- jsonlint --version
#- js-yaml --version
#- shellcheck --version
#- html-minifier --version
#- cleancss --version
#- uglifyjs --version
# Run validation & publish
#- make phpunit
- composer validate
- phpunit
#- make phpcs
notifications:
irc: "irc.freenode.org#dbwebb"
webhooks:
urls:
- https://webhooks.gitter.im/e/a89832db4f939e85ba97
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always

View File

@@ -175,7 +175,7 @@ class CAsciiArt
*/
public function getLuminance($red, $green, $blue)
{
switch($this->luminanceStrategy) {
switch ($this->luminanceStrategy) {
case 1:
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
break;

107
CCache.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
/**
* Deal with the cache directory and cached items.
*
*/
class CCache
{
/**
* Path to the cache directory.
*/
private $path;
/**
* Set the path to the cache dir which must exist.
*
* @param string path to the cache dir.
*
* @throws Exception when $path is not a directory.
*
* @return $this
*/
public function setDir($path)
{
if (!is_dir($path)) {
throw new Exception("Cachedir is not a directory.");
}
$this->path = $path;
return $this;
}
/**
* Get the path to the cache subdir and try to create it if its not there.
*
* @param string $subdir name of subdir
* @param array $create default is to try to create the subdir
*
* @return string | boolean as real path to the subdir or
* false if it does not exists
*/
public function getPathToSubdir($subdir, $create = true)
{
$path = realpath($this->path . "/" . $subdir);
if (is_dir($path)) {
return $path;
}
if ($create && is_writable($this->path)) {
$path = $this->path . "/" . $subdir;
if (mkdir($path)) {
return realpath($path);
}
}
return false;
}
/**
* Get status of the cache subdir.
*
* @param string $subdir name of subdir
*
* @return string with status
*/
public function getStatusOfSubdir($subdir)
{
$path = realpath($this->path . "/" . $subdir);
$exists = is_dir($path);
$res = $exists ? "exists" : "does not exist";
if ($exists) {
$res .= is_writable($path) ? ", writable" : ", not writable";
}
return $res;
}
/**
* Remove the cache subdir.
*
* @param string $subdir name of subdir
*
* @return null | boolean true if success else false, null if no operation
*/
public function removeSubdir($subdir)
{
$path = realpath($this->path . "/" . $subdir);
if (is_dir($path)) {
return rmdir($path);
}
return null;
}
}

238
CFastTrackCache.php Normal file
View File

@@ -0,0 +1,238 @@
<?php
/**
* Enable a fast track cache with a json representation of the image delivery.
*
*/
class CFastTrackCache
{
/**
* Cache is disabled to start with.
*/
private $enabled = false;
/**
* Path to the cache directory.
*/
private $path;
/**
* Filename of current cache item.
*/
private $filename;
/**
* Container with items to store as cached item.
*/
private $container;
/**
* Enable or disable cache.
*
* @param boolean $enable set to true to enable, false to disable
*
* @return $this
*/
public function enable($enabled)
{
$this->enabled = $enabled;
return $this;
}
/**
* Set the path to the cache dir which must exist.
*
* @param string $path to the cache dir.
*
* @throws Exception when $path is not a directory.
*
* @return $this
*/
public function setCacheDir($path)
{
if (!is_dir($path)) {
throw new Exception("Cachedir is not a directory.");
}
$this->path = rtrim($path, "/");
return $this;
}
/**
* Set the filename to store in cache, use the querystring to create that
* filename.
*
* @param array $clear items to clear in $_GET when creating the filename.
*
* @return string as filename created.
*/
public function setFilename($clear)
{
$query = $_GET;
// Remove parts from querystring that should not be part of filename
foreach ($clear as $value) {
unset($query[$value]);
}
arsort($query);
$queryAsString = http_build_query($query);
$this->filename = md5($queryAsString);
if (CIMAGE_DEBUG) {
$this->container["query-string"] = $queryAsString;
}
return $this->filename;
}
/**
* Add header items.
*
* @param string $header add this as header.
*
* @return $this
*/
public function addHeader($header)
{
$this->container["header"][] = $header;
return $this;
}
/**
* Add header items on output, these are not output when 304.
*
* @param string $header add this as header.
*
* @return $this
*/
public function addHeaderOnOutput($header)
{
$this->container["header-output"][] = $header;
return $this;
}
/**
* Set path to source image to.
*
* @param string $source path to source image file.
*
* @return $this
*/
public function setSource($source)
{
$this->container["source"] = $source;
return $this;
}
/**
* Set last modified of source image, use to check for 304.
*
* @param string $lastModified
*
* @return $this
*/
public function setLastModified($lastModified)
{
$this->container["last-modified"] = $lastModified;
return $this;
}
/**
* Get filename of cached item.
*
* @return string as filename.
*/
public function getFilename()
{
return $this->path . "/" . $this->filename;
}
/**
* Write current item to cache.
*
* @return boolean if cache file was written.
*/
public function writeToCache()
{
if (!$this->enabled) {
return false;
}
if (is_dir($this->path) && is_writable($this->path)) {
$filename = $this->getFilename();
return file_put_contents($filename, json_encode($this->container)) !== false;
}
return false;
}
/**
* Output current item from cache, if available.
*
* @return void
*/
public function output()
{
$filename = $this->getFilename();
if (!is_readable($filename)) {
return;
}
$item = json_decode(file_get_contents($filename), true);
if (!is_readable($item["source"])) {
return;
}
foreach ($item["header"] as $value) {
header($value);
}
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
header("HTTP/1.0 304 Not Modified");
if (CIMAGE_DEBUG) {
trace(__CLASS__ . " 304");
}
exit;
}
foreach ($item["header-output"] as $value) {
header($value);
}
if (CIMAGE_DEBUG) {
trace(__CLASS__ . " 200");
}
readfile($item["source"]);
exit;
}
}

View File

@@ -155,6 +155,13 @@ class CImage
/**
* Do lossy output using external postprocessing tools.
*/
private $lossy = null;
/**
* Verbose mode to print out a trace and display the created image
*/
@@ -190,7 +197,15 @@ class CImage
/**
* Path to command for filter optimize, for example optipng or null.
* Path to command for lossy optimize, for example pngquant.
*/
private $pngLossy;
private $pngLossyCmd;
/**
* Path to command for filter optimize, for example optipng.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -198,7 +213,7 @@ class CImage
/**
* Path to command for deflate optimize, for example pngout or null.
* Path to command for deflate optimize, for example pngout.
*/
private $pngDeflate;
private $pngDeflateCmd;
@@ -344,20 +359,27 @@ class CImage
/**
* Calculate target dimension for image when using fill-to-fit resize strategy.
*/
* Calculate target dimension for image when using fill-to-fit resize strategy.
*/
private $fillWidth;
private $fillHeight;
/**
* Allow remote file download, default is to disallow remote file download.
*/
* Allow remote file download, default is to disallow remote file download.
*/
private $allowRemote = false;
/**
* Path to cache for remote download.
*/
private $remoteCache;
/**
* Pattern to recognize a remote file.
*/
@@ -372,6 +394,12 @@ class CImage
private $useCache = true;
/**
* Disable the fasttrackCacke to start with, inject an object to enable it.
*/
private $fastTrackCache = null;
/*
* Set whitelist for valid hostnames from where remote source can be
@@ -439,6 +467,25 @@ class CImage
/**
* Inject object and use it, must be available as member.
*
* @param string $property to set as object.
* @param object $object to set to property.
*
* @return $this
*/
public function injectDependency($property, $object)
{
if (!property_exists($this, $property)) {
$this->raiseError("Injecting unknown property.");
}
$this->$property = $object;
return $this;
}
/**
* Set verbose mode.
*
@@ -512,13 +559,15 @@ class CImage
* Allow or disallow remote image download.
*
* @param boolean $allow true or false to enable and disable.
* @param string $cache path to cache dir.
* @param string $pattern to use to detect if its a remote file.
*
* @return $this
*/
public function setRemoteDownload($allow, $pattern = null)
public function setRemoteDownload($allow, $cache, $pattern = null)
{
$this->allowRemote = $allow;
$this->remoteCache = $cache;
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
$this->log(
@@ -606,7 +655,7 @@ class CImage
*/
private function checkFileExtension($extension)
{
$valid = array('jpg', 'jpeg', 'png', 'gif');
$valid = array('jpg', 'jpeg', 'png', 'gif', 'webp');
in_array(strtolower($extension), $valid)
or $this->raiseError('Not a valid file extension.');
@@ -629,7 +678,7 @@ class CImage
if ($extension == 'jpeg') {
$extension = 'jpg';
}
}
return $extension;
}
@@ -650,21 +699,12 @@ class CImage
}
$remote = new CRemoteImage();
$cache = $this->saveFolder . "/remote/";
if (!is_dir($cache)) {
if (!is_writable($this->saveFolder)) {
throw new Exception("Can not create remote cache, cachefolder not writable.");
}
mkdir($cache);
$this->log("The remote cache does not exists, creating it.");
}
if (!is_writable($cache)) {
if (!is_writable($this->remoteCache)) {
$this->log("The remote cache is not writable.");
}
$remote->setCache($cache);
$remote->setCache($this->remoteCache);
$remote->useCache($this->useCache);
$src = $remote->download($src);
@@ -802,6 +842,9 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Postprocessing using external tools
'lossy' => null,
);
// Convert crop settings from string to array
@@ -916,17 +959,34 @@ class CImage
is_readable($file)
or $this->raiseError('Image file does not exist.');
// Get details on image
$info = list($this->width, $this->height, $this->fileType, $this->attr) = getimagesize($file);
$info = list($this->width, $this->height, $this->fileType) = getimagesize($file);
if (empty($info)) {
throw new Exception("The file doesn't seem to be a valid image.");
// To support webp
$this->fileType = false;
if (function_exists("exif_imagetype")) {
$this->fileType = exif_imagetype($file);
if ($this->fileType === false) {
if (function_exists("imagecreatefromwebp")) {
$webp = imagecreatefromwebp($file);
if ($webp !== false) {
$this->width = imagesx($webp);
$this->height = imagesy($webp);
$this->fileType = IMG_WEBP;
}
}
}
}
}
if (!$this->fileType) {
throw new Exception("Loading image details, the file doesn't seem to be a valid image.");
}
if ($this->verbose) {
$this->log("Loading image details for: {$file}");
$this->log(" Image width x height (type): {$this->width} x {$this->height} ({$this->fileType}).");
$this->log(" Image filesize: " . filesize($file) . " bytes.");
$this->log(" Image mimetype: " . image_type_to_mime_type($this->fileType));
$this->log(" Image mimetype: " . $this->getMimeType());
}
return $this;
@@ -934,6 +994,23 @@ class CImage
/**
* Get mime type for image type.
*
* @return $this
* @throws Exception
*/
protected function getMimeType()
{
if ($this->fileType === IMG_WEBP) {
return "image/webp";
}
return image_type_to_mime_type($this->fileType);
}
/**
* Init new width and height and do some sanity checks on constraints, before any
* processing can be done.
@@ -1098,8 +1175,14 @@ class CImage
$this->newWidth = round($factor * $width);
$this->log("New height was set.");
} else {
// Use existing width and height as new width and height.
$this->newWidth = $width;
$this->newHeight = $height;
}
// Get image dimensions for pre-resize image.
if ($this->cropToFit || $this->fillToFit) {
@@ -1298,10 +1381,11 @@ class CImage
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
* @param string $prefix to add as part of filename
*
* @return $this
*/
public function generateFilename($base = null, $useSubdir = true)
public function generateFilename($base = null, $useSubdir = true, $prefix = null)
{
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
@@ -1323,8 +1407,8 @@ class CImage
$copyStrat = "_rs";
}
$width = $this->newWidth;
$height = $this->newHeight;
$width = $this->newWidth ? '_' . $this->newWidth : null;
$height = $this->newHeight ? '_' . $this->newHeight : null;
$offset = isset($this->offset)
? '_o' . $this->offset['top'] . '-' . $this->offset['right'] . '-' . $this->offset['bottom'] . '-' . $this->offset['left']
@@ -1374,8 +1458,8 @@ class CImage
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
$file = $prefix . $subdir . $filename . $width . $height
. $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
@@ -1438,9 +1522,14 @@ class CImage
$this->setSource($src, $dir);
}
$this->loadImageDetails($this->pathToImage);
$this->loadImageDetails();
$this->image = imagecreatefromstring(file_get_contents($this->pathToImage));
if ($this->fileType === IMG_WEBP) {
$this->image = imagecreatefromwebp($this->pathToImage);
} else {
$imageAsString = file_get_contents($this->pathToImage);
$this->image = imagecreatefromstring($imageAsString);
}
if ($this->image === false) {
throw new Exception("Could not load image.");
}
@@ -1695,25 +1784,41 @@ class CImage
// Resize by crop to fit
$this->log("Resizing using strategy - Crop to fit");
if (!$this->upscale && ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
if (!$this->upscale
&& ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
$this->log("Resizing - smaller image, do not upscale.");
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
$posX = 0;
$posY = 0;
$cropX = 0;
$cropY = 0;
if ($this->newWidth > $this->width) {
$posX = round(($this->newWidth - $this->width) / 2);
}
if ($this->newWidth < $this->width) {
$cropX = round(($this->width/2) - ($this->newWidth/2));
}
if ($this->newHeight > $this->height) {
$posY = round(($this->newHeight - $this->height) / 2);
}
if ($this->newHeight < $this->height) {
$cropY = round(($this->height/2) - ($this->newHeight/2));
}
$this->log(" cwidth: $this->cropWidth");
$this->log(" cheight: $this->cropHeight");
$this->log(" nwidth: $this->newWidth");
$this->log(" nheight: $this->newHeight");
$this->log(" width: $this->width");
$this->log(" height: $this->height");
$this->log(" posX: $posX");
$this->log(" posY: $posY");
$this->log(" cropX: $cropX");
$this->log(" cropY: $cropY");
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->newWidth, $this->newHeight);
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
} else {
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
@@ -1746,14 +1851,14 @@ class CImage
}
if (!$this->upscale
&& ($this->width < $this->newWidth || $this->height < $this->newHeight)
&& ($this->width < $this->newWidth && $this->height < $this->newHeight)
) {
$this->log("Resizing - smaller image, do not upscale.");
$posX = round(($this->fillWidth - $this->width) / 2);
$posY = round(($this->fillHeight - $this->height) / 2);
$posX = round(($this->newWidth - $this->width) / 2);
$posY = round(($this->newHeight - $this->height) / 2);
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->fillWidth, $this->fillHeight);
imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->width, $this->height);
} else {
$imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight);
@@ -1795,9 +1900,8 @@ class CImage
$cropX = round(($this->width - $this->newWidth) / 2);
}
//$this->log("posX=$posX, posY=$posY, cropX=$cropX, cropY=$cropY.");
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->newWidth, $this->newHeight);
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
$this->image = $imageResized;
$this->width = $this->newWidth;
$this->height = $this->newHeight;
@@ -2259,6 +2363,14 @@ class CImage
$this->jpegOptimizeCmd = null;
}
if (array_key_exists("png_lossy", $options)
&& $options['png_lossy'] !== false) {
$this->pngLossy = $options['png_lossy'];
$this->pngLossyCmd = $options['png_lossy_cmd'];
} else {
$this->pngLossyCmd = null;
}
if (isset($options['png_filter']) && $options['png_filter']) {
$this->pngFilterCmd = $options['png_filter_cmd'];
} else {
@@ -2286,9 +2398,11 @@ class CImage
// switch on mimetype
if (isset($this->extension)) {
return strtolower($this->extension);
} else {
return substr(image_type_to_extension($this->fileType), 1);
} elseif ($this->fileType === IMG_WEBP) {
return "webp";
}
return substr(image_type_to_extension($this->fileType), 1);
}
@@ -2344,6 +2458,11 @@ class CImage
imagegif($this->image, $this->cacheFileName);
break;
case 'webp':
$this->Log("Saving image as WEBP to cache using quality = {$this->quality}.");
imagewebp($this->image, $this->cacheFileName, $this->quality);
break;
case 'png':
default:
$this->Log("Saving image as PNG to cache using compression = {$this->compress}.");
@@ -2353,6 +2472,24 @@ class CImage
imagesavealpha($this->image, true);
imagepng($this->image, $this->cacheFileName, $this->compress);
// Use external program to process lossy PNG, if defined
$lossyEnabled = $this->pngLossy === true;
$lossySoftEnabled = $this->pngLossy === null;
$lossyActiveEnabled = $this->lossy === true;
if ($lossyEnabled || ($lossySoftEnabled && $lossyActiveEnabled)) {
if ($this->verbose) {
clearstatcache();
$this->log("Lossy enabled: $lossyEnabled");
$this->log("Lossy soft enabled: $lossySoftEnabled");
$this->Log("Filesize before lossy optimize: " . filesize($this->cacheFileName) . " bytes.");
}
$res = array();
$cmd = $this->pngLossyCmd . " $this->cacheFileName $this->cacheFileName";
exec($cmd, $res);
$this->Log($cmd);
$this->Log($res);
}
// Use external program to filter PNG, if defined
if ($this->pngFilterCmd) {
if ($this->verbose) {
@@ -2397,6 +2534,74 @@ class CImage
/**
* Convert image from one colorpsace/color profile to sRGB without
* color profile.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $cache as base directory where to store images.
* @param string $iccFile filename of colorprofile.
* @param boolean $useCache or not, default to always use cache.
*
* @return string | boolean false if no conversion else the converted
* filename.
*/
public function convert2sRGBColorSpace($src, $dir, $cache, $iccFile, $useCache = true)
{
if ($this->verbose) {
$this->log("# Converting image to sRGB colorspace.");
}
if (!class_exists("Imagick")) {
$this->log(" Ignoring since Imagemagick is not installed.");
return false;
}
// Prepare
$this->setSaveFolder($cache)
->setSource($src, $dir)
->generateFilename(null, false, 'srgb_');
// Check if the cached version is accurate.
if ($useCache && is_readable($this->cacheFileName)) {
$fileTime = filemtime($this->pathToImage);
$cacheTime = filemtime($this->cacheFileName);
if ($fileTime <= $cacheTime) {
$this->log(" Using cached version: " . $this->cacheFileName);
return $this->cacheFileName;
}
}
// Only covert if cachedir is writable
if (is_writable($this->saveFolder)) {
// Load file and check if conversion is needed
$image = new Imagick($this->pathToImage);
$colorspace = $image->getImageColorspace();
$this->log(" Current colorspace: " . $colorspace);
$profiles = $image->getImageProfiles('*', false);
$hasICCProfile = (array_search('icc', $profiles) !== false);
$this->log(" Has ICC color profile: " . ($hasICCProfile ? "YES" : "NO"));
if ($colorspace != Imagick::COLORSPACE_SRGB || $hasICCProfile) {
$this->log(" Converting to sRGB.");
$sRGBicc = file_get_contents($iccFile);
$image->profileImage('icc', $sRGBicc);
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$image->writeImage($this->cacheFileName);
return $this->cacheFileName;
}
}
return false;
}
/**
* Create a hard link, as an alias, to the cached file.
*
@@ -2430,7 +2635,7 @@ class CImage
/**
* Add HTTP header for putputting together with image.
* Add HTTP header for output together with image.
*
* @param string $type the header type such as "Cache-Control"
* @param string $value the value to use
@@ -2464,6 +2669,7 @@ class CImage
$format = $this->outputFormat;
}
$this->log("### Output");
$this->log("Output format is: $format");
if (!$this->verbose && $format == 'json') {
@@ -2481,17 +2687,24 @@ class CImage
// Get image modification time
clearstatcache();
$lastModified = filemtime($file);
$gmdate = gmdate("D, d M Y H:i:s", $lastModified);
$lastModifiedFormat = "D, d M Y H:i:s";
$gmdate = gmdate($lastModifiedFormat, $lastModified);
if (!$this->verbose) {
header('Last-Modified: ' . $gmdate . " GMT");
$header = "Last-Modified: $gmdate GMT";
header($header);
$this->fastTrackCache->addHeader($header);
$this->fastTrackCache->setLastModified($lastModified);
}
foreach($this->HTTPHeader as $key => $val) {
header("$key: $val");
foreach ($this->HTTPHeader as $key => $val) {
$header = "$key: $val";
header($header);
$this->fastTrackCache->addHeader($header);
}
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
&& strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
if ($this->verbose) {
$this->log("304 not modified");
@@ -2500,13 +2713,14 @@ class CImage
}
header("HTTP/1.0 304 Not Modified");
if (CIMAGE_DEBUG) {
trace(__CLASS__ . " 304");
}
} else {
// Get details on image
$info = getimagesize($file);
!empty($info) or $this->raiseError("The file doesn't seem to be an image.");
$mime = $info['mime'];
$this->loadImageDetails($file);
$mime = $this->getMimeType();
$size = filesize($file);
if ($this->verbose) {
@@ -2520,8 +2734,19 @@ class CImage
}
}
header("Content-type: $mime");
header("Content-length: $size");
$header = "Content-type: $mime";
header($header);
$this->fastTrackCache->addHeaderOnOutput($header);
$header = "Content-length: $size";
header($header);
$this->fastTrackCache->addHeaderOnOutput($header);
$this->fastTrackCache->setSource($file);
$this->fastTrackCache->writeToCache();
if (CIMAGE_DEBUG) {
trace(__CLASS__ . " 200");
}
readfile($file);
}
@@ -2556,7 +2781,7 @@ class CImage
$this->load($file);
$details['filename'] = basename($file);
$details['mimeType'] = image_type_to_mime_type($this->fileType);
$details['mimeType'] = $this->getMimeType($this->fileType);
$details['width'] = $this->width;
$details['height'] = $this->height;
$details['aspectRatio'] = round($this->width / $this->height, 3);
@@ -2658,6 +2883,7 @@ class CImage
private function verboseOutput()
{
$log = null;
$this->log("### Summary of verbose log");
$this->log("As JSON: \n" . $this->json());
$this->log("Memory peak: " . round(memory_get_peak_usage() /1024/1024) . "M");
$this->log("Memory limit: " . ini_get('memory_limit'));

View File

@@ -101,7 +101,7 @@ class CRemoteImage
*/
public function setCache($path)
{
$this->saveFolder = $path;
$this->saveFolder = rtrim($path, "/") . "/";
return $this;
}
@@ -147,7 +147,12 @@ class CRemoteImage
*/
public function setHeaderFields()
{
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
$cimageVersion = "CImage";
if (defined("CIMAGE_USER_AGENT")) {
$cimageVersion = CIMAGE_USER_AGENT;
}
$this->http->setHeader("User-Agent", "$cimageVersion (PHP/". phpversion() . " cURL)");
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
if ($this->useCache) {

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2012 - 2014 Mikael Roos, me@mikaelroos.se
Copyright (c) 2012 - 2016 Mikael Roos, https://mikaelroos.se, mos@dbwebb.se
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,13 +1,14 @@
[![Build Status](https://travis-ci.org/mosbth/cimage.svg?branch=master)](https://travis-ci.org/mosbth/cimage)
[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
Image conversion on the fly using PHP
=====================================
[![Join the chat at https://gitter.im/mosbth/cimage](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mosbth/cimage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/mosbth/cimage.svg?branch=master)](https://travis-ci.org/mosbth/cimage)
[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
About
-------------------------------------
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim07.png&w=200&c=140,140,520,340&sharpen"/>
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim07.png&w=200&c=140,140,520,340&sharpen"/>
`CImage` is a PHP class enabling resizing of images through scaling, cropping and filtering effects -- using PHP GD. The script `img.php` uses `CImage` to enable server-side image processing utilizing caching and optimization of the processed images.
@@ -21,7 +22,10 @@ Documentation
--------------------------------------
Read full documentation at:
http://dbwebb.se/opensource/cimage
<strike>http://dbwebb.se/opensource/cimage</strike>
New website is being setup at [cimage.se](https://cimage.se), to improve documentation (work is ongoing).
@@ -45,14 +49,14 @@ There are several ways of installing. You either install the whole project which
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
**Latest stable version is v0.7.6 released 2015-10-18.**
**Latest stable version is v0.7.16 released 2016-08-09.**
I prefer cloning like this. Do switch to the latest stable version.
```bash
git clone git://github.com/mosbth/cimage.git
cd cimage
git checkout v0.7.6
git checkout v0.7.16
```
Make the cache-directory writable by the webserver.
@@ -75,7 +79,7 @@ There are some all-included bundles of `img.php` that can be downloaded and used
Dowload the version of your choice like this.
```bash
wget https://github.com/mosbth/cimage/tree/v0.7.6/webroot/imgp.php
wget https://raw.githubusercontent.com/mosbth/cimage/v0.7.16/webroot/imgp.php
```
Open up the file in your editor and edit the array `$config`. Ensure that the paths to the image directory and the cache directory matches your environment, or create an own config-file for the script.
@@ -97,7 +101,7 @@ Lets take some use cases to let you know when and how `img.php` might be useful.
### Make a thumbnail
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim04.png&w=80&h=80&cf">
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim04.png&w=80&h=80&cf">
Lets say you have a larger image and you want to make a smaller thumbnail of it with a size of 80x80 pixels. You simply take the image and add constraints on `width`, `height` and you use the resize strategy `crop-to-fit` to crops out the parts of the image that does not fit.
@@ -111,7 +115,7 @@ To produce such a thumbnail, create a link like this:
Perhaps you got an image from a friend. The image was taken with the iPhone and thus rotated.
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=250">
<img src="https://cimage.se/cimage/imgd.php?src=example/issue36/me-270.jpg&w=250">
The original image is looking like this one, scaled down to a width of 250 pixels.
@@ -124,7 +128,7 @@ Lets call this *the URL-Photoshopper*. This is how the magic looks like.
> `img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro`
> `&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt`
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt">
<img src="https://cimage.se/cimage/imgd.php?src=example/issue36/me-270.jpg&w=100&h=100&cf&aro&rb=-25&a=8,30,30,38&f=grayscale&convolve=sharpen-alt">
For myself, I use `img.php` to put up all images on my website, it gives me the power of affecting the resulting images - without opening up a photo-editing application.
@@ -143,7 +147,7 @@ Try it out by pointing your browser to the test file `webroot/test/test.php`. It
###Process your first image
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim04.png&amp;w=w2&amp;a=40,0,50,0" alt=''>
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim04.png&amp;w=w2&amp;a=40,0,50,0" alt=''>
Try it yourself by opening up an image in your browser. Start with
@@ -197,7 +201,7 @@ Open an image through `img.php` by using its `src` attribute.
It looks like this.
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=w1&save-as=jpg">
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=w1&save-as=jpg">
All images are stored in a directory structure and you access them as:
@@ -211,7 +215,7 @@ Create a thumbnail of the image by applying constraints on width and height, or
| `&width=150` | `&height=150` | `&w=150&h=150` |
|---------------------|---------------------|---------------------|
| <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&h=150 alt=''> | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=150&h=150 alt=''> |
| <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=150 alt=''> | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&h=150 alt=''> | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=150&h=150 alt=''> |
By setting `width`, `height` or both, the image gets resized to be *not larger* than the defined dimensions *and* keeping its original aspect ratio.
@@ -226,10 +230,10 @@ Creating a thumbnail with a certain dimension of width and height, usually invol
| What | The image |
|---------------------|---------------------|
| **Original.** The original image resized with a max width and max height.<br>`?w=300&h=150` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150 alt=''> |
| **Stretch.** Stretch the image so that the resulting image has the defined width and height.<br>`?w=300&h=150&stretch` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&stretch alt=''> |
| **Crop to fit.** Keep the aspect ratio and crop out the parts of the image that does not fit.<br>`?w=300&h=150&crop-to-fit` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&crop-to-fit alt=''> |
| **Fill to fit.** Keep the aspect ratio and fill then blank space with a background color.<br>`?w=300&h=150&fill-to-fit=006600` | <img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=300&h=150&fill-to-fit=006600 alt=''> |
| **Original.** The original image resized with a max width and max height.<br>`?w=300&h=150` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150 alt=''> |
| **Stretch.** Stretch the image so that the resulting image has the defined width and height.<br>`?w=300&h=150&stretch` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&stretch alt=''> |
| **Crop to fit.** Keep the aspect ratio and crop out the parts of the image that does not fit.<br>`?w=300&h=150&crop-to-fit` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&crop-to-fit alt=''> |
| **Fill to fit.** Keep the aspect ratio and fill then blank space with a background color.<br>`?w=300&h=150&fill-to-fit=006600` | <img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=300&h=150&fill-to-fit=006600 alt=''> |
Learn to crop your images, creative cropping can make wonderful images from appearingly useless originals.
@@ -246,7 +250,7 @@ Fill to fit is useful when you have some image that must fit in a certain dimens
> `img.php?src=kodim13.png&w=600&aspect-ratio=4`
> `&crop-to-fit&sharpen&save-as=jpg&q=30`
<img src=http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30 alt=''>
<img src=https://cimage.se/cimage/imgd.php?src=example/kodim13.png&w=600&aspect-ratio=4&crop-to-fit&sharpen&save-as=jpg&q=30 alt=''>
Here is a list of all parameters that you can use together with `img.php`, grouped by its basic intent of usage.
@@ -429,7 +433,7 @@ For example, the following image is created like this:
> `&w=300&save-as=jpg`
<img src="http://dbwebb.se/kod-exempel/cimage/webroot/img.php?src=kodim24.png&w=300&save-as=jpg" alt=''>
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim24.png&w=300&save-as=jpg" alt=''>
Its JSON-representation is retrieved like this:

View File

@@ -5,6 +5,81 @@ Revision history
[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
v0.7.16 (2016-08-09)
-------------------------------------
* Fix default mode to be production.
* Added pngquant as extra postprocessing utility for PNG-images, #154.
* Bug `&status` wrong variable name for fast track cache.
v0.7.15 (2016-08-09)
-------------------------------------
* Added the [Lenna/Lena sample image](http://www.cs.cmu.edu/~chuck/lennapg/) as tif and created a png, jpeg and webp version using Imagick convert `convert lena.tif lena.{png,jpg,webp}`, #152.
* Limited and basic support for WEBP format, se #132.
v0.7.14 (2016-08-08)
-------------------------------------
* Re-add removed cache directory.
* Make fast track cache disabled by default in the config file.
v0.7.13 (2016-08-08)
-------------------------------------
* Moved functions from img.php to `functions.php`.
* Added function `trace()` to measure speed and memory consumption, only for development.
* Added fast cache #149.
* Added `imgf.php` as shortcut to check for fast cache, before loading `img.php` as usual, adding `imgf_config.php` as symlink to `img_config.php`.
* Created `defines.php` and moved definition av version there.
* Fixed images in README, #148.
* Initiated dependency injection to `CImage`, class names can be set in config file and will be injected to `CImage` from `img.php`. Not implemented for all classes. #151.
* Enabled debug mode to make it easier to trace what actually happens while processing the image, #150.
v0.7.12 (2016-06-01)
-------------------------------------
* Fixed to correctly display image when using a resize strategy without height or width.
* Fixed background color for option `no-upscale`, #144.
v0.7.11 (2016-04-18)
-------------------------------------
* Add option for `skip_original` to config file to always skip original, #118.
v0.7.10 (2016-04-01)
-------------------------------------
* Add backup option for images `src-alt`, #141.
* Add require of ext-gd in composer.json, #133.
* Fix strict mode only reporting 404 when failure, #127.
v0.7.9 (2015-12-07)
-------------------------------------
* Strict mode only reporting 404 when failure, #127.
* Added correct CImage version to remote agent string, #131.
* Adding CCache to improve cache handling of caching for dummy, remote and srgb. #130.
v0.7.8 (2015-12-06)
-------------------------------------
* HTTP error messages now 403, 404 and 500 as in #128 and #127.
* More examples on dealing with cache through bash `bin/cache.bash`, #129.
* Added conversion to sRGB using option `?srgb`. #120.
* Added Gitter badge to README, #126.
* Fix proper download url in README, #125.
* Change path in `webroot/htaccess` to make it work in current environment.
v0.7.7 (2015-10-21)
-------------------------------------

View File

@@ -3,9 +3,10 @@
* Autoloader for CImage and related class files.
*
*/
//include __DIR__ . "/../CHttpGet.php";
//include __DIR__ . "/../CRemoteImage.php";
//include __DIR__ . "/../CImage.php";
require_once __DIR__ . "/defines.php";
require_once __DIR__ . "/functions.php";
/**
* Autoloader for classes.

View File

@@ -1,22 +1,17 @@
#!/bin/bash
#
# Specify the utilities used
# ls -ult list and sorts fils by its access time
#
ECHO="printf"
#
# Main, start by checking basic usage
#
if [ $# -lt 1 ]
then
$ECHO "Usage: $0 [cache-dir]\n"
echo "Usage: $0 [cache-dir]"
exit 1
elif [ ! -d "$1" ]; then
$ECHO "Usage: $0 [cache-dir]\n"
$ECHO "$1 is not a directory.\n"
echo "Usage: $0 [cache-dir]"
echo "$1 is not a directory."
exit 1
fi
@@ -25,12 +20,24 @@ fi
#
# Print out details on cache-directory
#
$ECHO "Total size: $( du -sh $1 | cut -f1 )"
$ECHO "\nNumber of files: $( find $1 | wc -l )"
$ECHO "\n\nTop-5 largest files:\n"
$ECHO "$( du -s $1/* | sort -nr | head -5 )"
$ECHO "\n\nLast-5 created files:\n"
$ECHO "$( find $1/* -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort -r | head -5 )"
$ECHO "\n\nLast-5 accessed files:\n"
$ECHO "$( find $1/* -printf '%AY-%Am-%Ad %AH:%AM %f\n' | sort -r | head -5 )"
$ECHO "\n"
echo "# Size"
echo "Total size: $( du -sh $1 | cut -f1 )"
echo "Number of files: $( find $1 -type f | wc -l )"
echo "Number of dirs: $( find $1 -type d | wc -l )"
echo
echo "# Top-5 largest files/dirs:"
echo "$( du -s $1/* | sort -nr | head -5 )"
echo
echo "# Last-5 created files:"
echo "$( find $1 -type f -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort -r | head -5 )"
echo
echo "# Last-5 accessed files:"
echo "$( find $1 -type f -printf '%AY-%Am-%Ad %AH:%AM %f\n' | sort -r | head -5 )"
echo
echo "# 5 Oldest files:"
echo "$( find $1 -type f -printf '%AY-%Am-%Ad %AH:%AM %f\n' | sort | head -5 )"
echo
echo "# Files not accessed within the last 30 days"
echo "Number of files: $( find $1 -type f -atime +30 | wc -l )"
echo "Total file size: $( find $1 -type f -atime +30 -exec du {} \; | cut -f1 | paste -sd+ | bc )"
echo

View File

@@ -34,11 +34,15 @@ fi
$ECHO "Creating '$TARGET_D', '$TARGET_P' and '$TARGET_S' by combining the following files:"
$ECHO "\n"
$ECHO "\n webroot/img_header.php"
$ECHO "\n defines.php"
$ECHO "\n functions.php"
$ECHO "\n CHttpGet.php"
$ECHO "\n CRemoteImage.php"
$ECHO "\n CWhitelist.php"
$ECHO "\n CAsciiArt.php"
$ECHO "\n CImage.php"
$ECHO "\n CCache.php"
$ECHO "\n CFastTrackCache.php"
$ECHO "\n webroot/img.php"
$ECHO "\n"
$ECHO "\n'$TARGET_D' is for development mode."
@@ -59,6 +63,12 @@ cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode'
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 defines.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 functions.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 CHttpGet.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
@@ -74,6 +84,12 @@ $ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 CImage.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 CCache.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 CFastTrackCache.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
tail -n +2 webroot/img.php | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null
$ECHO "$NEWLINES" | tee -a $TARGET_D $TARGET_P $TARGET_S > /dev/null

4
cache/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

0
cache/README.md vendored
View File

View File

View File

@@ -18,15 +18,25 @@
"docs": "http://dbwebb.se/opensource/cimage"
},
"require": {
"php": ">=5.3"
"php": ">=5.3",
"ext-gd": "*"
},
"suggest": {
"ext-exif": "*"
},
"autoload": {
"classmap": [
"files": [
"defines.php",
"functions.php"
],
"classmap": [
"CImage.php",
"CHttpGet.php",
"CRemoteImage.php",
"CWhitelist.php",
"CAsciiArt.php"
"CAsciiArt.php",
"CCache.php",
"CFastTrackCache.php"
]
}
}

11
defines.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
// Version of cimage and img.php
define("CIMAGE_VERSION", "v0.7.16 (2016-08-09)");
// For CRemoteImage
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
// Image type IMG_WEBP is only defined from 5.6.25
if (!defined("IMG_WEBP")) {
define("IMG_WEBP", -1);
}

View File

@@ -0,0 +1,731 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta charset="utf-8"/>
<title>CImage API Documentaion</title>
<meta name="author" content=""/>
<meta name="description" content=""/>
<link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
<link href="../css/font-awesome.min.css" rel="stylesheet">
<link href="../css/prism.css" rel="stylesheet" media="all"/>
<link href="../css/template.css" rel="stylesheet" media="all"/>
<!--[if lt IE 9]>
<script src="../js/html5.js"></script>
<![endif]-->
<script src="../js/jquery-1.11.0.min.js"></script>
<script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/jquery.smooth-scroll.js"></script>
<script src="../js/prism.min.js"></script>
<!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
<script type="text/javascript">
function loadExternalCodeSnippets() {
Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
var src = pre.getAttribute('data-src');
var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
var language = 'php';
var code = document.createElement('code');
code.className = 'language-' + language;
pre.textContent = '';
code.textContent = 'Loading…';
pre.appendChild(code);
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status < 400 && xhr.responseText) {
code.textContent = xhr.responseText;
Prism.highlightElement(code);
}
else if (xhr.status >= 400) {
code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
}
else {
code.textContent = '✖ Error: File does not exist or is empty';
}
}
};
xhr.send(null);
});
}
$(document).ready(function(){
loadExternalCodeSnippets();
});
$('#source-view').on('shown', function () {
loadExternalCodeSnippets();
})
</script>
<link rel="shortcut icon" href="../images/favicon.ico"/>
<link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
<link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
<link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<i class="icon-ellipsis-vertical"></i>
</a>
<a class="brand" href="../index.html">CImage API Documentaion</a>
<div class="nav-collapse">
<ul class="nav pull-right">
<li class="dropdown" id="charts-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Charts <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>
<a href="../graphs/class.html">
<i class="icon-list-alt"></i>&#160;Class hierarchy diagram
</a>
</li>
</ul>
</li>
<li class="dropdown" id="reports-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Reports <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
<a href="../reports/deprecated.html">
<i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<!--<div class="go_to_top">-->
<!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
<!--</div>-->
</div>
<div id="___" class="container-fluid">
<section class="row-fluid">
<div class="span2 sidebar">
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1847469476"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-1847469476" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="row-fluid">
<div class="span10 offset2">
<div class="row-fluid">
<div class="span8 content class">
<nav>
<a href="../namespaces/default.html">\</a> <i class="icon-level-up"></i>
</nav>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
<h1><small>\</small>CAsciiArt</h1>
<p><em>Create an ASCII version of an image.</em></p>
<section id="summary">
<h2>Summary</h2>
<section class="row-fluid heading">
<section class="span4">
<a href="#methods">Methods</a>
</section>
<section class="span4">
<a href="#properties">Properties</a>
</section>
<section class="span4">
<a href="#constants">Constants</a>
</section>
</section>
<section class="row-fluid public">
<section class="span4">
<a href="../classes/CAsciiArt.html#method___construct" class="">__construct()</a><br />
<a href="../classes/CAsciiArt.html#method_addCharacterSet" class="">addCharacterSet()</a><br />
<a href="../classes/CAsciiArt.html#method_setOptions" class="">setOptions()</a><br />
<a href="../classes/CAsciiArt.html#method_createFromFile" class="">createFromFile()</a><br />
<a href="../classes/CAsciiArt.html#method_luminanceAreaAverage" class="">luminanceAreaAverage()</a><br />
<a href="../classes/CAsciiArt.html#method_getLuminance" class="">getLuminance()</a><br />
<a href="../classes/CAsciiArt.html#method_luminance2character" class="">luminance2character()</a><br />
</section>
<section class="span4">
<em>No public properties found</em>
</section>
<section class="span4">
<em>No constants found</em>
</section>
</section>
<section class="row-fluid protected">
<section class="span4">
<em>No protected methods found</em>
</section>
<section class="span4">
<em>No protected properties found</em>
</section>
<section class="span4">
<em>N/A</em>
</section>
</section>
<section class="row-fluid private">
<section class="span4">
<em>No private methods found</em>
</section>
<section class="span4">
<a href="../classes/CAsciiArt.html#property_characterSet" class="">$characterSet</a><br />
<a href="../classes/CAsciiArt.html#property_characters" class="">$characters</a><br />
<a href="../classes/CAsciiArt.html#property_charCount" class="">$charCount</a><br />
<a href="../classes/CAsciiArt.html#property_scale" class="">$scale</a><br />
<a href="../classes/CAsciiArt.html#property_luminanceStrategy" class="">$luminanceStrategy</a><br />
</section>
<section class="span4">
<em>N/A</em>
</section>
</section>
</section>
</div>
<aside class="span4 detailsbar">
<dl>
<dt>File</dt>
<dd><a href="../files/CAsciiArt.html"><div class="path-wrapper">CAsciiArt.php</div></a></dd>
<dt>Package</dt>
<dd><div class="namespace-wrapper">Default</div></dd>
<dt>Class hierarchy</dt>
<dd class="hierarchy">
<div class="namespace-wrapper">\CAsciiArt</div>
</dd>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<a id="properties" name="properties"></a>
<div class="row-fluid">
<div class="span8 content class">
<h2>Properties</h2>
</div>
<aside class="span4 detailsbar"></aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_characterSet" name="property_characterSet" class="anchor"></a>
<article class="property">
<h3 class="private ">$characterSet</h3>
<pre class="signature">$characterSet : </pre>
<p><em>Character set to use.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_characters" name="property_characters" class="anchor"></a>
<article class="property">
<h3 class="private ">$characters</h3>
<pre class="signature">$characters : </pre>
<p><em>Current character set.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_charCount" name="property_charCount" class="anchor"></a>
<article class="property">
<h3 class="private ">$charCount</h3>
<pre class="signature">$charCount : </pre>
<p><em>Length of current character set.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_scale" name="property_scale" class="anchor"></a>
<article class="property">
<h3 class="private ">$scale</h3>
<pre class="signature">$scale : </pre>
<p><em>Scale of the area to swap to a character.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_luminanceStrategy" name="property_luminanceStrategy" class="anchor"></a>
<article class="property">
<h3 class="private ">$luminanceStrategy</h3>
<pre class="signature">$luminanceStrategy : </pre>
<p><em>Strategy to calculate luminance.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<a id="methods" name="methods"></a>
<div class="row-fluid">
<div class="span8 content class"><h2>Methods</h2></div>
<aside class="span4 detailsbar"></aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method___construct" name="method___construct" class="anchor"></a>
<article class="method">
<h3 class="public ">__construct()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">__construct() </pre>
<p><em>Constructor which sets default options.</em></p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_addCharacterSet" name="method_addCharacterSet" class="anchor"></a>
<article class="method">
<h3 class="public ">addCharacterSet()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">addCharacterSet(string <span class="argument">$key</span>, string <span class="argument">$value</span>) : $this</pre>
<p><em>Add a custom character set.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>string</td>
<td>$key </td>
<td><p>for the character set.</p></td>
</tr>
<tr>
<td>string</td>
<td>$value </td>
<td><p>for the character set.</p></td>
</tr>
</table>
<h4>Returns</h4>
$this
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_setOptions" name="method_setOptions" class="anchor"></a>
<article class="method">
<h3 class="public ">setOptions()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">setOptions(array <span class="argument">$options = array()</span>) : $this</pre>
<p><em>Set options for processing, defaults are available.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>array</td>
<td>$options </td>
<td><p>to use as default settings.</p></td>
</tr>
</table>
<h4>Returns</h4>
$this
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_createFromFile" name="method_createFromFile" class="anchor"></a>
<article class="method">
<h3 class="public ">createFromFile()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">createFromFile(string <span class="argument">$filename</span>) : string</pre>
<p><em>Create an Ascii image from an image file.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>string</td>
<td>$filename </td>
<td><p>of the image to use.</p></td>
</tr>
</table>
<h4>Returns</h4>
string
&mdash; <p>$ascii with the ASCII image.</p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_luminanceAreaAverage" name="method_luminanceAreaAverage" class="anchor"></a>
<article class="method">
<h3 class="public ">luminanceAreaAverage()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">luminanceAreaAverage(string <span class="argument">$img</span>, integer <span class="argument">$x1</span>, integer <span class="argument">$y1</span>, integer <span class="argument">$x2</span>, integer <span class="argument">$y2</span>) : integer</pre>
<p><em>Get the luminance from a region of an image using average color value.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>string</td>
<td>$img </td>
<td><p>the image.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$x1 </td>
<td><p>the area to get pixels from.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$y1 </td>
<td><p>the area to get pixels from.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$x2 </td>
<td><p>the area to get pixels from.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$y2 </td>
<td><p>the area to get pixels from.</p></td>
</tr>
</table>
<h4>Returns</h4>
integer
&mdash; <p>$luminance with a value between 0 and 100.</p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_getLuminance" name="method_getLuminance" class="anchor"></a>
<article class="method">
<h3 class="public ">getLuminance()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">getLuminance(integer <span class="argument">$red</span>, integer <span class="argument">$green</span>, integer <span class="argument">$blue</span>) : float</pre>
<p><em>Calculate luminance value with different strategies.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>integer</td>
<td>$red </td>
<td><p>The color red.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$green </td>
<td><p>The color green.</p></td>
</tr>
<tr>
<td>integer</td>
<td>$blue </td>
<td><p>The color blue.</p></td>
</tr>
</table>
<h4>Returns</h4>
float
&mdash; <p>$luminance with a value between 0 and 1.</p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_luminance2character" name="method_luminance2character" class="anchor"></a>
<article class="method">
<h3 class="public ">luminance2character()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">luminance2character( <span class="argument">$luminance</span>) : string</pre>
<p><em>Translate the luminance value to a character.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td></td>
<td>$luminance </td>
<td></td>
</tr>
</table>
<h4>Returns</h4>
string
&mdash; <p>with the ascii character.</p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
</div>
</section>
<div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="source-view-label">CAsciiArt.php</h3>
</div>
<div class="modal-body">
<pre data-src="../files/CAsciiArt.php.txt" class="language-php line-numbers"></pre>
</div>
</div>
<footer class="row-fluid">
<section class="span10 offset2">
<section class="row-fluid">
<section class="span10 offset1">
<section class="row-fluid footer-sections">
<section class="span4">
<h1><i class="icon-code"></i></h1>
<div>
<ul>
</ul>
</div>
</section>
<section class="span4">
<h1><i class="icon-bar-chart"></i></h1>
<div>
<ul>
<li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
</ul>
</div>
</section>
<section class="span4">
<h1><i class="icon-pushpin"></i></h1>
<div>
<ul>
<li><a href="../reports/errors.html">Errors</a></li>
<li><a href="../reports/markers.html">Markers</a></li>
</ul>
</div>
</section>
</section>
</section>
</section>
<section class="row-fluid">
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>
</footer>
</div>
</body>
</html>

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1983965054"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-603682456"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-1983965054" class="accordion-body collapse in">
<div id="namespace-603682456" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -186,6 +187,7 @@
<section class="row-fluid public">
<section class="span4">
<a href="../classes/CHttpGet.html#method___construct" class="">__construct()</a><br />
<a href="../classes/CHttpGet.html#method_buildUrl" class="">buildUrl()</a><br />
<a href="../classes/CHttpGet.html#method_setUrl" class="">setUrl()</a><br />
<a href="../classes/CHttpGet.html#method_setHeader" class="">setHeader()</a><br />
<a href="../classes/CHttpGet.html#method_parseHeader" class="">parseHeader()</a><br />
@@ -331,6 +333,49 @@
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_buildUrl" name="method_buildUrl" class="anchor"></a>
<article class="method">
<h3 class="public ">buildUrl()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">buildUrl(string <span class="argument">$baseUrl</span>, string <span class="argument">$merge</span>) : string</pre>
<p><em>Build an encoded url.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>string</td>
<td>$baseUrl </td>
<td><p>This is the original url which will be merged.</p></td>
</tr>
<tr>
<td>string</td>
<td>$merge </td>
<td><p>Thse parts should be merged into the baseUrl,
the format is as parse_url.</p></td>
</tr>
</table>
<h4>Returns</h4>
string
&mdash; <p>$url as the modified url.</p>
</article>
</div>
<aside class="span4 detailsbar">
@@ -468,6 +513,11 @@
</tr>
</table>
<h4>Throws</h4>
<dl>
<dt>\Exception</dt>
<dd><p>when curl fails to retrieve url.</p></dd>
</dl>
<h4>Returns</h4>
boolean
@@ -587,16 +637,16 @@
<tr>
<td>mixed</td>
<td>$default </td>
<td><p>as default value (int seconds) if date is</p>
<pre><code> missing in response header.</code></pre></td>
<td><p>as default value (int seconds) if date is
missing in response header.</p></td>
</tr>
</table>
<h4>Returns</h4>
integer
&mdash; <p>as timestamp or $default if Date is missing in</p>
<pre><code> response header.</code></pre>
&mdash; <p>as timestamp or $default if Date is missing in
response header.</p>
</article>
</div>
@@ -626,8 +676,8 @@
<tr>
<td>mixed</td>
<td>$default </td>
<td><p>as default value if date is missing in response</p>
<pre><code> header.</code></pre></td>
<td><p>as default value if date is missing in response
header.</p></td>
</tr>
</table>
@@ -727,7 +777,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

File diff suppressed because it is too large Load Diff

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-811883102"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1171772037"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-811883102" class="accordion-body collapse in">
<div id="namespace-1171772037" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -185,13 +186,11 @@
</section>
<section class="row-fluid public">
<section class="span4">
<a href="../classes/CRemoteImage.html#method___construct" class="">__construct()</a><br />
<a href="../classes/CRemoteImage.html#method_getStatus" class="">getStatus()</a><br />
<a href="../classes/CRemoteImage.html#method_getDetails" class="">getDetails()</a><br />
<a href="../classes/CRemoteImage.html#method_setCache" class="">setCache()</a><br />
<a href="../classes/CRemoteImage.html#method_isCacheWritable" class="">isCacheWritable()</a><br />
<a href="../classes/CRemoteImage.html#method_useCache" class="">useCache()</a><br />
<a href="../classes/CRemoteImage.html#method_contentTypeToFileExtension" class="">contentTypeToFileExtension()</a><br />
<a href="../classes/CRemoteImage.html#method_setHeaderFields" class="">setHeaderFields()</a><br />
<a href="../classes/CRemoteImage.html#method_save" class="">save()</a><br />
<a href="../classes/CRemoteImage.html#method_updateCacheDetails" class="">updateCacheDetails()</a><br />
@@ -230,7 +229,6 @@
<a href="../classes/CRemoteImage.html#property_url" class="">$url</a><br />
<a href="../classes/CRemoteImage.html#property_fileName" class="">$fileName</a><br />
<a href="../classes/CRemoteImage.html#property_fileJson" class="">$fileJson</a><br />
<a href="../classes/CRemoteImage.html#property_fileImage" class="">$fileImage</a><br />
<a href="../classes/CRemoteImage.html#property_cache" class="">$cache</a><br />
</section>
<section class="span4">
@@ -423,7 +421,7 @@
<article class="property">
<h3 class="private ">$fileName</h3>
<pre class="signature">$fileName : </pre>
<p><em>Base name of cache file for downloaded item.</em></p>
<p><em>Base name of cache file for downloaded item and name of image.</em></p>
<h4>Type</h4>
@@ -450,30 +448,6 @@
<p><em>Filename for json-file with details of cached item.</em></p>
<h4>Type</h4>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="property_fileImage" name="property_fileImage" class="anchor"></a>
<article class="property">
<h3 class="private ">$fileImage</h3>
<pre class="signature">$fileImage : </pre>
<p><em>Filename for image-file.</em></p>
<h4>Type</h4>
</article>
@@ -522,32 +496,6 @@
<div class="row-fluid">
<div class="span8 content class">
<a id="method___construct" name="method___construct" class="anchor"></a>
<article class="method">
<h3 class="public ">__construct()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">__construct() </pre>
<p><em>Constructor</em></p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_getStatus" name="method_getStatus" class="anchor"></a>
<article class="method">
<h3 class="public ">getStatus()</h3>
@@ -712,43 +660,6 @@ a remote file.</em></p>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_contentTypeToFileExtension" name="method_contentTypeToFileExtension" class="anchor"></a>
<article class="method">
<h3 class="public ">contentTypeToFileExtension()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">contentTypeToFileExtension(string <span class="argument">$type</span>) : string</pre>
<p><em>Translate a content type to a file extension.</em></p>
<h4>Parameters</h4>
<table class="table table-condensed table-hover">
<tr>
<td>string</td>
<td>$type </td>
<td><p>a valid content type.</p></td>
</tr>
</table>
<h4>Returns</h4>
string
&mdash; <p>as file extension or false if no match.</p>
</article>
</div>
<aside class="span4 detailsbar">
<h1><i class="icon-arrow-down"></i></h1>
<dl>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
<div class="row-fluid">
<div class="span8 content class">
<a id="method_setHeaderFields" name="method_setHeaderFields" class="anchor"></a>
<article class="method">
<h3 class="public ">setHeaderFields()</h3>
@@ -852,6 +763,11 @@ a remote file.</em></p>
</tr>
</table>
<h4>Throws</h4>
<dl>
<dt>\Exception</dt>
<dd><p>when status code does not match 200 or 304.</p></dd>
</dl>
<h4>Returns</h4>
string
@@ -976,7 +892,7 @@ a remote file.</em></p>
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-470874282"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1100227540"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-470874282" class="accordion-body collapse in">
<div id="namespace-1100227540" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -300,8 +301,8 @@ whitelist should be a regexp without the surrounding / or #.</em></p>
<tr>
<td>array</td>
<td>$whitelist </td>
<td><p>with all valid options,</p>
<pre><code> default is to clear the whitelist.</code></pre></td>
<td><p>with all valid options,
default is to clear the whitelist.</p></td>
</tr>
</table>
@@ -413,7 +414,7 @@ whitelist should be a regexp without the surrounding / or #.</em></p>
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -0,0 +1,257 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta charset="utf-8"/>
<title>CImage API Documentaion</title>
<meta name="author" content=""/>
<meta name="description" content=""/>
<link href="../css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
<link href="../css/font-awesome.min.css" rel="stylesheet">
<link href="../css/prism.css" rel="stylesheet" media="all"/>
<link href="../css/template.css" rel="stylesheet" media="all"/>
<!--[if lt IE 9]>
<script src="../js/html5.js"></script>
<![endif]-->
<script src="../js/jquery-1.11.0.min.js"></script>
<script src="../js/ui/1.10.4/jquery-ui.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/jquery.smooth-scroll.js"></script>
<script src="../js/prism.min.js"></script>
<!-- TODO: Add http://jscrollpane.kelvinluck.com/ to style the scrollbars for browsers not using webkit-->
<script type="text/javascript">
function loadExternalCodeSnippets() {
Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
var src = pre.getAttribute('data-src');
var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
var language = 'php';
var code = document.createElement('code');
code.className = 'language-' + language;
pre.textContent = '';
code.textContent = 'Loading…';
pre.appendChild(code);
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status < 400 && xhr.responseText) {
code.textContent = xhr.responseText;
Prism.highlightElement(code);
}
else if (xhr.status >= 400) {
code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
}
else {
code.textContent = '✖ Error: File does not exist or is empty';
}
}
};
xhr.send(null);
});
}
$(document).ready(function(){
loadExternalCodeSnippets();
});
$('#source-view').on('shown', function () {
loadExternalCodeSnippets();
})
</script>
<link rel="shortcut icon" href="../images/favicon.ico"/>
<link rel="apple-touch-icon" href="../images/apple-touch-icon.png"/>
<link rel="apple-touch-icon" sizes="72x72" href="../images/apple-touch-icon-72x72.png"/>
<link rel="apple-touch-icon" sizes="114x114" href="../images/apple-touch-icon-114x114.png"/>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<i class="icon-ellipsis-vertical"></i>
</a>
<a class="brand" href="../index.html">CImage API Documentaion</a>
<div class="nav-collapse">
<ul class="nav pull-right">
<li class="dropdown" id="charts-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Charts <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>
<a href="../graphs/class.html">
<i class="icon-list-alt"></i>&#160;Class hierarchy diagram
</a>
</li>
</ul>
</li>
<li class="dropdown" id="reports-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Reports <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
<a href="../reports/deprecated.html">
<i class="icon-list-alt"></i>&#160;Deprecated <span class="label label-info pull-right">0</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<!--<div class="go_to_top">-->
<!--<a href="#___" style="color: inherit">Back to top&#160;&#160;<i class="icon-upload icon-white"></i></a>-->
<!--</div>-->
</div>
<div id="___" class="container-fluid">
<section class="row-fluid">
<div class="span2 sidebar">
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-306826089"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-306826089" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="row-fluid">
<div class="span10 offset2">
<div class="row-fluid">
<div class="span8 content file">
<nav>
</nav>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal"><i class="icon-code"></i></a>
<h1><small></small>CAsciiArt.php</h1>
<p><em></em></p>
<h2>Classes</h2>
<table class="table table-hover">
<tr>
<td><a href="../classes/CAsciiArt.html">CAsciiArt</a></td>
<td><em>Create an ASCII version of an image.</em></td>
</tr>
</table>
</div>
<aside class="span4 detailsbar">
<dl>
<dt>Package</dt>
<dd><div class="namespace-wrapper">\Default</div></dd>
</dl>
<h2>Tags</h2>
<table class="table table-condensed">
<tr><td colspan="2"><em>None found</em></td></tr>
</table>
</aside>
</div>
</div>
</section>
<div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="source-view-label"></h3>
</div>
<div class="modal-body">
<pre data-src="../files/CAsciiArt.php.txt" class="language-php line-numbers"></pre>
</div>
</div>
<footer class="row-fluid">
<section class="span10 offset2">
<section class="row-fluid">
<section class="span10 offset1">
<section class="row-fluid footer-sections">
<section class="span4">
<h1><i class="icon-code"></i></h1>
<div>
<ul>
</ul>
</div>
</section>
<section class="span4">
<h1><i class="icon-bar-chart"></i></h1>
<div>
<ul>
<li><a href="../graphs/class.html">Class Hierarchy Diagram</a></li>
</ul>
</div>
</section>
<section class="span4">
<h1><i class="icon-pushpin"></i></h1>
<div>
<ul>
<li><a href="../reports/errors.html">Errors</a></li>
<li><a href="../reports/markers.html">Markers</a></li>
</ul>
</div>
</section>
</section>
</section>
</section>
<section class="row-fluid">
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,213 @@
<?php
/**
* Create an ASCII version of an image.
*
*/
class CAsciiArt
{
/**
* Character set to use.
*/
private $characterSet = array(
'one' => "#0XT|:,.' ",
'two' => "@%#*+=-:. ",
'three' => "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
);
/**
* Current character set.
*/
private $characters = null;
/**
* Length of current character set.
*/
private $charCount = null;
/**
* Scale of the area to swap to a character.
*/
private $scale = null;
/**
* Strategy to calculate luminance.
*/
private $luminanceStrategy = null;
/**
* Constructor which sets default options.
*/
public function __construct()
{
$this->setOptions();
}
/**
* Add a custom character set.
*
* @param string $key for the character set.
* @param string $value for the character set.
*
* @return $this
*/
public function addCharacterSet($key, $value)
{
$this->characterSet[$key] = $value;
return $this;
}
/**
* Set options for processing, defaults are available.
*
* @param array $options to use as default settings.
*
* @return $this
*/
public function setOptions($options = array())
{
$default = array(
"characterSet" => 'two',
"scale" => 14,
"luminanceStrategy" => 3,
"customCharacterSet" => null,
);
$default = array_merge($default, $options);
if (!is_null($default['customCharacterSet'])) {
$this->addCharacterSet('custom', $default['customCharacterSet']);
$default['characterSet'] = 'custom';
}
$this->scale = $default['scale'];
$this->characters = $this->characterSet[$default['characterSet']];
$this->charCount = strlen($this->characters);
$this->luminanceStrategy = $default['luminanceStrategy'];
return $this;
}
/**
* Create an Ascii image from an image file.
*
* @param string $filename of the image to use.
*
* @return string $ascii with the ASCII image.
*/
public function createFromFile($filename)
{
$img = imagecreatefromstring(file_get_contents($filename));
list($width, $height) = getimagesize($filename);
$ascii = null;
$incY = $this->scale;
$incX = $this->scale / 2;
for ($y = 0; $y < $height - 1; $y += $incY) {
for ($x = 0; $x < $width - 1; $x += $incX) {
$toX = min($x + $this->scale / 2, $width - 1);
$toY = min($y + $this->scale, $height - 1);
$luminance = $this->luminanceAreaAverage($img, $x, $y, $toX, $toY);
$ascii .= $this->luminance2character($luminance);
}
$ascii .= PHP_EOL;
}
return $ascii;
}
/**
* Get the luminance from a region of an image using average color value.
*
* @param string $img the image.
* @param integer $x1 the area to get pixels from.
* @param integer $y1 the area to get pixels from.
* @param integer $x2 the area to get pixels from.
* @param integer $y2 the area to get pixels from.
*
* @return integer $luminance with a value between 0 and 100.
*/
public function luminanceAreaAverage($img, $x1, $y1, $x2, $y2)
{
$numPixels = ($x2 - $x1 + 1) * ($y2 - $y1 + 1);
$luminance = 0;
for ($x = $x1; $x <= $x2; $x++) {
for ($y = $y1; $y <= $y2; $y++) {
$rgb = imagecolorat($img, $x, $y);
$red = (($rgb >> 16) & 0xFF);
$green = (($rgb >> 8) & 0xFF);
$blue = ($rgb & 0xFF);
$luminance += $this->getLuminance($red, $green, $blue);
}
}
return $luminance / $numPixels;
}
/**
* Calculate luminance value with different strategies.
*
* @param integer $red The color red.
* @param integer $green The color green.
* @param integer $blue The color blue.
*
* @return float $luminance with a value between 0 and 1.
*/
public function getLuminance($red, $green, $blue)
{
switch($this->luminanceStrategy) {
case 1:
$luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255;
break;
case 2:
$luminance = ($red * 0.299 + $green * 0.587 + $blue * 0.114) / 255;
break;
case 3:
$luminance = sqrt(0.299 * pow($red, 2) + 0.587 * pow($green, 2) + 0.114 * pow($blue, 2)) / 255;
break;
case 0:
default:
$luminance = ($red + $green + $blue) / (255 * 3);
}
return $luminance;
}
/**
* Translate the luminance value to a character.
*
* @param string $position a value between 0-100 representing the
* luminance.
*
* @return string with the ascii character.
*/
public function luminance2character($luminance)
{
$position = (int) round($luminance * ($this->charCount - 1));
$char = $this->characters[$position];
return $char;
}
}

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-785926434"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1589006485"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-785926434" class="accordion-body collapse in">
<div id="namespace-1589006485" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -245,7 +246,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -21,6 +21,33 @@ class CHttpGet
/**
* Build an encoded url.
*
* @param string $baseUrl This is the original url which will be merged.
* @param string $merge Thse parts should be merged into the baseUrl,
* the format is as parse_url.
*
* @return string $url as the modified url.
*/
public function buildUrl($baseUrl, $merge)
{
$parts = parse_url($baseUrl);
$parts = array_merge($parts, $merge);
$url = $parts['scheme'];
$url .= "://";
$url .= $parts['host'];
$url .= isset($parts['port'])
? ":" . $parts['port']
: "" ;
$url .= $parts['path'];
return $url;
}
/**
* Set the url for the request.
*
@@ -30,6 +57,18 @@ class CHttpGet
*/
public function setUrl($url)
{
$parts = parse_url($url);
$path = "";
if (isset($parts['path'])) {
$pathParts = explode('/', $parts['path']);
unset($pathParts[0]);
foreach ($pathParts as $value) {
$path .= "/" . rawurlencode($value);
}
}
$url = $this->buildUrl($url, array("path" => $path));
$this->request['url'] = $url;
return $this;
}
@@ -62,7 +101,14 @@ class CHttpGet
*/
public function parseHeader()
{
$header = explode("\r\n", rtrim($this->response['headerRaw'], "\r\n"));
//$header = explode("\r\n", rtrim($this->response['headerRaw'], "\r\n"));
$rawHeaders = rtrim($this->response['headerRaw'], "\r\n");
# Handle multiple responses e.g. with redirections (proxies too)
$headerGroups = explode("\r\n\r\n", $rawHeaders);
# We're only interested in the last one
$header = explode("\r\n", end($headerGroups));
$output = array();
if ('HTTP' === substr($header[0], 0, 4)) {
@@ -86,6 +132,8 @@ class CHttpGet
*
* @param boolean $debug set to true to dump headers.
*
* @throws Exception when curl fails to retrieve url.
*
* @return boolean
*/
public function doGet($debug = false)
@@ -99,6 +147,8 @@ class CHttpGet
CURLINFO_HEADER_OUT => $debug,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 5,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 2,
);
$ch = curl_init();
@@ -106,7 +156,7 @@ class CHttpGet
$response = curl_exec($ch);
if (!$response) {
return false;
throw new Exception("Failed retrieving url, details follows: " . curl_error($ch));
}
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-163130442"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1494355388"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-163130442" class="accordion-body collapse in">
<div id="namespace-1494355388" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -245,7 +246,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -63,6 +63,13 @@ class CImage
/**
* Add HTTP headers for outputing image.
*/
private $HTTPHeader = array();
/**
* Default background color, red, green, blue, alpha.
*
@@ -113,13 +120,6 @@ class CImage
/**
* The root folder of images (only used in constructor to create $pathToImage?).
*/
private $imageFolder;
/**
* Image filename, may include subdirectory, relative from $imageFolder
*/
@@ -193,6 +193,7 @@ class CImage
* Path to command for filter optimize, for example optipng or null.
*/
private $pngFilter;
private $pngFilterCmd;
@@ -200,13 +201,16 @@ class CImage
* Path to command for deflate optimize, for example pngout or null.
*/
private $pngDeflate;
private $pngDeflateCmd;
/**
* Path to command to optimize jpeg images, for example jpegtran or null.
*/
private $jpegOptimize;
private $jpegOptimize;
private $jpegOptimizeCmd;
/**
@@ -282,6 +286,56 @@ class CImage
private $fillToFit;
/**
* To store value for option scale.
*/
private $scale;
/**
* To store value for option.
*/
private $rotateBefore;
/**
* To store value for option.
*/
private $rotateAfter;
/**
* To store value for option.
*/
private $autoRotate;
/**
* To store value for option.
*/
private $sharpen;
/**
* To store value for option.
*/
private $emboss;
/**
* To store value for option.
*/
private $blur;
/**
* Used with option area to set which parts of the image to use.
*/
@@ -318,6 +372,38 @@ class CImage
private $useCache = true;
/*
* Set whitelist for valid hostnames from where remote source can be
* downloaded.
*/
private $remoteHostWhitelist = null;
/*
* Do verbose logging to file by setting this to a filename.
*/
private $verboseFileName = null;
/*
* Output to ascii can take som options as an array.
*/
private $asciiOptions = array();
/*
* Image copy strategy, defaults to RESAMPLE.
*/
const RESIZE = 1;
const RESAMPLE = 2;
private $copyStrategy = NULL;
/**
* Properties, the class is mutable and the method setOptions()
* decides (partly) what properties are created.
@@ -332,9 +418,7 @@ class CImage
public $crop_x;
public $crop_y;
public $filters;
private $type; // Calculated from source image
private $attr; // Calculated from source image
private $useOriginal; // Use original image if possible
@@ -391,9 +475,7 @@ class CImage
/**
* Use cache or not.
*
* @todo clean up how $this->noCache is used in other methods.
*
* @param string $use true or false to use cache.
* @param boolean $use true or false to use cache.
*
* @return $this
*/
@@ -405,6 +487,27 @@ class CImage
/**
* Create and save a dummy image. Use dimensions as stated in
* $this->newWidth, or $width or default to 100 (same for height.
*
* @param integer $width use specified width for image dimension.
* @param integer $height use specified width for image dimension.
*
* @return $this
*/
public function createDummyImage($width = null, $height = null)
{
$this->newWidth = $this->newWidth ?: $width ?: 100;
$this->newHeight = $this->newHeight ?: $height ?: 100;
$this->image = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
return $this;
}
/**
* Allow or disallow remote image download.
*
@@ -418,10 +521,12 @@ class CImage
$this->allowRemote = $allow;
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
$this->log("Set remote download to: "
$this->log(
"Set remote download to: "
. ($this->allowRemote ? "true" : "false")
. " using pattern "
. $this->remotePattern);
. $this->remotePattern
);
return $this;
}
@@ -455,7 +560,10 @@ class CImage
public function setRemoteHostWhitelist($whitelist = null)
{
$this->remoteHostWhitelist = $whitelist;
$this->log("Setting remote host whitelist to: " . print_r($this->remoteHostWhitelist, 1));
$this->log(
"Setting remote host whitelist to: "
. (is_null($whitelist) ? "null" : print_r($whitelist, 1))
);
return $this;
}
@@ -472,14 +580,18 @@ class CImage
public function isRemoteSourceOnWhitelist($src)
{
if (is_null($this->remoteHostWhitelist)) {
$allow = true;
} else {
$whitelist = new CWhitelist();
$hostname = parse_url($src, PHP_URL_HOST);
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
$this->log("Remote host on whitelist not configured - allowing.");
return true;
}
$this->log("Remote host is on whitelist: " . ($allow ? "true" : "false"));
$whitelist = new CWhitelist();
$hostname = parse_url($src, PHP_URL_HOST);
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
$this->log(
"Remote host is on whitelist: "
. ($allow ? "true" : "false")
);
return $allow;
}
@@ -504,6 +616,26 @@ class CImage
/**
* Normalize the file extension.
*
* @param string $extension of image file or skip to use internal.
*
* @return string $extension as a normalized file extension.
*/
private function normalizeFileExtension($extension = null)
{
$extension = strtolower($extension ? $extension : $this->extension);
if ($extension == 'jpeg') {
$extension = 'jpg';
}
return $extension;
}
/**
* Download a remote image and return path to its local copy.
*
@@ -537,7 +669,7 @@ class CImage
$src = $remote->download($src);
$this->log("Remote HTTP status: " . $remote->getStatus());
$this->log("Remote item has local cached file: $src");
$this->log("Remote item is in local cache: $src");
$this->log("Remote details on cache:" . print_r($remote->getDetails(), true));
return $src;
@@ -546,16 +678,18 @@ class CImage
/**
* Set src file.
* Set source file to use as image source.
*
* @param string $src of image.
* @param string $dir as base directory where images are.
* @param string $dir as optional base directory where images are.
*
* @return $this
*/
public function setSource($src, $dir = null)
{
if (!isset($src)) {
$this->imageSrc = null;
$this->pathToImage = null;
return $this;
}
@@ -569,9 +703,9 @@ class CImage
$src = basename($src);
}
$this->imageSrc = ltrim($src, '/');
$this->imageFolder = rtrim($dir, '/');
$this->pathToImage = $this->imageFolder . '/' . $this->imageSrc;
$this->imageSrc = ltrim($src, '/');
$imageFolder = rtrim($dir, '/');
$this->pathToImage = $imageFolder . '/' . $this->imageSrc;
return $this;
}
@@ -582,23 +716,23 @@ class CImage
* Set target file.
*
* @param string $src of target image.
* @param string $dir as base directory where images are stored.
* @param string $dir as optional base directory where images are stored.
* Uses $this->saveFolder if null.
*
* @return $this
*/
public function setTarget($src = null, $dir = null)
{
if (!(isset($src) && isset($dir))) {
if (!isset($src)) {
$this->cacheFileName = null;
return $this;
}
$this->saveFolder = $dir;
$this->cacheFileName = $dir . '/' . $src;
if (isset($dir)) {
$this->saveFolder = rtrim($dir, '/');
}
/* Allow readonly cache
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
*/
$this->cacheFileName = $this->saveFolder . '/' . $src;
// Sanitize filename
$this->cacheFileName = preg_replace('/^a-zA-Z0-9\.-_/', '', $this->cacheFileName);
@@ -609,6 +743,18 @@ class CImage
/**
* Get filename of target file.
*
* @return Boolean|String as filename of target or false if not set.
*/
public function getTarget()
{
return $this->cacheFileName;
}
/**
* Set options to use when processing image.
*
@@ -656,11 +802,6 @@ class CImage
// Output format
'outputFormat' => null,
'dpr' => 1,
// Options for saving
//'quality' => null,
//'compress' => null,
//'saveAs' => null,
);
// Convert crop settings from string to array
@@ -777,7 +918,9 @@ class CImage
// Get details on image
$info = list($this->width, $this->height, $this->fileType, $this->attr) = getimagesize($file);
!empty($info) or $this->raiseError("The file doesn't seem to be an image.");
if (empty($info)) {
throw new Exception("The file doesn't seem to be a valid image.");
}
if ($this->verbose) {
$this->log("Loading image details for: {$file}");
@@ -974,7 +1117,7 @@ class CImage
$this->cropHeight = round($height / $ratio);
$this->log("Crop width, height, ratio: $this->cropWidth x $this->cropHeight ($ratio).");
} else if ($this->fillToFit) {
} elseif ($this->fillToFit) {
// Use newWidth and newHeigh as defined width/height,
// image should fit the area.
@@ -1152,13 +1295,15 @@ class CImage
/**
* Generate filename to save file in cache.
*
* @param string $base as basepath for storing file.
* @param string $base as optional basepath for storing file.
* @param boolean $useSubdir use or skip the subdir part when creating the
* filename.
*
* @return $this
*/
public function generateFilename($base)
public function generateFilename($base = null, $useSubdir = true)
{
$parts = pathinfo($this->pathToImage);
$filename = basename($this->pathToImage);
$cropToFit = $this->cropToFit ? '_cf' : null;
$fillToFit = $this->fillToFit ? '_ff' : null;
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
@@ -1170,6 +1315,14 @@ class CImage
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
$saveAs = $this->normalizeFileExtension();
$saveAs = $saveAs ? "_$saveAs" : null;
$copyStrat = null;
if ($this->copyStrategy === self::RESIZE) {
$copyStrat = "_rs";
}
$width = $this->newWidth;
$height = $this->newHeight;
@@ -1187,7 +1340,7 @@ class CImage
if (is_array($filter)) {
$filters .= "_f{$filter['id']}";
for ($i=1; $i<=$filter['argc']; $i++) {
$filters .= ":".$filter["arg{$i}"];
$filters .= "-".$filter["arg{$i}"];
}
}
}
@@ -1200,16 +1353,6 @@ class CImage
$autoRotate = $this->autoRotate ? 'ar' : null;
$this->extension = isset($this->extension)
? $this->extension
: (isset($parts['extension'])
? $parts['extension']
: null);
$extension = empty($this->extension)
? null
: "." . $this->extension;
$optimize = $this->jpegOptimize ? 'o' : null;
$optimize .= $this->pngFilter ? 'f' : null;
$optimize .= $this->pngDeflate ? 'd' : null;
@@ -1224,14 +1367,20 @@ class CImage
$upscale = '_nu';
}
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$file = $subdir . '_' . $parts['filename'] . '_' . $width . '_'
$subdir = null;
if ($useSubdir === true) {
$subdir = str_replace('/', '-', dirname($this->imageSrc));
$subdir = ($subdir == '.') ? '_.' : $subdir;
$subdir .= '_';
}
$file = $subdir . $filename . '_' . $width . '_'
. $height . $offset . $crop . $cropToFit . $fillToFit
. $crop_x . $crop_y . $upscale
. $quality . $filters . $sharpen . $emboss . $blur . $palette . $optimize
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor . $convolve
. $extension;
. $quality . $filters . $sharpen . $emboss . $blur . $palette
. $optimize . $compress
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
. $convolve . $copyStrat . $saveAs;
return $this->setTarget($file, $base);
}
@@ -1273,22 +1422,6 @@ class CImage
/**
* To display error message when failing to load somehow corrupt image.
*
* @return void
*
*/
public function failedToLoad()
{
header("HTTP/1.0 404 Not Found");
echo("CImage.php says 404: Fatal error when opening image.<br>");
$image = imagecreatefromstring(file_get_contents($this->pathToImage));
exit();
}
/**
* Load image from disk. Try to load image without verbose error message,
* if fail, load again and display error messages.
@@ -1307,9 +1440,12 @@ class CImage
$this->loadImageDetails($this->pathToImage);
$this->image = @imagecreatefromstring(file_get_contents($this->pathToImage));
$this->image or $this->failedToLoad();
$this->image = imagecreatefromstring(file_get_contents($this->pathToImage));
if ($this->image === false) {
throw new Exception("Could not load image.");
}
/* Removed v0.7.7
if (image_type_to_mime_type($this->fileType) == 'image/png') {
$type = $this->getPngType();
$hasFewColors = imagecolorstotal($this->image);
@@ -1321,14 +1457,15 @@ class CImage
$this->palette = true;
}
}
*/
if ($this->verbose) {
$this->log("Image successfully loaded from file.");
$this->log("### Image successfully loaded from file.");
$this->log(" imageistruecolor() : " . (imageistruecolor($this->image) ? 'true' : 'false'));
$this->log(" imagecolorstotal() : " . imagecolorstotal($this->image));
$this->log(" Number of colors in image = " . $this->colorsTotal($this->image));
$index = imagecolortransparent($this->image);
$this->log(" Detected transparent color = " . ($index > 0 ? implode(", ", imagecolorsforindex($this->image, $index)) : "NONE") . " at index = $index");
$this->log(" Detected transparent color = " . ($index >= 0 ? implode(", ", imagecolorsforindex($this->image, $index)) : "NONE") . " at index = $index");
}
return $this;
@@ -1339,37 +1476,20 @@ class CImage
/**
* Get the type of PNG image.
*
* @param string $filename to use instead of default.
*
* @return int as the type of the png-image
*
*/
private function getPngType()
public function getPngType($filename = null)
{
$pngType = ord(file_get_contents($this->pathToImage, false, null, 25, 1));
$filename = $filename ? $filename : $this->pathToImage;
switch ($pngType) {
$pngType = ord(file_get_contents($filename, false, null, 25, 1));
case self::PNG_GREYSCALE:
$this->log("PNG is type 0, Greyscale.");
break;
case self::PNG_RGB:
$this->log("PNG is type 2, RGB");
break;
case self::PNG_RGB_PALETTE:
$this->log("PNG is type 3, RGB with palette");
break;
case self::PNG_GREYSCALE_ALPHA:
$this->Log("PNG is type 4, Greyscale with alpha channel");
break;
case self::PNG_RGB_ALPHA:
$this->Log("PNG is type 6, RGB with alpha channel (PNG 32-bit)");
break;
default:
$this->Log("PNG is UNKNOWN type, is it really a PNG image?");
if ($this->verbose) {
$this->log("Checking png type of: " . $filename);
$this->log($this->getPngTypeAsString($pngType));
}
return $pngType;
@@ -1377,6 +1497,59 @@ class CImage
/**
* Get the type of PNG image as a verbose string.
*
* @param integer $type to use, default is to check the type.
* @param string $filename to use instead of default.
*
* @return int as the type of the png-image
*
*/
private function getPngTypeAsString($pngType = null, $filename = null)
{
if ($filename || !$pngType) {
$pngType = $this->getPngType($filename);
}
$index = imagecolortransparent($this->image);
$transparent = null;
if ($index != -1) {
$transparent = " (transparent)";
}
switch ($pngType) {
case self::PNG_GREYSCALE:
$text = "PNG is type 0, Greyscale$transparent";
break;
case self::PNG_RGB:
$text = "PNG is type 2, RGB$transparent";
break;
case self::PNG_RGB_PALETTE:
$text = "PNG is type 3, RGB with palette$transparent";
break;
case self::PNG_GREYSCALE_ALPHA:
$text = "PNG is type 4, Greyscale with alpha channel";
break;
case self::PNG_RGB_ALPHA:
$text = "PNG is type 6, RGB with alpha channel (PNG 32-bit)";
break;
default:
$text = "PNG is UNKNOWN type, is it really a PNG image?";
}
return $text;
}
/**
* Calculate number of colors in an image.
*
@@ -1412,7 +1585,7 @@ class CImage
*/
public function preResize()
{
$this->log("Pre-process before resizing");
$this->log("### Pre-process before resizing");
// Rotate image
if ($this->rotateBefore) {
@@ -1445,6 +1618,39 @@ class CImage
/**
* Resize or resample the image while resizing.
*
* @param int $strategy as CImage::RESIZE or CImage::RESAMPLE
*
* @return $this
*/
public function setCopyResizeStrategy($strategy)
{
$this->copyStrategy = $strategy;
return $this;
}
/**
* Resize and or crop the image.
*
* @return void
*/
public function imageCopyResampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
{
if($this->copyStrategy == self::RESIZE) {
$this->log("Copy by resize");
imagecopyresized($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
} else {
$this->log("Copy by resample");
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
}
}
/**
* Resize and or crop the image.
*
@@ -1453,7 +1659,7 @@ class CImage
public function resize()
{
$this->log("Starting to Resize()");
$this->log("### Starting to Resize()");
$this->log("Upscale = '$this->upscale'");
// Only use a specified area of the image, $this->offset is defining the area to use
@@ -1513,7 +1719,7 @@ class CImage
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopyresampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
$this->imageCopyResampled($imgPreCrop, $this->image, 0, 0, 0, 0, $this->cropWidth, $this->cropHeight, $this->width, $this->height);
imagecopy($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight);
}
@@ -1521,7 +1727,7 @@ class CImage
$this->width = $this->newWidth;
$this->height = $this->newHeight;
} else if ($this->fillToFit) {
} elseif ($this->fillToFit) {
// Resize by fill to fit
$this->log("Resizing using strategy - Fill to fit");
@@ -1552,7 +1758,7 @@ class CImage
} else {
$imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight);
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopyresampled($imgPreFill, $this->image, 0, 0, 0, 0, $this->fillWidth, $this->fillHeight, $this->width, $this->height);
$this->imageCopyResampled($imgPreFill, $this->image, 0, 0, 0, 0, $this->fillWidth, $this->fillHeight, $this->width, $this->height);
imagecopy($imageResized, $imgPreFill, $posX, $posY, 0, 0, $this->fillWidth, $this->fillHeight);
}
@@ -1560,7 +1766,7 @@ class CImage
$this->width = $this->newWidth;
$this->height = $this->newHeight;
} else if (!($this->newWidth == $this->width && $this->newHeight == $this->height)) {
} elseif (!($this->newWidth == $this->width && $this->newHeight == $this->height)) {
// Resize it
$this->log("Resizing, new height and/or width");
@@ -1581,10 +1787,10 @@ class CImage
if ($this->newWidth > $this->width && $this->newHeight > $this->height) {
$posX = round(($this->newWidth - $this->width) / 2);
$posY = round(($this->newHeight - $this->height) / 2);
} else if ($this->newWidth > $this->width) {
} elseif ($this->newWidth > $this->width) {
$posX = round(($this->newWidth - $this->width) / 2);
$cropY = round(($this->height - $this->newHeight) / 2);
} else if ($this->newHeight > $this->height) {
} elseif ($this->newHeight > $this->height) {
$posY = round(($this->newHeight - $this->height) / 2);
$cropX = round(($this->width - $this->newWidth) / 2);
}
@@ -1598,7 +1804,7 @@ class CImage
}
} else {
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
imagecopyresampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
$this->imageCopyResampled($imageResized, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height);
$this->image = $imageResized;
$this->width = $this->newWidth;
$this->height = $this->newHeight;
@@ -1617,7 +1823,7 @@ class CImage
*/
public function postResize()
{
$this->log("Post-process after resizing");
$this->log("### Post-process after resizing");
// Rotate image
if ($this->rotateAfter) {
@@ -2013,7 +2219,10 @@ class CImage
imagealphablending($img, false);
imagesavealpha($img, true);
$index = imagecolortransparent($this->image);
$index = $this->image
? imagecolortransparent($this->image)
: -1;
if ($index != -1) {
imagealphablending($img, true);
@@ -2074,10 +2283,11 @@ class CImage
*/
protected function getTargetImageExtension()
{
// switch on mimetype
if (isset($this->extension)) {
return strtolower($this->extension);
} else {
return image_type_to_extension($this->fileType);
return substr(image_type_to_extension($this->fileType), 1);
}
}
@@ -2086,21 +2296,29 @@ class CImage
/**
* Save image.
*
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param string $src as target filename.
* @param string $base as base directory where to store images.
* @param boolean $overwrite or not, default to always overwrite file.
*
* @return $this or false if no folder is set.
*/
public function save($src = null, $base = null)
public function save($src = null, $base = null, $overwrite = true)
{
if (isset($src)) {
$this->setTarget($src, $base);
}
if ($overwrite === false && is_file($this->cacheFileName)) {
$this->Log("Not overwriting file since its already exists and \$overwrite if false.");
return;
}
is_writable($this->saveFolder)
or $this->raiseError('Target directory is not writable.');
switch($this->getTargetImageExtension()) {
$type = $this->getTargetImageExtension();
$this->Log("Saving image as " . $type);
switch($type) {
case 'jpeg':
case 'jpg':
@@ -2194,8 +2412,6 @@ class CImage
return $this;
}
$alias = $alias . "." . $this->getTargetImageExtension();
if (is_readable($alias)) {
unlink($alias);
}
@@ -2213,11 +2429,28 @@ class CImage
/**
* Add HTTP header for putputting together with image.
*
* @param string $type the header type such as "Cache-Control"
* @param string $value the value to use
*
* @return void
*/
public function addHTTPHeader($type, $value)
{
$this->HTTPHeader[$type] = $value;
}
/**
* Output image to browser using caching.
*
* @param string $file to read and output, default is to use $this->cacheFileName
* @param string $format set to json to output file as json object with details
* @param string $file to read and output, default is to
* use $this->cacheFileName
* @param string $format set to json to output file as json
* object with details
*
* @return void
*/
@@ -2237,6 +2470,10 @@ class CImage
header('Content-type: application/json');
echo $this->json($file);
exit;
} elseif ($format == 'ascii') {
header('Content-type: text/plain');
echo $this->ascii($file);
exit;
}
$this->log("Outputting image: $file");
@@ -2250,6 +2487,10 @@ class CImage
header('Last-Modified: ' . $gmdate . " GMT");
}
foreach($this->HTTPHeader as $key => $val) {
header("$key: $val");
}
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
if ($this->verbose) {
@@ -2262,18 +2503,25 @@ class CImage
} else {
if ($this->verbose) {
$this->log("Last modified: " . $gmdate . " GMT");
$this->verboseOutput();
exit;
}
// Get details on image
$info = getimagesize($file);
!empty($info) or $this->raiseError("The file doesn't seem to be an image.");
$mime = $info['mime'];
$size = filesize($file);
header('Content-type: ' . $mime);
if ($this->verbose) {
$this->log("Last-Modified: " . $gmdate . " GMT");
$this->log("Content-type: " . $mime);
$this->log("Content-length: " . $size);
$this->verboseOutput();
if (is_null($this->verboseFileName)) {
exit;
}
}
header("Content-type: $mime");
header("Content-length: $size");
readfile($file);
}
@@ -2314,6 +2562,18 @@ class CImage
$details['aspectRatio'] = round($this->width / $this->height, 3);
$details['size'] = filesize($file);
$details['colors'] = $this->colorsTotal($this->image);
$details['includedFiles'] = count(get_included_files());
$details['memoryPeek'] = round(memory_get_peak_usage()/1024/1024, 3) . " MB" ;
$details['memoryCurrent'] = round(memory_get_usage()/1024/1024, 3) . " MB";
$details['memoryLimit'] = ini_get('memory_limit');
if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
$details['loadTime'] = (string) round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']), 3) . "s";
}
if ($details['mimeType'] == 'image/png') {
$details['pngType'] = $this->getPngTypeAsString(null, $file);
}
$options = null;
if (defined("JSON_PRETTY_PRINT") && defined("JSON_UNESCAPED_SLASHES")) {
@@ -2325,6 +2585,38 @@ class CImage
/**
* Set options for creating ascii version of image.
*
* @param array $options empty to use default or set options to change.
*
* @return void.
*/
public function setAsciiOptions($options = array())
{
$this->asciiOptions = $options;
}
/**
* Create an ASCII version from the image details.
*
* @param string $file the file to output.
*
* @return string ASCII representation of the image.
*/
public function ascii($file = null)
{
$file = $file ? $file : $this->cacheFileName;
$asciiArt = new CAsciiArt();
$asciiArt->setOptions($this->asciiOptions);
return $asciiArt->createFromFile($file);
}
/**
* Log an event if verbose mode.
*
@@ -2343,6 +2635,21 @@ class CImage
/**
* Do verbose output to a file.
*
* @param string $fileName where to write the verbose output.
*
* @return void
*/
public function setVerboseToFile($fileName)
{
$this->log("Setting verbose output to file.");
$this->verboseFileName = $fileName;
}
/**
* Do verbose output and print out the log and the actual images.
*
@@ -2368,15 +2675,17 @@ class CImage
}
}
echo <<<EOD
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CImage verbose output</title>
<style>body{background-color: #ddd}</style>
if (!is_null($this->verboseFileName)) {
file_put_contents(
$this->verboseFileName,
str_replace("<br/>", "\n", $log)
);
} else {
echo <<<EOD
<h1>CImage Verbose Output</h1>
<pre>{$log}</pre>
EOD;
}
}

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-609156684"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1879794739"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-609156684" class="accordion-body collapse in">
<div id="namespace-1879794739" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -245,7 +246,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -48,7 +48,7 @@ class CRemoteImage
/**
* Base name of cache file for downloaded item.
* Base name of cache file for downloaded item and name of image.
*/
private $fileName;
@@ -61,13 +61,6 @@ class CRemoteImage
/**
* Filename for image-file.
*/
private $fileImage;
/**
* Cache details loaded from file.
*/
@@ -75,16 +68,6 @@ class CRemoteImage
/**
* Constructor
*
*/
public function __construct()
{
;
}
/**
* Get status of last HTTP request.
*
@@ -157,34 +140,14 @@ class CRemoteImage
/**
* Translate a content type to a file extension.
*
* @param string $type a valid content type.
*
* @return string as file extension or false if no match.
*/
function contentTypeToFileExtension($type) {
$extension = array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
);
return isset($extension[$type])
? $extension[$type]
: false;
}
/**
* Set header fields.
*
* @return $this
*/
function setHeaderFields() {
$this->http->setHeader("User-Agent", "CImage/0.6 (PHP/". phpversion() . " cURL)");
public function setHeaderFields()
{
$this->http->setHeader("User-Agent", "CImage/0.7.2 (PHP/". phpversion() . " cURL)");
$this->http->setHeader("Accept", "image/jpeg,image/png,image/gif");
if ($this->useCache) {
@@ -202,37 +165,31 @@ class CRemoteImage
*
* @return string as path to saved file or false if not saved.
*/
function save() {
public function save()
{
$this->cache = array();
$date = $this->http->getDate(time());
$maxAge = $this->http->getMaxAge($this->defaultMaxAge);
$lastModified = $this->http->getLastModified();
$type = $this->http->getContentType();
$extension = $this->contentTypeToFileExtension($type);
$this->cache['Date'] = gmdate("D, d M Y H:i:s T", $date);
$this->cache['Max-Age'] = $maxAge;
$this->cache['Content-Type'] = $type;
$this->cache['File-Extension'] = $extension;
$this->cache['Url'] = $this->url;
if ($lastModified) {
$this->cache['Last-Modified'] = gmdate("D, d M Y H:i:s T", $lastModified);
}
if ($extension) {
// Save only if body is a valid image
$body = $this->http->getBody();
$img = imagecreatefromstring($body);
$this->fileImage = $this->fileName . "." . $extension;
// Save only if body is a valid image
$body = $this->http->getBody();
$img = imagecreatefromstring($body);
if ($img !== false) {
file_put_contents($this->fileImage, $body);
file_put_contents($this->fileJson, json_encode($this->cache));
return $this->fileImage;
}
if ($img !== false) {
file_put_contents($this->fileName, $body);
file_put_contents($this->fileJson, json_encode($this->cache));
return $this->fileName;
}
return false;
@@ -245,21 +202,21 @@ class CRemoteImage
*
* @return string as path to cached file.
*/
function updateCacheDetails() {
public function updateCacheDetails()
{
$date = $this->http->getDate(time());
$maxAge = $this->http->getMaxAge($this->defaultMaxAge);
$lastModified = $this->http->getLastModified();
$this->cache['Date'] = gmdate("D, d M Y H:i:s T", $date);
$this->cache['Max-Age'] = $maxAge;
$this->cache['Date'] = gmdate("D, d M Y H:i:s T", $date);
$this->cache['Max-Age'] = $maxAge;
if ($lastModified) {
$this->cache['Last-Modified'] = gmdate("D, d M Y H:i:s T", $lastModified);
}
file_put_contents($this->fileJson, json_encode($this->cache));
return $this->fileImage;
return $this->fileName;
}
@@ -269,10 +226,12 @@ class CRemoteImage
*
* @param string $url a remote url.
*
* @throws Exception when status code does not match 200 or 304.
*
* @return string as path to downloaded file or false if failed.
*/
function download($url) {
public function download($url)
{
$this->http = new CHttpGet();
$this->url = $url;
@@ -296,12 +255,12 @@ class CRemoteImage
if ($this->status === 200) {
$this->isCacheWritable();
return $this->save();
} else if ($this->status === 304) {
} elseif ($this->status === 304) {
$this->isCacheWritable();
return $this->updateCacheDetails();
}
return false;
throw new Exception("Unknown statuscode when downloading remote image: " . $this->status);
}
@@ -313,7 +272,7 @@ class CRemoteImage
*/
public function loadCacheDetails()
{
$cacheFile = str_replace(array("/", ":", "#", ".", "?"), "-", $this->url);
$cacheFile = md5($this->url);
$this->fileName = $this->saveFolder . $cacheFile;
$this->fileJson = $this->fileName . ".json";
if (is_readable($this->fileJson)) {
@@ -330,15 +289,15 @@ class CRemoteImage
*/
public function getCachedSource()
{
$this->fileImage = $this->fileName . "." . $this->cache['File-Extension'];
$imageExists = is_readable($this->fileImage);
$imageExists = is_readable($this->fileName);
// Is cache valid?
$date = strtotime($this->cache['Date']);
$maxAge = $this->cache['Max-Age'];
$now = time();
$now = time();
if ($imageExists && $date + $maxAge > $now) {
return $this->fileImage;
return $this->fileName;
}
// Prepare for a 304 if available

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1345074256"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1920829892"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-1345074256" class="accordion-body collapse in">
<div id="namespace-1920829892" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -245,7 +246,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -23,11 +23,11 @@ class CWhitelist
*/
public function set($whitelist = array())
{
if (is_array($whitelist)) {
$this->whitelist = $whitelist;
} else {
if (!is_array($whitelist)) {
throw new Exception("Whitelist is not of a supported format.");
}
$this->whitelist = $whitelist;
return $this;
}

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-716918064"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-105414451"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-716918064" class="accordion-body collapse in">
<div id="namespace-105414451" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -238,7 +239,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -17,7 +17,7 @@
spl_autoload_register(function ($class) {
//$path = CIMAGE_SOURCE_PATH . "/{$class}.php";
$path = __DIR__ . "/{$class}.php";
if(is_file($path)) {
if (is_file($path)) {
require($path);
}
});

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-110318675"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-543265601"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-110318675" class="accordion-body collapse in">
<div id="namespace-543265601" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -219,7 +220,7 @@
<h3 class=" ">errorPage()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">errorPage(string <span class="argument">$msg</span>) : void</pre>
<p><em>Default configuration options, can be overridden in own config-file.</em></p>
<p><em>Display error message.</em></p>
<h4>Parameters</h4>
@@ -506,7 +507,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -106,12 +106,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -136,15 +136,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-805317831"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-112631378"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-805317831" class="accordion-body collapse in">
<div id="namespace-112631378" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -240,7 +241,7 @@ config-file imgtest_config.php.</em></p>
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
<?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(
/**
* Set mode as 'strict', 'production' or 'development'.
*
* Default values:
* mode: 'production'
*/
//'mode' => 'production', // 'development', 'strict'
/**
* Where are the sources for the classfiles.
*
* Default values:
* autoloader: null // used from v0.6.2
* cimage_class: null // used until v0.6.1
*/
'autoloader' => __DIR__ . '/../autoload.php',
//'cimage_class' => __DIR__ . '/../CImage.php',
/**
* Paths, where are the images stored and where is the cache.
* End all paths with a slash.
*
* Default values:
* image_path: __DIR__ . '/img/'
* cache_path: __DIR__ . '/../cache/'
* alias_path: null
*/
'image_path' => __DIR__ . '/img/',
'cache_path' => __DIR__ . '/../cache/',
//'alias_path' => __DIR__ . '/img/alias/',
/**
* Use password to protect from missusage, send &pwd=... or &password=..
* with the request to match the password or set to false to disable.
* Passwords are only used together with options for remote download
* and aliasing.
*
* Create a passwords like this, depending on the type used:
* text: 'my_password'
* md5: md5('my_password')
* hash: password_hash('my_password', PASSWORD_DEFAULT)
*
* Default values.
* password_always: false // do not always require password,
* password: false // as in do not use password
* password_type: 'text' // use plain password, not encoded,
*/
//'password_always' => false, // always require password,
//'password' => false, // "secret-password",
//'password_type' => 'text', // supports 'text', 'md5', 'hash',
/**
* Allow or disallow downloading of remote images available on
* remote servers. Default is to disallow remote download.
*
* When enabling remote download, the default is to allow download any
* link starting with http or https. This can be changed using
* remote_pattern.
*
* When enabling remote_whitelist a check is made that the hostname of the
* source to download matches the whitelist. By default the check is
* disabled and thereby allowing download from any hosts.
*
* Default values.
* remote_allow: false
* remote_pattern: null // use default values from CImage which is to
* // allow download from any http- and
* // https-source.
* remote_whitelist: null // use default values from CImage which is to
* // allow download from any hosts.
*/
//'remote_allow' => true,
//'remote_pattern' => '#^https?://#',
//'remote_whitelist' => array(
// '\.facebook\.com$',
// '^(?:images|photos-[a-z])\.ak\.instagram\.com$',
// '\.google\.com$'
//),
/**
* A regexp for validating characters in the image or alias filename.
*
* Default value:
* valid_filename: '#^[a-z0-9A-Z-/_ \.:]+$#'
* valid_aliasname: '#^[a-z0-9A-Z-_]+$#'
*/
//'valid_filename' => '#^[a-z0-9A-Z-/_ \.:]+$#',
//'valid_aliasname' => '#^[a-z0-9A-Z-_]+$#',
/**
* Change the default values for CImage quality and compression used
* when saving images.
*
* Default value:
* jpg_quality: null, integer between 0-100
* png_compression: null, integer between 0-9
*/
//'jpg_quality' => 75,
//'png_compression' => 1,
/**
* A function (hook) can be called after img.php has processed all
* configuration options and before processing the image using CImage.
* The function receives the $img variabel and an array with the
* majority of current settings.
*
* Default value:
* hook_before_CImage: null
*/
/*'hook_before_CImage' => function (CImage $img, Array $allConfig) {
if ($allConfig['newWidth'] > 10) {
$allConfig['newWidth'] *= 2;
}
return $allConfig;
},*/
/**
* Add header for cache control when outputting images.
*
* Default value:
* cache_control: null, or set to string
*/
//'cache_control' => "max-age=86400",
/**
* The name representing a dummy image which is automatically created
* and stored at the defined path. The dummy image can then be used
* inplace of an original image as a placeholder.
* The dummy_dir must be writable and it defaults to a subdir of the
* cache directory.
* Write protect the dummy_dir to prevent creation of new dummy images,
* but continue to use the existing ones.
*
* Default value:
* dummy_enabled: true as default, disable dummy feature by setting
* to false.
* dummy_filename: 'dummy' use this as ?src=dummy to create a dummy image.
* dummy_dir: Defaults to subdirectory of 'cache_path',
* named the same as 'dummy_filename'
*/
//'dummy_enabled' => true,
//'dummy_filename' => 'dummy',
//'dummy_dir' => 'some writable directory',
/**
* Check that the imagefile is a file below 'image_path' using realpath().
* Security constraint to avoid reaching images outside image_path.
* This means that symbolic links to images outside the image_path will fail.
*
* Default value:
* image_path_constraint: true
*/
//'image_path_constraint' => false,
/**
* Set default timezone.
*
* Default values.
* default_timezone: ini_get('default_timezone') or 'UTC'
*/
//'default_timezone' => 'UTC',
/**
* Max image dimensions, larger dimensions results in 404.
* This is basically a security constraint to avoid using resources on creating
* large (unwanted) images.
*
* Default values.
* max_width: 2000
* max_height: 2000
*/
//'max_width' => 2000,
//'max_height' => 2000,
/**
* Set default background color for all images. Override it using
* option bgColor.
* Colorvalue is 6 digit hex string between 000000-FFFFFF
* or 8 digit hex string if using the alpha channel where
* the alpha value is between 00 (opaqe) and 7F (transparent),
* that is between 00000000-FFFFFF7F.
*
* Default values.
* background_color: As specified by CImage
*/
//'background_color' => "FFFFFF",
//'background_color' => "FFFFFF7F",
/**
* Post processing of images using external tools, set to true or false
* and set command to be executed.
*
* Default values.
*
* 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'
*/
/*
'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',
),
*/
/**
* Create custom convolution expressions, matrix 3x3, divisor and
* offset.
*
* Default values.
* convolution_constant: array()
*/
/*
'convolution_constant' => array(
//'sharpen' => '-1,-1,-1, -1,16,-1, -1,-1,-1, 8, 0',
//'sharpen-alt' => '0,-1,0, -1,5,-1, 0,-1,0, 1, 0',
),
*/
/**
* Prevent leeching of images by controlling the hostname of those who
* can access the images. Default is to allow hotlinking.
*
* Password apply when hotlinking is disallowed, use password to allow
* hotlinking.
*
* The whitelist is an array of regexpes for allowed hostnames that can
* hotlink images.
*
* Default values.
* allow_hotlinking: true
* hotlinking_whitelist: array()
*/
/*
'allow_hotlinking' => false,
'hotlinking_whitelist' => array(
'^dbwebb\.se$',
),
*/
/**
* Create custom shortcuts for more advanced expressions.
*
* Default values.
* shortcut: array(
* 'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
* )
*/
/*
'shortcut' => array(
'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
),*/
/**
* Predefined size constants.
*
* These can be used together with &width or &height to create a constant value
* for a width or height where can be changed in one place.
* Useful when your site changes its layout or if you have a grid to fit images into.
*
* Example:
* &width=w1 // results in width=613
* &width=c2 // results in spanning two columns with a gutter, 30*2+10=70
* &width=c24 // results in spanning whole grid 24*30+((24-1)*10)=950
*
* Default values.
* size_constant: As specified by the function below.
*/
/*
'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;
},*/
/**
* Predefined aspect ratios.
*
* Default values.
* aspect_ratio_constant: As the function below.
*/
/*'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,
);
},*/
/**
* default options for ascii image.
*
* Default values as specified below in the array.
* ascii-options:
* characterSet: Choose any character set available in CAsciiArt.
* scale: How many pixels should each character
* translate to.
* luminanceStrategy: Choose any strategy available in CAsciiArt.
* customCharacterSet: Define your own character set.
*/
/*'ascii-options' => array(
"characterSet" => 'two',
"scale" => 14,
"luminanceStrategy" => 3,
"customCharacterSet" => null,
);
},*/
);

View File

@@ -83,12 +83,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -152,7 +152,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -4,32 +4,37 @@
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: G Pages: 1 -->
<svg width="138pt" height="258pt"
viewBox="0.00 0.00 138.00 258.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 254)">
<svg width="138pt" height="312pt"
viewBox="0.00 0.00 138.00 312.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 308)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-254 134,-254 134,4 -4,4"/>
<polygon fill="white" stroke="none" points="-4,4 -4,-308 134,-308 134,4 -4,4"/>
<g id="clust1" class="cluster"><title>cluster_Global</title>
<path fill="none" stroke="gray" d="M20,-8C20,-8 110,-8 110,-8 116,-8 122,-14 122,-20 122,-20 122,-230 122,-230 122,-236 116,-242 110,-242 110,-242 20,-242 20,-242 14,-242 8,-236 8,-230 8,-230 8,-20 8,-20 8,-14 14,-8 20,-8"/>
<text text-anchor="middle" x="65" y="-229.2" font-family="Times,serif" font-size="11.00" fill="gray">Global</text>
<path fill="none" stroke="gray" d="M20,-8C20,-8 110,-8 110,-8 116,-8 122,-14 122,-20 122,-20 122,-284 122,-284 122,-290 116,-296 110,-296 110,-296 20,-296 20,-296 14,-296 8,-290 8,-284 8,-284 8,-20 8,-20 8,-14 14,-8 20,-8"/>
<text text-anchor="middle" x="65" y="-283.2" font-family="Times,serif" font-size="11.00" fill="gray">Global</text>
</g>
<!-- \\CRemoteImage -->
<g id="node1" class="node"><title>\\CRemoteImage</title>
<polygon fill="none" stroke="black" points="114,-214 16,-214 16,-178 114,-178 114,-214"/>
<text text-anchor="middle" x="65" y="-193.2" font-family="Courier,monospace" font-size="11.00">CRemoteImage</text>
<polygon fill="none" stroke="black" points="114,-268 16,-268 16,-232 114,-232 114,-268"/>
<text text-anchor="middle" x="65" y="-247.2" font-family="Courier,monospace" font-size="11.00">CRemoteImage</text>
</g>
<!-- \\CImage -->
<g id="node2" class="node"><title>\\CImage</title>
<polygon fill="none" stroke="black" points="93.5,-160 36.5,-160 36.5,-124 93.5,-124 93.5,-160"/>
<text text-anchor="middle" x="65" y="-139.2" font-family="Courier,monospace" font-size="11.00">CImage</text>
<polygon fill="none" stroke="black" points="93.5,-214 36.5,-214 36.5,-178 93.5,-178 93.5,-214"/>
<text text-anchor="middle" x="65" y="-193.2" font-family="Courier,monospace" font-size="11.00">CImage</text>
</g>
<!-- \\CAsciiArt -->
<g id="node3" class="node"><title>\\CAsciiArt</title>
<polygon fill="none" stroke="black" points="103.5,-160 26.5,-160 26.5,-124 103.5,-124 103.5,-160"/>
<text text-anchor="middle" x="65" y="-139.2" font-family="Courier,monospace" font-size="11.00">CAsciiArt</text>
</g>
<!-- \\CHttpGet -->
<g id="node3" class="node"><title>\\CHttpGet</title>
<g id="node4" class="node"><title>\\CHttpGet</title>
<polygon fill="none" stroke="black" points="100.5,-106 29.5,-106 29.5,-70 100.5,-70 100.5,-106"/>
<text text-anchor="middle" x="65" y="-85.2" font-family="Courier,monospace" font-size="11.00">CHttpGet</text>
</g>
<!-- \\CWhitelist -->
<g id="node4" class="node"><title>\\CWhitelist</title>
<g id="node5" class="node"><title>\\CWhitelist</title>
<polygon fill="none" stroke="black" points="107,-52 23,-52 23,-16 107,-16 107,-52"/>
<text text-anchor="middle" x="65" y="-31.2" font-family="Courier,monospace" font-size="11.00">CWhitelist</text>
</g>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -58,12 +58,12 @@
<ul class="dropdown-menu">
<li>
<a href="reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -88,15 +88,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-11723610"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-774114870"></a>
<a href="namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-11723610" class="accordion-body collapse in">
<div id="namespace-774114870" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="classes/CImage.html">CImage</a></li>
<li class="class"><a href="classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="classes/CWhitelist.html">CWhitelist</a></li>
@@ -123,6 +124,10 @@
<h2>Classes</h2>
<table class="table table-hover">
<tr>
<td><a href="classes/CAsciiArt.html">CAsciiArt</a></td>
<td><em>Create an ASCII version of an image.</em></td>
</tr>
<tr>
<td><a href="classes/CHttpGet.html">CHttpGet</a></td>
<td><em>Get a image from a remote server using HTTP GET and If-Modified-Since.</em></td>
</tr>
@@ -166,7 +171,7 @@
<h3 class=" ">errorPage()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">errorPage(string <span class="argument">$msg</span>) : void</pre>
<p><em>Default configuration options, can be overridden in own config-file.</em></p>
<p><em>Display error message.</em></p>
<h4>Parameters</h4>
@@ -443,7 +448,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -58,12 +58,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -88,15 +88,16 @@
<div class="accordion" style="margin-bottom: 0">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1315371834"></a>
<a class="accordion-toggle " data-toggle="collapse" data-target="#namespace-1997823667"></a>
<a href="../namespaces/default.html" style="margin-left: 30px; padding-left: 0">\</a>
</div>
<div id="namespace-1315371834" class="accordion-body collapse in">
<div id="namespace-1997823667" class="accordion-body collapse in">
<div class="accordion-inner">
<ul>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CAsciiArt.html">CAsciiArt</a></li>
<li class="class"><a href="../classes/CHttpGet.html">CHttpGet</a></li>
<li class="class"><a href="../classes/CImage.html">CImage</a></li>
<li class="class"><a href="../classes/CRemoteImage.html">CRemoteImage</a></li>
<li class="class"><a href="../classes/CWhitelist.html">CWhitelist</a></li>
@@ -123,6 +124,10 @@
<h2>Classes</h2>
<table class="table table-hover">
<tr>
<td><a href="../classes/CAsciiArt.html">CAsciiArt</a></td>
<td><em>Create an ASCII version of an image.</em></td>
</tr>
<tr>
<td><a href="../classes/CHttpGet.html">CHttpGet</a></td>
<td><em>Get a image from a remote server using HTTP GET and If-Modified-Since.</em></td>
</tr>
@@ -166,7 +171,7 @@
<h3 class=" ">errorPage()</h3>
<a href="#source-view" role="button" class="pull-right btn" data-toggle="modal" style="font-size: 1.1em; padding: 9px 14px"><i class="icon-code"></i></a>
<pre class="signature" style="margin-right: 54px;">errorPage(string <span class="argument">$msg</span>) : void</pre>
<p><em>Default configuration options, can be overridden in own config-file.</em></p>
<p><em>Display error message.</em></p>
<h4>Parameters</h4>
@@ -443,7 +448,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -59,12 +59,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -142,7 +142,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -59,12 +59,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -91,6 +91,7 @@
<li class="nav-header">Navigation</li>
<li><a href="#CRemoteImage.php"><i class="icon-file"></i> CRemoteImage.php</a></li>
<li><a href="#CImage.php"><i class="icon-file"></i> CImage.php</a></li>
<li><a href="#CAsciiArt.php"><i class="icon-file"></i> CAsciiArt.php</a></li>
<li><a href="#CHttpGet.php"><i class="icon-file"></i> CHttpGet.php</a></li>
<li><a href="#CWhitelist.php"><i class="icon-file"></i> CWhitelist.php</a></li>
</ul>
@@ -110,7 +111,7 @@
<h3>
<i class="icon-file"></i>
CRemoteImage.php
<small style="float: right;padding-right: 10px;">2</small>
<small style="float: right;padding-right: 10px;">1</small>
</h3>
<div>
<table class="table markers table-bordered">
@@ -126,11 +127,6 @@
<td>error</td>
<td>0</td>
<td>No summary was found for this file</td>
</tr>
<tr>
<td>error</td>
<td>119</td>
<td>Argument $path is missing from the Docblock of setCache()</td>
</tr>
</tbody>
</table>
@@ -141,7 +137,7 @@
<h3>
<i class="icon-file"></i>
CImage.php
<small style="float: right;padding-right: 10px;">21</small>
<small style="float: right;padding-right: 10px;">34</small>
</h3>
<div>
<table class="table markers table-bordered">
@@ -160,103 +156,194 @@
</tr>
<tr>
<td>error</td>
<td>1042</td>
<td>Argument $saveAs is missing from the Docblock of setSaveAsExtension()</td>
<td>1641</td>
<td>Argument $dst_image is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1702</td>
<td>Argument $bgColor is missing from the Docblock of rotate()</td>
<td>1641</td>
<td>Argument $src_image is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>87</td>
<td>1641</td>
<td>Argument $dst_x is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $dst_y is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $src_x is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $src_y is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $dst_w is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $dst_h is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $src_w is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>1641</td>
<td>Argument $src_h is missing from the Docblock of imageCopyResampled</td>
</tr>
<tr>
<td>error</td>
<td>94</td>
<td>No summary for property $bgColorDefault</td>
</tr>
<tr>
<td>error</td>
<td>216</td>
<td>196</td>
<td>No summary for property $pngFilterCmd</td>
</tr>
<tr>
<td>error</td>
<td>204</td>
<td>No summary for property $pngDeflateCmd</td>
</tr>
<tr>
<td>error</td>
<td>212</td>
<td>No summary for property $jpegOptimizeCmd</td>
</tr>
<tr>
<td>error</td>
<td>220</td>
<td>No summary for property $height</td>
</tr>
<tr>
<td>error</td>
<td>223</td>
<td>227</td>
<td>No summary for property $newWidthOrig</td>
</tr>
<tr>
<td>error</td>
<td>224</td>
<td>228</td>
<td>No summary for property $newHeight</td>
</tr>
<tr>
<td>error</td>
<td>225</td>
<td>229</td>
<td>No summary for property $newHeightOrig</td>
</tr>
<tr>
<td>error</td>
<td>238</td>
<td>242</td>
<td>No summary for property $upscale</td>
</tr>
<tr>
<td>error</td>
<td>246</td>
<td>250</td>
<td>No summary for property $cropOrig</td>
</tr>
<tr>
<td>error</td>
<td>296</td>
<td>350</td>
<td>No summary for property $fillHeight</td>
</tr>
<tr>
<td>error</td>
<td>311</td>
<td>365</td>
<td>No summary for property $remotePattern</td>
</tr>
<tr>
<td>error</td>
<td>329</td>
<td>380</td>
<td>No summary for property $remoteHostWhitelist</td>
</tr>
<tr>
<td>error</td>
<td>387</td>
<td>No summary for property $verboseFileName</td>
</tr>
<tr>
<td>error</td>
<td>394</td>
<td>No summary for property $asciiOptions</td>
</tr>
<tr>
<td>error</td>
<td>403</td>
<td>No summary for property $copyStrategy</td>
</tr>
<tr>
<td>error</td>
<td>415</td>
<td>No summary for property $cropToFit</td>
</tr>
<tr>
<td>error</td>
<td>330</td>
<td>416</td>
<td>No summary for property $cropWidth</td>
</tr>
<tr>
<td>error</td>
<td>331</td>
<td>417</td>
<td>No summary for property $cropHeight</td>
</tr>
<tr>
<td>error</td>
<td>332</td>
<td>418</td>
<td>No summary for property $crop_x</td>
</tr>
<tr>
<td>error</td>
<td>333</td>
<td>419</td>
<td>No summary for property $crop_y</td>
</tr>
<tr>
<td>error</td>
<td>334</td>
<td>420</td>
<td>No summary for property $filters</td>
</tr>
<tr>
<td>error</td>
<td>335</td>
<td>No summary for property $type</td>
</tr>
<tr>
<td>error</td>
<td>336</td>
<td>421</td>
<td>No summary for property $attr</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="package-contents">
<a name="CAsciiArt.php" id="CAsciiArt.php"></a>
<h3>
<i class="icon-file"></i>
CAsciiArt.php
<small style="float: right;padding-right: 10px;">1</small>
</h3>
<div>
<table class="table markers table-bordered">
<thead>
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>error</td>
<td>337</td>
<td>No summary for property $useOriginal</td>
<td>0</td>
<td>No summary was found for this file</td>
</tr>
</tbody>
</table>
@@ -367,7 +454,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

View File

@@ -59,12 +59,12 @@
<ul class="dropdown-menu">
<li>
<a href="../reports/errors.html">
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">27</span>
<i class="icon-list-alt"></i>&#160;Errors <span class="label label-info pull-right">40</span>
</a>
</li>
<li>
<a href="../reports/markers.html">
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">164</span>
<i class="icon-list-alt"></i>&#160;Markers <span class="label label-info pull-right">2</span>
</a>
</li>
<li>
@@ -88,13 +88,8 @@
<div class="span2 sidebar">
<ul class="side-nav nav nav-list">
<li class="nav-header">Navigation</li>
<li><a href="#webroot/img.php"><i class="icon-file"></i> webroot/img.php</a></li>
<li><a href="#CRemoteImage.php"><i class="icon-file"></i> CRemoteImage.php</a></li>
<li><a href="#CImage.php"><i class="icon-file"></i> CImage.php</a></li>
<li><a href="#webroot/img_config.php"><i class="icon-file"></i> webroot/img_config.php</a></li>
<li><a href="#CHttpGet.php"><i class="icon-file"></i> CHttpGet.php</a></li>
<li><a href="#autoload.php"><i class="icon-file"></i> autoload.php</a></li>
</ul>
<li><a href="#CImage.php"><i class="icon-file"></i> CImage.php</a></li>
</ul>
</div>
<div class="span10 offset2">
@@ -106,196 +101,12 @@
<div id="marker-accordion">
<div class="package-contents">
<a name="webroot/img.php" id="webroot/img.php"></a>
<h3>
<i class="icon-file"></i>
webroot/img.php
<small style="float: right;padding-right: 10px;">25</small>
</h3>
<div>
<table class="table markers table-bordered">
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
<tr>
<td></td>
<td>6</td>
<td>dbwebb.se/opensource/cimage</td>
</tr>
<tr>
<td></td>
<td>7</td>
<td>github.com/mosbth/cimage</td>
</tr>
<tr>
<td></td>
<td>158</td>
<td>Settings for any mode</td>
</tr>
<tr>
<td></td>
<td>166</td>
<td>Specific settings for each mode</td>
</tr>
<tr>
<td></td>
<td>217</td>
<td>Check if passwords match, if configured to use passwords</td>
</tr>
<tr>
<td></td>
<td>249</td>
<td>Always allow when password match</td>
</tr>
<tr>
<td></td>
<td>255</td>
<td>Allow when serverName matches refererHost</td>
</tr>
<tr>
<td></td>
<td>346</td>
<td>Check for valid/invalid characters</td>
</tr>
<tr>
<td></td>
<td>356</td>
<td>If source is a remote file, ignore local file checks.</td>
</tr>
<tr>
<td></td>
<td>360</td>
<td>Check that the image is a file below the directory &#039;image_path&#039;.</td>
</tr>
<tr>
<td></td>
<td>387</td>
<td>Set sizes to map constant to value, easier to use with width or height</td>
</tr>
<tr>
<td></td>
<td>393</td>
<td>Add grid column width, useful for use as predefined size for width (or height).</td>
</tr>
<tr>
<td></td>
<td>415</td>
<td>Check to replace predefined size</td>
</tr>
<tr>
<td></td>
<td>420</td>
<td>Support width as % of original width</td>
</tr>
<tr>
<td></td>
<td>440</td>
<td>Check to replace predefined size</td>
</tr>
<tr>
<td></td>
<td>445</td>
<td>height</td>
</tr>
<tr>
<td></td>
<td>475</td>
<td>Check to replace predefined aspect ratio</td>
</tr>
<tr>
<td></td>
<td>750</td>
<td>php.net/manual/en/function.imageconvolution.php</td>
</tr>
<tr>
<td></td>
<td>755</td>
<td>Check if the convolve is matching an existing constant</td>
</tr>
<tr>
<td></td>
<td>835</td>
<td>code.jquery.com/jquery-2.1.1.min.js&quot;&gt;&lt;/script&gt;</td>
</tr>
<tr>
<td></td>
<td>866</td>
<td>Options for calculate dimensions</td>
</tr>
<tr>
<td></td>
<td>877</td>
<td>Pre-processing, before resizing is done</td>
</tr>
<tr>
<td></td>
<td>882</td>
<td>General processing options</td>
</tr>
<tr>
<td></td>
<td>885</td>
<td>Post-processing, after resizing is done</td>
</tr>
<tr>
<td></td>
<td>894</td>
<td>Output format</td>
</tr>
</table>
</div>
</div>
<div class="package-contents">
<a name="CRemoteImage.php" id="CRemoteImage.php"></a>
<h3>
<i class="icon-file"></i>
CRemoteImage.php
<small style="float: right;padding-right: 10px;">5</small>
</h3>
<div>
<table class="table markers table-bordered">
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
<tr>
<td></td>
<td>227</td>
<td>Save only if body is a valid image</td>
</tr>
<tr>
<td></td>
<td>279</td>
<td>First check if the cache is valid and can be used</td>
</tr>
<tr>
<td></td>
<td>290</td>
<td>Do a HTTP request to download item</td>
</tr>
<tr>
<td></td>
<td>336</td>
<td>Is cache valid?</td>
</tr>
<tr>
<td></td>
<td>344</td>
<td>Prepare for a 304 if available</td>
</tr>
</table>
</div>
</div>
<div class="package-contents">
<div class="package-contents">
<a name="CImage.php" id="CImage.php"></a>
<h3>
<i class="icon-file"></i>
CImage.php
<small style="float: right;padding-right: 10px;">93</small>
<small style="float: right;padding-right: 10px;">2</small>
</h3>
<div>
<table class="table markers table-bordered">
@@ -305,730 +116,19 @@
<th>Description</th>
</tr>
<tr>
<td></td>
<td>6</td>
<td>dbwebb.se/opensource/cimage</td>
</tr>
<tr>
<td></td>
<td>7</td>
<td>github.com/mosbth/cimage</td>
</tr>
<tr>
<td></td>
<td>86</td>
<td>private $bgColorDefault = self::BACKGROUND_COLOR;</td>
</tr>
<tr>
<td></td>
<td>215</td>
<td>Calculated from source image</td>
</tr>
<tr>
<td></td>
<td>216</td>
<td>Calculated from source image</td>
</tr>
<tr>
<td></td>
<td>223</td>
<td>Save original value</td>
</tr>
<tr>
<td></td>
<td>225</td>
<td>Save original value</td>
</tr>
<tr>
<td></td>
<td>246</td>
<td>Save original value</td>
</tr>
<tr>
<td></td>
<td>310</td>
<td>private $remotePattern = &#039;#^[http|https]://#&#039;;</td>
</tr>
<tr>
<td></td>
<td>311</td>
<td>#&#039;;</td>
</tr>
<tr>
<td></td>
<td>335</td>
<td>Calculated from source image</td>
</tr>
<tr>
<td></td>
<td>336</td>
<td>Calculated from source image</td>
</tr>
<tr>
<td></td>
<td>337</td>
<td>Use original image if possible</td>
</tr>
<tr>
<td></td>
<td>603</td>
<td>Sanitize filename</td>
</tr>
<tr>
<td></td>
<td>624</td>
<td>Options for calculate dimensions</td>
</tr>
<tr>
<td></td>
<td>631</td>
<td>array(&#039;width&#039;=&gt;null, &#039;height&#039;=&gt;null, &#039;start_x&#039;=&gt;0, &#039;start_y&#039;=&gt;0),</td>
</tr>
<tr>
<td></td>
<td>632</td>
<td>&#039;0,0,0,0&#039;,</td>
</tr>
<tr>
<td></td>
<td>635</td>
<td>Options for caching or using original</td>
</tr>
<tr>
<td></td>
<td>639</td>
<td>Pre-processing, before resizing is done</td>
</tr>
<tr>
<td></td>
<td>644</td>
<td>General options</td>
</tr>
<tr>
<td></td>
<td>647</td>
<td>Post-processing, after resizing is done</td>
</tr>
<tr>
<td></td>
<td>656</td>
<td>Output format</td>
</tr>
<tr>
<td></td>
<td>660</td>
<td>Options for saving</td>
</tr>
<tr>
<td></td>
<td>661</td>
<td>&#039;quality&#039; =&gt; null,</td>
</tr>
<tr>
<td></td>
<td>662</td>
<td>&#039;compress&#039; =&gt; null,</td>
</tr>
<tr>
<td></td>
<td>663</td>
<td>&#039;saveAs&#039; =&gt; null,</td>
</tr>
<tr>
<td></td>
<td>666</td>
<td>Convert crop settings from string to array</td>
</tr>
<tr>
<td></td>
<td>677</td>
<td>Convert area settings from string to array</td>
</tr>
<tr>
<td></td>
<td>688</td>
<td>Convert filter settings from array of string to array of array</td>
</tr>
<tr>
<td></td>
<td>700</td>
<td>php.net/manual/en/function.imagefilter.php&#039;</td>
</tr>
<tr>
<td></td>
<td>708</td>
<td>Merge default arguments with incoming and set properties.</td>
</tr>
<tr>
<td></td>
<td>709</td>
<td>$args = array_merge_recursive($defaults, $args);</td>
</tr>
<tr>
<td></td>
<td>719</td>
<td>Save original values to enable re-calculating</td>
</tr>
<tr>
<td></td>
<td>778</td>
<td>Get details on image</td>
</tr>
<tr>
<td></td>
<td>805</td>
<td>width as %</td>
</tr>
<tr>
<td></td>
<td>811</td>
<td>height as %</td>
</tr>
<tr>
<td></td>
<td>819</td>
<td>width &amp; height from aspect ratio</td>
</tr>
<tr>
<td></td>
<td>841</td>
<td>Change width &amp; height based on dpr</td>
</tr>
<tr>
<td></td>
<td>853</td>
<td>Check values to be within domain</td>
</tr>
<tr>
<td></td>
<td>876</td>
<td>Crop, use cropped width and height as base for calulations</td>
</tr>
<tr>
<td></td>
<td>881</td>
<td>Check if there is an area to crop off</td>
</tr>
<tr>
<td></td>
<td>898</td>
<td>Check if crop is set</td>
</tr>
<tr>
<td></td>
<td>922</td>
<td>Calculate new width and height if keeping aspect-ratio.</td>
</tr>
<tr>
<td></td>
<td>927</td>
<td>Crop-to-fit and both new width and height are set.</td>
</tr>
<tr>
<td></td>
<td>930</td>
<td>Use newWidth and newHeigh as width/height, image should fit in box.</td>
</tr>
<tr>
<td></td>
<td>935</td>
<td>Both new width and height are set.</td>
</tr>
<tr>
<td></td>
<td>936</td>
<td>Use newWidth and newHeigh as max width/height, image should not be larger.</td>
</tr>
<tr>
<td></td>
<td>946</td>
<td>Use new width as max-width</td>
</tr>
<tr>
<td></td>
<td>953</td>
<td>Use new height as max-hight</td>
</tr>
<tr>
<td></td>
<td>960</td>
<td>Get image dimensions for pre-resize image.</td>
</tr>
<tr>
<td></td>
<td>963</td>
<td>Get relations of original &amp; target image</td>
</tr>
<tr>
<td></td>
<td>969</td>
<td>Use newWidth and newHeigh as defined width/height,</td>
</tr>
<tr>
<td></td>
<td>970</td>
<td>image should fit the area.</td>
</tr>
<tr>
<td></td>
<td>979</td>
<td>Use newWidth and newHeigh as defined width/height,</td>
</tr>
<tr>
<td></td>
<td>980</td>
<td>image should fit the area.</td>
</tr>
<tr>
<td></td>
<td>990</td>
<td>Crop, ensure to set new width and height</td>
</tr>
<tr>
<td></td>
<td>997</td>
<td>Fill to fit, ensure to set new width and height</td>
</tr>
<tr>
<td></td>
<td>1004</td>
<td>No new height or width is set, use existing measures.</td>
</tr>
<tr>
<td></td>
<td>1417</td>
<td>Rotate image</td>
</tr>
<tr>
<td></td>
<td>1424</td>
<td>Auto-rotate image</td>
</tr>
<tr>
<td></td>
<td>1431</td>
<td>Scale the original image before starting</td>
</tr>
<tr>
<td></td>
<td>1459</td>
<td>Only use a specified area of the image, $this-&gt;offset is defining the area to use</td>
</tr>
<tr>
<td></td>
<td>1472</td>
<td>Do as crop, take only part of image</td>
</tr>
<tr>
<td></td>
<td>1482</td>
<td>Consider rewriting the no-upscale code to fit within this if-statement,</td>
</tr>
<tr>
<td></td>
<td>1483</td>
<td>likely to be more readable code.</td>
</tr>
<tr>
<td></td>
<td>1484</td>
<td>The code is more or leass equal in below crop-to-fit, fill-to-fit and stretch</td>
</tr>
<tr>
<td></td>
<td>1489</td>
<td>Resize by crop to fit</td>
</tr>
<tr>
<td></td>
<td>1526</td>
<td>Resize by fill to fit</td>
</tr>
<tr>
<td></td>
<td>1535</td>
<td>Check ratio for landscape or portrait</td>
</tr>
<tr>
<td></td>
<td>1565</td>
<td>Resize it</td>
</tr>
<tr>
<td></td>
<td>1592</td>
<td>$this-&gt;log(&quot;posX=$posX, posY=$posY, cropX=$cropX, cropY=$cropY.&quot;);</td>
</tr>
<tr>
<td></td>
<td>1622</td>
<td>Rotate image</td>
</tr>
<tr>
<td></td>
<td>1628</td>
<td>Apply filters</td>
</tr>
<tr>
<td></td>
<td>1659</td>
<td>Convert to palette image</td>
</tr>
<tr>
<td></td>
<td>1665</td>
<td>Blur the image</td>
</tr>
<tr>
<td></td>
<td>1671</td>
<td>Emboss the image</td>
</tr>
<tr>
<td></td>
<td>1677</td>
<td>Sharpen the image</td>
</tr>
<tr>
<td></td>
<td>1683</td>
<td>Custom convolution</td>
</tr>
<tr>
<td></td>
<td>1685</td>
<td>$this-&gt;log(&quot;Convolve: &quot; . $this-&gt;convolve);</td>
</tr>
<tr>
<td></td>
<td>1764</td>
<td>stackoverflow.com/questions/5752514/how-to-convert-png-to-8-bit-png-using-php-gd-library</td>
</tr>
<tr>
<td></td>
<td>1837</td>
<td>Check of matching constant</td>
</tr>
<tr>
<td></td>
<td>1845</td>
<td>Expect list of 11 numbers, split by , and build up arguments</td>
</tr>
<tr>
<td></td>
<td>1897</td>
<td>Use incoming options or use $this.</td>
</tr>
<tr>
<td></td>
<td>1900</td>
<td>Treat incoming as string, split by +</td>
</tr>
<tr>
<td></td>
<td>1904</td>
<td>Check each option if it matches constant value</td>
</tr>
<tr>
<td></td>
<td>2110</td>
<td>Use JPEG optimize if defined</td>
</tr>
<tr>
<td></td>
<td>2133</td>
<td>Turn off alpha blending and set alpha flag</td>
</tr>
<tr>
<td></td>
<td>2138</td>
<td>Use external program to filter PNG, if defined</td>
</tr>
<tr>
<td></td>
<td>2151</td>
<td>Use external program to deflate PNG, if defined</td>
</tr>
<tr>
<td></td>
<td>2244</td>
<td>Get image modification time</td>
</tr>
<tr>
<td></td>
<td>2271</td>
<td>Get details on image</td>
</tr>
<tr>
<td>TODO</td>
<td>383</td>
<td>467</td>
<td>clean up how $this-&gt;saveFolder is used in other methods.</td>
</tr>
<tr>
<td>TODO</td>
<td>328</td>
<td>414</td>
<td>Clean up these and check if and how they are used</td>
</tr>
</table>
</div>
</div>
<div class="package-contents">
<a name="webroot/img_config.php" id="webroot/img_config.php"></a>
<h3>
<i class="icon-file"></i>
webroot/img_config.php
<small style="float: right;padding-right: 10px;">36</small>
</h3>
<div>
<table class="table markers table-bordered">
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
<tr>
<td></td>
<td>17</td>
<td>&#039;mode&#039; =&gt; &#039;production&#039;, // &#039;development&#039;, &#039;strict&#039;</td>
</tr>
<tr>
<td></td>
<td>25</td>
<td>used from v0.6.2</td>
</tr>
<tr>
<td></td>
<td>26</td>
<td>used until v0.6.1</td>
</tr>
<tr>
<td></td>
<td>29</td>
<td>&#039;cimage_class&#039; =&gt; __DIR__ . &#039;/../CImage.php&#039;,</td>
</tr>
<tr>
<td></td>
<td>44</td>
<td>&#039;alias_path&#039; =&gt; __DIR__ . &#039;/img/alias/&#039;,</td>
</tr>
<tr>
<td></td>
<td>55</td>
<td>as in do not use password</td>
</tr>
<tr>
<td></td>
<td>56</td>
<td>do not always require password,</td>
</tr>
<tr>
<td></td>
<td>58</td>
<td>&#039;password&#039; =&gt; false, // &quot;secret-password&quot;,</td>
</tr>
<tr>
<td></td>
<td>59</td>
<td>&#039;password_always&#039; =&gt; false, // always require password,</td>
</tr>
<tr>
<td></td>
<td>77</td>
<td>use default values from CImage which is to</td>
</tr>
<tr>
<td></td>
<td>78</td>
<td>allow download from any http- and </td>
</tr>
<tr>
<td></td>
<td>79</td>
<td>https-source.</td>
</tr>
<tr>
<td></td>
<td>80</td>
<td>use default values from CImage which is to </td>
</tr>
<tr>
<td></td>
<td>81</td>
<td>allow download from any hosts.</td>
</tr>
<tr>
<td></td>
<td>83</td>
<td>&#039;remote_allow&#039; =&gt; true,</td>
</tr>
<tr>
<td></td>
<td>84</td>
<td>&#039;remote_pattern&#039; =&gt; &#039;#^https?://#&#039;,</td>
</tr>
<tr>
<td></td>
<td>85</td>
<td>&#039;remote_whitelist&#039; =&gt; array(</td>
</tr>
<tr>
<td></td>
<td>86</td>
<td>&#039;\.facebook\.com$&#039;,</td>
</tr>
<tr>
<td></td>
<td>87</td>
<td>&#039;^(?:images|photos-[a-z])\.ak\.instagram\.com$&#039;,</td>
</tr>
<tr>
<td></td>
<td>88</td>
<td>&#039;\.google\.com$&#039;</td>
</tr>
<tr>
<td></td>
<td>89</td>
<td>),</td>
</tr>
<tr>
<td></td>
<td>100</td>
<td>&#039;valid_filename&#039; =&gt; &#039;#^[a-z0-9A-Z-/_\.:]+$#&#039;,</td>
</tr>
<tr>
<td></td>
<td>101</td>
<td>&#039;valid_aliasname&#039; =&gt; &#039;#^[a-z0-9A-Z-_]+$#&#039;,</td>
</tr>
<tr>
<td></td>
<td>113</td>
<td>&#039;image_path_constraint&#039; =&gt; false,</td>
</tr>
<tr>
<td></td>
<td>123</td>
<td>&#039;default_timezone&#039; =&gt; &#039;UTC&#039;,</td>
</tr>
<tr>
<td></td>
<td>136</td>
<td>&#039;max_width&#039; =&gt; 2000,</td>
</tr>
<tr>
<td></td>
<td>137</td>
<td>&#039;max_height&#039; =&gt; 2000,</td>
</tr>
<tr>
<td></td>
<td>152</td>
<td>&#039;background_color&#039; =&gt; &quot;FFFFFF&quot;,</td>
</tr>
<tr>
<td></td>
<td>153</td>
<td>&#039;background_color&#039; =&gt; &quot;FFFFFF7F&quot;,</td>
</tr>
<tr>
<td></td>
<td>196</td>
<td>&#039;sharpen&#039; =&gt; &#039;-1,-1,-1, -1,16,-1, -1,-1,-1, 8, 0&#039;,</td>
</tr>
<tr>
<td></td>
<td>197</td>
<td>&#039;sharpen-alt&#039; =&gt; &#039;0,-1,0, -1,5,-1, 0,-1,0, 1, 0&#039;,</td>
</tr>
<tr>
<td></td>
<td>247</td>
<td>results in width=613</td>
</tr>
<tr>
<td></td>
<td>248</td>
<td>results in spanning two columns with a gutter, 30*2+10=70</td>
</tr>
<tr>
<td></td>
<td>249</td>
<td>results in spanning whole grid 24*30+((24-1)*10)=950</td>
</tr>
<tr>
<td></td>
<td>257</td>
<td>Set sizes to map constant to value, easier to use with width or height</td>
</tr>
<tr>
<td></td>
<td>263</td>
<td>Add grid column width, useful for use as predefined size for width (or height).</td>
</tr>
</table>
</div>
</div>
<div class="package-contents">
<a name="CHttpGet.php" id="CHttpGet.php"></a>
<h3>
<i class="icon-file"></i>
CHttpGet.php
<small style="float: right;padding-right: 10px;">1</small>
</h3>
<div>
<table class="table markers table-bordered">
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
<tr>
<td></td>
<td>211</td>
<td>max-age=2592000</td>
</tr>
</table>
</div>
</div>
<div class="package-contents">
<a name="autoload.php" id="autoload.php"></a>
<h3>
<i class="icon-file"></i>
autoload.php
<small style="float: right;padding-right: 10px;">4</small>
</h3>
<div>
<table class="table markers table-bordered">
<tr>
<th>Type</th>
<th>Line</th>
<th>Description</th>
</tr>
<tr>
<td></td>
<td>6</td>
<td>include __DIR__ . &quot;/../CHttpGet.php&quot;;</td>
</tr>
<tr>
<td></td>
<td>7</td>
<td>include __DIR__ . &quot;/../CRemoteImage.php&quot;;</td>
</tr>
<tr>
<td></td>
<td>8</td>
<td>include __DIR__ . &quot;/../CImage.php&quot;;</td>
</tr>
<tr>
<td></td>
<td>18</td>
<td>$path = CIMAGE_SOURCE_PATH . &quot;/{$class}.php&quot;;</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
@@ -1068,7 +168,7 @@
<section class="span10 offset1">
<hr />
Documentation is powered by <a href="http://www.phpdoc.org/">phpDocumentor </a> and authored
on March 6th, 2015 at 12:38.
on December 2nd, 2015 at 11:04.
</section>
</section>
</section>

186
functions.php Normal file
View File

@@ -0,0 +1,186 @@
<?php
/**
* General functions to use in img.php.
*/
/**
* Trace and log execution to logfile, useful for debugging and development.
*
* @param string $msg message to log to file.
*
* @return void
*/
function trace($msg)
{
$file = CIMAGE_DEBUG_FILE;
if (!is_writable($file)) {
return;
}
$timer = number_format((microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]), 6);
$details = "{$timer}ms";
$details .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
$details .= ":" . count(get_included_files());
file_put_contents($file, "$details:$msg\n", FILE_APPEND);
}
/**
* Display error message.
*
* @param string $msg to display.
* @param int $type of HTTP error to display.
*
* @return void
*/
function errorPage($msg, $type = 500)
{
global $mode;
switch ($type) {
case 403:
$header = "403 Forbidden";
break;
case 404:
$header = "404 Not Found";
break;
default:
$header = "500 Internal Server Error";
}
if ($mode == "strict") {
$header = "404 Not Found";
}
header("HTTP/1.0 $header");
if ($mode == "development") {
die("[img.php] $msg");
}
error_log("[img.php] $msg");
die("HTTP/1.0 $header");
}
/**
* 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 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;
}
/**
* Get value from config array or default if key is not set in config array.
*
* @param string $key the key in the config array.
* @param mixed $default value to be default if $key is not set in config.
*
* @return mixed value as $config[$key] or $default.
*/
function getConfig($key, $default)
{
global $config;
return isset($config[$key])
? $config[$key]
: $default;
}
/**
* 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, $verboseFile;
static $log = array();
if (!($verbose || $verboseFile)) {
return;
}
if (is_null($msg)) {
return $log;
}
$log[] = $msg;
}
/**
* Log when verbose mode, when used without argument it returns the result.
*
* @param string $msg to log.
*
* @return void or array.
*/
function checkExternalCommand($what, $enabled, $commandString)
{
$no = $enabled ? null : 'NOT';
$text = "Post processing $what is $no enabled.<br>";
list($command) = explode(" ", $commandString);
$no = is_executable($command) ? null : 'NOT';
$text .= "The command for $what is $no an executable.<br>";
return $text;
}

Binary file not shown.

View File

@@ -13,4 +13,10 @@
<log type="coverage-clover" target="coverage.clover" />
</logging>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<file>*.php</file>
</whitelist>
</filter>
</phpunit>

68
test/CCacheTest.php Normal file
View File

@@ -0,0 +1,68 @@
<?php
/**
* A testclass
*
*/
class CCacheTest extends \PHPUnit_Framework_TestCase
{
/**
* Test
*
* @return void
*/
public function testSetCacheDir()
{
$cache = new CCache();
$cache->setDir(CACHE_PATH);
$exp = "exists, writable";
$res = $cache->getStatusOfSubdir("");
$this->assertEquals($exp, $res, "Status of cache dir missmatch.");
}
/**
* Test
*
* @expectedException Exception
*
* @return void
*/
public function testSetWrongCacheDir()
{
$cache = new CCache();
$cache->setDir(CACHE_PATH . "/NO_EXISTS");
}
/**
* Test
*
* @return void
*/
public function testCreateSubdir()
{
$cache = new CCache();
$cache->setDir(CACHE_PATH);
$subdir = "__test__";
$cache->removeSubdir($subdir);
$exp = "does not exist";
$res = $cache->getStatusOfSubdir($subdir, false);
$this->assertEquals($exp, $res, "Subdir should not be created.");
$res = $cache->getPathToSubdir($subdir);
$exp = realpath(CACHE_PATH . "/$subdir");
$this->assertEquals($exp, $res, "Subdir path missmatch.");
$exp = "exists, writable";
$res = $cache->getStatusOfSubdir($subdir);
$this->assertEquals($exp, $res, "Subdir should exist.");
$res = $cache->removeSubdir($subdir);
$this->assertTrue($res, "Remove subdir.");
}
}

View File

@@ -5,6 +5,57 @@
*/
class CImageDummyTest extends \PHPUnit_Framework_TestCase
{
const DUMMY = "__dummy__";
private $cachepath;
/**
* Setup environment
*
* @return void
*/
protected function setUp()
{
$cache = new CCache();
$cache->setDir(CACHE_PATH);
$this->cachepath = $cache->getPathToSubdir(self::DUMMY);
}
/**
* Clean up cache dir content.
*
* @return void
*/
protected function removeFilesInCacheDir()
{
$files = glob($this->cachepath . "/*");
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
}
}
}
/**
* Teardown environment
*
* @return void
*/
protected function tearDown()
{
$cache = new CCache();
$cache->setDir(CACHE_PATH);
$this->removeFilesInCacheDir();
$cache->removeSubdir(self::DUMMY);
}
/**
* Test
*
@@ -14,15 +65,15 @@ class CImageDummyTest extends \PHPUnit_Framework_TestCase
{
$img = new CImage();
$img->setSaveFolder(CACHE_PATH . "/dummy");
$img->setSource('dummy', CACHE_PATH . "/dummy");
$img->setSaveFolder($this->cachepath);
$img->setSource(self::DUMMY, $this->cachepath);
$img->createDummyImage();
$img->generateFilename(null, false);
$img->save(null, null, false);
$filename = $img->getTarget();
$this->assertEquals(basename($filename), "dummy_100_100", "Filename not as expected on dummy image.");
$this->assertEquals(basename($filename), self::DUMMY . "_100_100", "Filename not as expected on dummy image.");
}
@@ -36,14 +87,14 @@ class CImageDummyTest extends \PHPUnit_Framework_TestCase
{
$img = new CImage();
$img->setSaveFolder(CACHE_PATH . "/dummy");
$img->setSource('dummy', CACHE_PATH . "/dummy");
$img->setSaveFolder($this->cachepath);
$img->setSource(self::DUMMY, $this->cachepath);
$img->createDummyImage(200, 400);
$img->generateFilename(null, false);
$img->save(null, null, false);
$filename = $img->getTarget();
$this->assertEquals(basename($filename), "dummy_200_400", "Filename not as expected on dummy image.");
$this->assertEquals(basename($filename), self::DUMMY . "_200_400", "Filename not as expected on dummy image.");
}
}

View File

@@ -61,7 +61,7 @@ class CImageRemoteDownloadTest extends \PHPUnit_Framework_TestCase
public function testAllowRemoteDownloadDefaultPatternValid($source)
{
$img = new CImage();
$img->setRemoteDownload(true);
$img->setRemoteDownload(true, "");
$res = $img->isRemoteSource($source);
$this->assertTrue($res, "Should be a valid remote source: '$source'.");
@@ -79,7 +79,7 @@ class CImageRemoteDownloadTest extends \PHPUnit_Framework_TestCase
public function testAllowRemoteDownloadDefaultPatternInvalid($source)
{
$img = new CImage();
$img->setRemoteDownload(true);
$img->setRemoteDownload(true, "");
$res = $img->isRemoteSource($source);
$this->assertFalse($res, "Should not be a valid remote source: '$source'.");

74
test/CImageSRGBTest.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
/**
* A testclass
*
*/
class CImageSRGBTest extends \PHPUnit_Framework_TestCase
{
private $srgbDir = "srgb";
private $cache;
private $srgbColorProfile;
/**
* Setup before test
*
* @return void
*/
protected function setUp()
{
$this->srgbColorProfile = __DIR__ . '/../icc/sRGB_IEC61966-2-1_black_scaled.icc';
$this->cache = CACHE_PATH . "/" . $this->srgbDir;
if (!is_writable($this->cache)) {
mkdir($this->cache);
}
}
/**
* Test
*
* @return void
*/
public function testCreate1()
{
$img = new CImage();
$filename = $img->convert2sRGBColorSpace(
'car.png',
IMAGE_PATH,
$this->cache,
$this->srgbColorProfile
);
if (class_exists("Imagick")) {
$this->assertEquals("srgb_car.png", basename($filename), "Filename not as expected on image.");
} else {
$this->assertFalse($filename, "ImageMagick not installed, silent fail");
}
}
/**
* Test
*
* @return void
*/
public function testCreate2()
{
$img = new CImage();
$filename = $img->convert2sRGBColorSpace(
'car.jpg',
IMAGE_PATH,
$this->cache,
$this->srgbColorProfile
);
$this->assertFalse($filename);
}
}

View File

@@ -10,15 +10,20 @@ echo "Extension exif is $no loaded.<br>";
$no = extension_loaded('curl') ? null : 'NOT';
echo "Extension curl is $no loaded.<br>";
$no = extension_loaded('imagick') ? null : 'NOT';
echo "Extension imagick is $no loaded.<br>";
$no = extension_loaded('gd') ? null : 'NOT';
echo "Extension gd is $no loaded.<br>";
if (!$no) {
echo "<pre>", var_dump(gd_info()), "</pre>";
}
echo "<strong>Checking path for postprocessing tools</strong>";
echo "<br>pngquant: ";
system("which pngquant");
echo "<br>optipng: ";
system("which optipng");

View File

@@ -5,7 +5,6 @@
#
# img A directory where all images are stored
# img/me.jpg Access a image as usually.
# img/img.php This is where I choose to place img.php (and img_config.php).
# image/me.jpg Access a image though img.php using htaccess rewrite.
# image/me.jpg?w=300 Using options to img.php.
#
@@ -15,4 +14,4 @@
# image/me/me.jpg?w=300 Using options to img.php.
#
RewriteEngine on
RewriteRule ^image/(.*)$ img/img.php?src=$1 [QSA,NC,L]
RewriteRule ^image/(.*)$ img.php?src=$1 [QSA,NC,L]

View File

@@ -8,131 +8,6 @@
*
*/
$version = "v0.7.7 (2015-10-21)";
/**
* Display error message.
*
* @param string $msg to display.
*
* @return void
*/
function errorPage($msg)
{
global $mode;
header("HTTP/1.0 500 Internal Server Error");
if ($mode == 'development') {
die("[img.php] $msg");
}
error_log("[img.php] $msg");
die("HTTP/1.0 500 Internal Server Error");
}
/**
* 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;
}
/**
* Get value from config array or default if key is not set in config array.
*
* @param string $key the key in the config array.
* @param mixed $default value to be default if $key is not set in config.
*
* @return mixed value as $config[$key] or $default.
*/
function getConfig($key, $default)
{
global $config;
return isset($config[$key])
? $config[$key]
: $default;
}
/**
* 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, $verboseFile;
static $log = array();
if (!($verbose || $verboseFile)) {
return;
}
if (is_null($msg)) {
return $log;
}
$log[] = $msg;
}
/**
* Get configuration options from file, if the file exists, else use $config
* if its defined or create an empty $config.
@@ -145,6 +20,24 @@ if (is_file($configFile)) {
$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"];
}
/**
@@ -153,7 +46,7 @@ if (is_file($configFile)) {
*/
$verbose = getDefined(array('verbose', 'v'), true, false);
$verboseFile = getDefined('vf', true, false);
verbose("img.php version = $version");
verbose("img.php version = " . CIMAGE_VERSION);
@@ -175,7 +68,7 @@ set_time_limit(20);
ini_set('gd.jpeg_ignore_warning', 1);
if (!extension_loaded('gd')) {
errorPage("Extension gd is nod loaded.");
errorPage("Extension gd is not loaded.", 500);
}
// Specific settings for each mode
@@ -211,7 +104,7 @@ if ($mode == 'strict') {
ini_set('log_errors', 0);
} else {
errorPage("Unknown mode: $mode");
errorPage("Unknown mode: $mode", 500);
}
verbose("mode = $mode");
@@ -244,7 +137,7 @@ $pwd = get(array('password', 'pwd'), null);
// Check if passwords match, if configured to use passwords
$passwordMatch = null;
if ($pwd) {
switch($pwdType) {
switch ($pwdType) {
case 'md5':
$passwordMatch = ($pwdConfig === md5($pwd));
break;
@@ -260,7 +153,7 @@ if ($pwd) {
}
if ($pwdAlways && $passwordMatch !== true) {
errorPage("Password required and does not match or exists.");
errorPage("Password required and does not match or exists.", 403);
}
verbose("password match = $passwordMatch");
@@ -284,9 +177,9 @@ if (!$allowHotlinking) {
; // Always allow when password match
verbose("Hotlinking since passwordmatch");
} elseif ($passwordMatch === false) {
errorPage("Hotlinking/leeching not allowed when password missmatch.");
errorPage("Hotlinking/leeching not allowed when password missmatch.", 403);
} elseif (!$referer) {
errorPage("Hotlinking/leeching not allowed and referer is missing.");
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.");
@@ -297,11 +190,11 @@ if (!$allowHotlinking) {
if ($allowedByWhitelist) {
verbose("Hotlinking/leeching allowed by whitelist.");
} else {
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.");
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.", 403);
}
} else {
errorPage("Hotlinking/leeching not allowed.");
errorPage("Hotlinking/leeching not allowed.", 403);
}
}
@@ -312,24 +205,58 @@ verbose("referer host = $refererHost");
/**
* Get the source files.
* Create the class for the image.
*/
$autoloader = getConfig('autoloader', false);
$cimageClass = getConfig('cimage_class', false);
if ($autoloader) {
require $autoloader;
} elseif ($cimageClass) {
require $cimageClass;
}
$CImage = getConfig('CImage', 'CImage');
$img = new $CImage();
$img->setVerbose($verbose || $verboseFile);
/**
* Create the class for the image.
* Get the cachepath from config.
*/
$img = new CImage();
$img->setVerbose($verbose || $verboseFile);
$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();
}
@@ -341,8 +268,10 @@ $img->setVerbose($verbose || $verboseFile);
$allowRemote = getConfig('remote_allow', false);
if ($allowRemote && $passwordMatch !== false) {
$cacheRemote = $cache->getPathToSubdir("remote");
$pattern = getConfig('remote_pattern', null);
$img->setRemoteDownload($allowRemote, $pattern);
$img->setRemoteDownload($allowRemote, $cacheRemote, $pattern);
$whitelist = getConfig('remote_whitelist', null);
$img->setRemoteHostWhitelist($whitelist);
@@ -375,20 +304,30 @@ if (isset($shortcut)
* src - the source image file.
*/
$srcImage = urldecode(get('src'))
or errorPage('Must set src-attribute.');
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('Filename contains invalid characters.');
or errorPage('Source filename contains invalid characters.', 404);
if ($dummyEnabled && $srcImage === $dummyFilename) {
@@ -398,23 +337,46 @@ if ($dummyEnabled && $srcImage === $dummyFilename) {
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
$remoteSource = true;
} elseif ($imagePathConstraint) {
} else {
// Check that the image is a file below the directory 'image_path'.
// Check if file exists on disk or try using src-alt
$pathToImage = realpath($imagePath . $srcImage);
$imageDir = realpath($imagePath);
is_file($pathToImage)
or errorPage(
'Source image is not a valid file, check the filename and that a
matching file exists on the filesystem.'
);
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.'
as specified in the config file img_config.php.',
404
);
}
@@ -464,11 +426,11 @@ if (isset($sizes[$newWidth])) {
// Support width as % of original width
if ($newWidth[strlen($newWidth)-1] == '%') {
is_numeric(substr($newWidth, 0, -1))
or errorPage('Width % not numeric.');
or errorPage('Width % not numeric.', 404);
} else {
is_null($newWidth)
or ($newWidth > 10 && $newWidth <= $maxWidth)
or errorPage('Width out of range.');
or errorPage('Width out of range.', 404);
}
verbose("new width = $newWidth");
@@ -489,11 +451,11 @@ if (isset($sizes[$newHeight])) {
// height
if ($newHeight[strlen($newHeight)-1] == '%') {
is_numeric(substr($newHeight, 0, -1))
or errorPage('Height % out of range.');
or errorPage('Height % out of range.', 404);
} else {
is_null($newHeight)
or ($newHeight > 10 && $newHeight <= $maxHeight)
or errorPage('Hight out of range.');
or errorPage('Height out of range.', 404);
}
verbose("new height = $newHeight");
@@ -531,7 +493,7 @@ if ($negateAspectRatio) {
is_null($aspectRatio)
or is_numeric($aspectRatio)
or errorPage('Aspect ratio out of range');
or errorPage('Aspect ratio out of range', 404);
verbose("aspect ratio = $aspectRatio");
@@ -631,20 +593,17 @@ 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");
/**
* 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
*/
@@ -653,7 +612,7 @@ $qualityDefault = getConfig('jpg_quality', null);
is_null($quality)
or ($quality > 0 and $quality <= 100)
or errorPage('Quality out of range');
or errorPage('Quality out of range', 404);
if (is_null($quality) && !is_null($qualityDefault)) {
$quality = $qualityDefault;
@@ -671,7 +630,7 @@ $compressDefault = getConfig('png_compression', null);
is_null($compress)
or ($compress > 0 and $compress <= 9)
or errorPage('Compress out of range');
or errorPage('Compress out of range', 404);
if (is_null($compress) && !is_null($compressDefault)) {
$compress = $compressDefault;
@@ -697,7 +656,7 @@ $scale = get(array('scale', 's'));
is_null($scale)
or ($scale >= 0 and $scale <= 400)
or errorPage('Scale out of range');
or errorPage('Scale out of range', 404);
verbose("scale = $scale");
@@ -746,7 +705,7 @@ $rotateBefore = get(array('rotateBefore', 'rotate-before', 'rb'));
is_null($rotateBefore)
or ($rotateBefore >= -360 and $rotateBefore <= 360)
or errorPage('RotateBefore out of range');
or errorPage('RotateBefore out of range', 404);
verbose("rotateBefore = $rotateBefore");
@@ -759,7 +718,7 @@ $rotateAfter = get(array('rotateAfter', 'rotate-after', 'ra', 'rotate', 'r'));
is_null($rotateAfter)
or ($rotateAfter >= -360 and $rotateAfter <= 360)
or errorPage('RotateBefore out of range');
or errorPage('RotateBefore out of range', 404);
verbose("rotateAfter = $rotateAfter");
@@ -881,6 +840,9 @@ 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',
@@ -893,6 +855,15 @@ $postProcessing = getConfig('postprocessing', array(
/**
* 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.
@@ -908,13 +879,13 @@ if ($alias && $aliasPath && $passwordMatch) {
$useCache = false;
is_writable($aliasPath)
or errorPage("Directory for alias is not writable.");
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.');
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.');
errorPage('Alias is not enabled in the config file or password not matching.', 403);
}
verbose("alias = $alias");
@@ -922,14 +893,7 @@ verbose("alias = $alias");
/**
* Get the cachepath from config.
*/
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
/**
* Get the cachepath from config.
* Add cache control HTTP header.
*/
$cacheControl = getConfig('cache_control', null);
@@ -943,11 +907,8 @@ if ($cacheControl) {
/**
* Prepare a dummy image and use it as source image.
*/
$dummyDir = getConfig('dummy_dir', $cachePath. "/" . $dummyFilename);
if ($dummyImage === true) {
is_writable($dummyDir)
or verbose("dummy dir not writable = $dummyDir");
$dummyDir = $cache->getPathToSubdir("dummy");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
@@ -972,16 +933,58 @@ if ($dummyImage === true) {
/**
* 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 = $version\n";
$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";
$text .= "Cache writable = " . is_writable($cachePath) . "\n";
$text .= "Cache dummy writable = " . is_writable($dummyDir) . "\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';
@@ -990,9 +993,17 @@ if ($status) {
$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);
}
@@ -1061,6 +1072,7 @@ if (is_callable($hookBeforeCImage)) {
// Other
'postProcessing' => $postProcessing,
'lossy' => $lossy,
));
verbose(print_r($allConfig, 1));
extract($allConfig);
@@ -1145,6 +1157,9 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
// Output format
'outputFormat' => $outputFormat,
'dpr' => $dpr,
// Postprocessing using external tools
'lossy' => $lossy,
)
)
->loadImageDetails()

BIN
webroot/img/apple.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
webroot/img/car_srgb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
webroot/img/duke.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

BIN
webroot/img/hamburger.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

BIN
webroot/img/lena.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

BIN
webroot/img/lena.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

BIN
webroot/img/lena.tif Normal file

Binary file not shown.

BIN
webroot/img/lena.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
webroot/img/planet.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
webroot/img/webp/1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -5,28 +5,54 @@
* config-file imgtest_config.php.
*
*/
/**
* Change to true to enable debug mode which logs additional information
* to file. Only use for test and development. You must create the logfile
* and make it writable by the webserver or log entries will silently fail.
*
* CIMAGE_DEBUG will be false by default, if its not defined.
*/
if (!defined("CIMAGE_DEBUG")) {
define("CIMAGE_DEBUG", false);
//define("CIMAGE_DEBUG", true);
define("CIMAGE_DEBUG_FILE", "/tmp/cimage");
}
return array(
/**
* Set mode as 'strict', 'production' or 'development'.
*
* development: Development mode with verbose error reporting. Option
* &verbose and &status enabled.
* production: Production mode logs all errors to file, giving server
* error 500 for bad usage. Option &verbose and &status
* disabled.
* strict: Strict mode logs few errors to file, giving server error
* 500 for bad usage. Stripped from comments and spaces.
* Option &verbose and &status disabled.
*
* Default values:
* mode: 'production'
*/
'mode' => 'development', // 'development', 'strict'
//'mode' => 'production', // 'development', 'strict'
//'mode' => 'production',
//'mode' => 'development',
//'mode' => 'strict',
/**
* Where are the sources for the classfiles.
* Where to find the autoloader.
*
* Default values:
* autoloader: null // used from v0.6.2
* cimage_class: null // used until v0.6.1
* autoloader: null
*/
'autoloader' => __DIR__ . '/../autoload.php',
//'cimage_class' => __DIR__ . '/../CImage.php',
@@ -35,16 +61,44 @@ return array(
* End all paths with a slash.
*
* Default values:
* image_path: __DIR__ . '/img/'
* cache_path: __DIR__ . '/../cache/'
* alias_path: null
* image_path: __DIR__ . '/img/'
* cache_path: __DIR__ . '/../cache/'
* alias_path: null
*/
'image_path' => __DIR__ . '/img/',
'cache_path' => __DIR__ . '/../cache/',
'image_path' => __DIR__ . '/img/',
'cache_path' => __DIR__ . '/../cache/',
//'alias_path' => __DIR__ . '/img/alias/',
/**
* Fast track cache. Save a json representation of the image as a
* fast track to the cached version of the image. This avoids some
* processing and allows for quicker load times of cached images.
*
* Default values:
* fast_track_allow: false
*/
//'fast_track_allow' => true,
/**
* Class names to use, to ease dependency injection. You can change Class
* name if you want to use your own class instead. This is a way to extend
* the codebase.
*
* Default values:
* CImage: CImage
* CCache: CCache
* CFastTrackCache: CFastTrackCache
*/
//'CImage' => 'CImage',
//'CCache' => 'CCache',
//'CFastTrackCache' => 'CFastTrackCache',
/**
* Use password to protect from missusage, send &pwd=... or &password=..
* with the request to match the password or set to false to disable.
@@ -97,6 +151,20 @@ return array(
/**
* Use backup image if src-image is not found on disk. The backup image
* is only available for local images and based on wether the original
* image is found on disk or not. The backup image must be a local image
* or the dummy image.
*
* Default value:
* src_alt: null //disabled by default
*/
//'src_alt' => 'car.png',
//'src_alt' => 'dummy',
/**
* A regexp for validating characters in the image or alias filename.
*
@@ -122,6 +190,34 @@ return array(
/**
* Convert the image to srgb before processing. Saves the converted
* image in a cache subdir 'srgb'. This option is default false but can
* be changed to default true to do this conversion for all images.
* This option requires PHP extension imagick and will silently fail
* if that is not installed.
*
* Default value:
* srgb_default: false
* srgb_colorprofile: __DIR__ . '/../icc/sRGB_IEC61966-2-1_black_scaled.icc'
*/
//'srgb_default' => false,
//'srgb_colorprofile' => __DIR__ . '/../icc/sRGB_IEC61966-2-1_black_scaled.icc',
/**
* Set skip-original to true to always process the image and use
* the cached version. Default is false and to use the original
* image when its no processing needed.
*
* Default value:
* skip_original: false
*/
//'skip_original' => true,
/**
* A function (hook) can be called after img.php has processed all
* configuration options and before processing the image using CImage.
@@ -152,30 +248,27 @@ return array(
/**
* The name representing a dummy image which is automatically created
* and stored at the defined path. The dummy image can then be used
* inplace of an original image as a placeholder.
* The dummy_dir must be writable and it defaults to a subdir of the
* cache directory.
* Write protect the dummy_dir to prevent creation of new dummy images,
* but continue to use the existing ones.
* and stored as a image in the dir CACHE_PATH/dummy. The dummy image
* can then be used as a placeholder image.
* The dir CACHE_PATH/dummy is automatically created when needed.
* Write protect the CACHE_PATH/dummy to prevent creation of new
* dummy images, but continue to use the existing ones.
*
* Default value:
* dummy_enabled: true as default, disable dummy feature by setting
* to false.
* dummy_filename: 'dummy' use this as ?src=dummy to create a dummy image.
* dummy_dir: Defaults to subdirectory of 'cache_path',
* named the same as 'dummy_filename'
*/
//'dummy_enabled' => true,
//'dummy_filename' => 'dummy',
//'dummy_dir' => 'some writable directory',
/**
* Check that the imagefile is a file below 'image_path' using realpath().
* Security constraint to avoid reaching images outside image_path.
* This means that symbolic links to images outside the image_path will fail.
* This means that symbolic links to images outside the image_path will
* fail.
*
* Default value:
* image_path_constraint: true
@@ -228,8 +321,16 @@ return array(
* Post processing of images using external tools, set to true or false
* and set command to be executed.
*
* The png_lossy can alos have a value of null which means that its
* enabled but not used as default. Each image having the option
* &lossy will be processed. This means one can individually choose
* when to use the lossy processing.
*
* Default values.
*
* png_lossy: false
* png_lossy_cmd: '/usr/local/bin/pngquant --force --output'
*
* png_filter: false
* png_filter_cmd: '/usr/local/bin/optipng -q'
*
@@ -241,6 +342,9 @@ return array(
*/
/*
'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',
@@ -366,7 +470,7 @@ return array(
/**
* default options for ascii image.
* Default options for ascii image.
*
* Default values as specified below in the array.
* ascii-options:

View File

@@ -10,6 +10,7 @@
* @link https://github.com/mosbth/cimage
*
*/
define("CIMAGE_BUNDLE", true);
/**

1307
webroot/imgd.php Normal file → Executable file

File diff suppressed because it is too large Load Diff

91
webroot/imgf.php Normal file
View File

@@ -0,0 +1,91 @@
<?php
/**
* Fast track cache, read entries from the cache before processing image
* the ordinary way.
*/
// Load the config file or use defaults
$configFile = __DIR__
. "/"
. basename(__FILE__, ".php")
. "_config.php";
if (is_file($configFile) && is_readable($configFile)) {
$config = require $configFile;
} elseif (!isset($config)) {
$config = array(
"fast_track_allow" => true,
"autoloader" => __DIR__ . "/../autoload.php",
"cache_path" => __DIR__ . "/../cache/",
);
}
// Make CIMAGE_DEBUG false by default, if not already defined
if (!defined("CIMAGE_DEBUG")) {
define("CIMAGE_DEBUG", false);
}
// Debug mode needs additional functions
if (CIMAGE_DEBUG) {
require $config["autoloader"];
}
// Cache path must be valid
$cacheIsReadable = is_dir($config["cache_path"]) && is_readable($config["cache_path"]);
if (!$cacheIsReadable) {
die("imgf.php: Cache is not readable, check path in configfile.");
}
// Prepare to check if fast cache should be used
$cachePath = $config["cache_path"] . "/fasttrack";
$query = $_GET;
// Do not use cache when no-cache is active
$useCache = !(array_key_exists("no-cache", $query) || array_key_exists("nc", $query));
// Only use cache if enabled by configuration
$useCache = $useCache && isset($config["fast_track_allow"]) && $config["fast_track_allow"] === true;
// Remove parts from querystring that should not be part of filename
$clear = array("nc", "no-cache");
foreach ($clear as $value) {
unset($query[$value]);
}
// Create the cache filename
arsort($query);
$queryAsString = http_build_query($query);
$filename = md5($queryAsString);
$filename = "$cachePath/$filename";
// Check cached item, if any
if ($useCache && is_readable($filename)) {
$item = json_decode(file_get_contents($filename), true);
if (is_readable($item["source"])) {
foreach ($item["header"] as $value) {
header($value);
}
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
header("HTTP/1.0 304 Not Modified");
if (CIMAGE_DEBUG) {
trace("imgf 304");
}
exit;
}
foreach ($item["header-output"] as $value) {
header($value);
}
if (CIMAGE_DEBUG) {
trace("imgf 200");
}
readfile($item["source"]);
exit;
}
}
// No fast track cache, proceed as usual
include __DIR__ . "/img.php";

1
webroot/imgf_config.php Symbolic link
View File

@@ -0,0 +1 @@
img_config.php

1307
webroot/imgp.php Normal file → Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -17,12 +17,13 @@ $description = "Do not upscale image when original image (slice) is smaller than
// Use these images in the test
$images = array(
'car.png',
'apple.jpg',
);
// For each image, apply these testcases
$nc = null; //"&nc"; //null; //&nc';
$nc = "&bgc=660000"; //null; //"&nc"; //null; //&nc';
$testcase = array(
$nc . '&w=600',
$nc . '&w=600&no-upscale',
@@ -34,16 +35,20 @@ $testcase = array(
$nc . '&w=700&h=400&no-upscale&stretch',
$nc . '&w=700&h=200&stretch',
$nc . '&w=700&h=200&no-upscale&stretch',
$nc . '&w=300&h=400&stretch',
$nc . '&w=300&h=400&no-upscale&stretch',
$nc . '&w=600&h=400&crop-to-fit',
$nc . '&w=600&h=400&no-upscale&crop-to-fit',
$nc . '&w=600&h=200&crop-to-fit',
$nc . '&w=600&h=200&no-upscale&crop-to-fit',
$nc . '&w=300&h=400&crop-to-fit',
$nc . '&w=300&h=400&no-upscale&crop-to-fit',
$nc . '&w=600&h=400&fill-to-fit',
$nc . '&w=600&h=400&no-upscale&fill-to-fit',
$nc . '&w=250&h=400&stretch',
$nc . '&w=250&h=400&no-upscale&stretch',
$nc . '&w=700&h=400&crop-to-fit',
$nc . '&w=700&h=400&no-upscale&crop-to-fit',
$nc . '&w=700&h=200&crop-to-fit',
$nc . '&w=700&h=200&no-upscale&crop-to-fit',
$nc . '&w=250&h=400&crop-to-fit',
$nc . '&w=250&h=400&no-upscale&crop-to-fit',
$nc . '&w=600&h=500&fill-to-fit',
$nc . '&w=600&h=500&no-upscale&fill-to-fit',
$nc . '&w=250&h=400&fill-to-fit',
$nc . '&w=250&h=400&no-upscale&fill-to-fit',
$nc . '&w=700&h=400&fill-to-fit',
$nc . '&w=700&h=400&no-upscale&fill-to-fit',
/*
$nc . '&w=600&ar=1.6',
$nc . '&w=600&ar=1.6&no-upscale',