1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-08-23 16:12:52 +02:00

Compare commits

...

164 Commits

Author SHA1 Message Date
Mikael Roos
b44be78f06 Fix deprecation notice on "Creation of dynamic property" for PHP 8.2. 2023-10-27 10:20:16 +02:00
Mikael Roos
1056f0a5ee Spelling in README 2022-11-17 16:13:56 +01:00
Mikael Roos
1666ea1412 Build to prepare to tag 2022-11-17 16:08:48 +01:00
Mikael Roos
bb57af697b Remove build status from README (since it is not up to date) 2022-11-17 16:06:25 +01:00
Mikael Roos
55ce23ae5e Add fix for WINDOWS2WSL 2022-11-17 16:05:25 +01:00
Mikael Roos
4589b3b3cd Enable configuration fix for solving Windows 2 WSL2 issue with is_readable/is_writable #189 2022-11-17 15:40:43 +01:00
Mikael Roos
d5ca10cebc Add a webpage with links useful to test various aspects of img.php 2022-11-17 15:31:40 +01:00
Mikael Roos
9d7343a2df Merge pull request #188 from niciz/patch-1
Update CHttpGet.php for php 8.1 deprecated notice
2022-11-08 13:50:12 +01:00
niciz
3d7adcdbde Update CHttpGet.php for php 8.1 deprecated notice 2022-11-08 12:23:07 +01:00
Mikael Roos
80cd4e092f v0.8.4 (2022-05-30) 2022-05-30 15:32:20 +02:00
Mikael Roos
4c0ac8ed23 Support PHP 8.1 and remove deprecated messages when run in in development mode 2022-05-24 16:41:01 +02:00
Mikael Roos
39b86628db Generate prebuilt all include files for various settings 2022-05-24 16:38:48 +02:00
Mikael Roos
5f4280d387 Fix deprecated for PHP 8.1 2022-05-24 16:37:50 +02:00
Mikael Roos
dd315dbd21 Fix deprecated for PHP 8.1 2022-05-24 16:33:08 +02:00
Mikael Roos
493118e1c5 Add php version as output in verbose mode 2022-05-24 12:57:27 +02:00
Mikael Roos
e41b3d9877 Add PHP 81 as test environment 2022-05-24 12:57:08 +02:00
Mikael Roos
bb60001c36 Prepare to tag 2021-10-27 11:40:40 +02:00
Mikael Roos
adeca3f9f9 Prepare to tag 2021-10-27 11:40:18 +02:00
Mikael Roos
a5662690fe Remove bad configuration 2021-10-27 11:21:29 +02:00
Mikael Roos
3cfa9a6a98 Add htmlentities to escape input, fix #183 2021-09-13 08:17:47 +02:00
Mikael Roos
4ecebcd5b4 Add a security policy #183 2021-09-09 13:51:13 +02:00
Mikael Roos
9196d1ee41 Update the docker-compose.yaml to include PHP 8.0, #181 2021-05-10 16:01:23 +02:00
Mikael Roos
0249056761 Updated version number in define.php. 2020-06-08 12:38:44 +02:00
Mikael Roos
4ea72be49a Enable to set JPEG image as interlaced, implement feature #177. 2020-06-08 12:26:40 +02:00
Mikael Roos
2ce1f18fe5 Set PHP 7.0 as precondition (to prepare to update the codebase). 2020-06-08 12:26:01 +02:00
Mikael Roos
0f1f537b62 Add function getValue() to read from querystring. 2020-06-08 12:25:47 +02:00
Mikael Roos
1411adc828 Fix error in composer.json 2020-05-06 09:51:12 +02:00
Mikael Roos
86737af69e Update composer.json and move ext-gd from required to suggested to ease installation where cli does not have all extensions installed. 2020-05-06 09:06:46 +02:00
Mikael Roos
c563275ed5 Support PHP 7.4, some minor fixes with notices. 2020-01-15 16:51:39 +01:00
Mikael Roos
8fec09b195 Merge pull request #176 from SpaceLenore/patch-1
fixed markdown syntax
2018-10-28 19:08:45 +01:00
Lenore
ac16343cd7 fixed markdown syntax
added spaces so the markdown gets parsed correctly
2018-10-28 17:49:35 +01:00
Mikael Roos
cd142c5880 prepare to tag 2017-11-06 10:24:47 +01:00
Mikael Roos
91dd92d483 Remove webroot/img/{round8.PNG,wider.JPEG,wider.JPG} to avoid unzip warning message when installing with composer. 2017-11-06 10:24:16 +01:00
Mikael Roos
4b64d921d1 Adding docker-compose.yml #169. 2017-06-26 10:30:21 +02:00
Mikael Roos
4211d7e0e6 Adding docker-compose.yml #169. 2017-06-26 10:30:08 +02:00
Mikael Roos
dd8878c8bd add issue number 2017-03-31 00:55:38 +02:00
Mikael Roos
f9604518e4 prepare to tag v0.7.19 2017-03-31 00:47:55 +02:00
Mikael Roos
61aa52854e Move exception handler from functions.php to img.php. 2017-03-31 00:46:43 +02:00
Mikael Roos
401478c839 Correct XSS injection in check_system.php. 2016-08-31 15:26:14 +02:00
Mikael Roos
f0ab9479d6 read lena.tif, will need it in the future 2016-08-13 18:33:09 +02:00
Mikael Roos
9ff7a61ca9 remove tif version of lena 2016-08-13 17:49:36 +02:00
Mikael Roos
3170beb832 Composer suggests ext-imagick and ext-curl. 2016-08-11 17:39:45 +02:00
Mikael Roos
8001f72a1a prepare to tag v0.7.18 2016-08-09 13:27:46 +02:00
Mikael Roos
0f9e0220f1 Made &lossless a requirement to not use the original image. 2016-08-09 13:27:30 +02:00
Mikael Roos
e59ef91991 prepare to tag v0.7.17 2016-08-09 13:23:04 +02:00
Mikael Roos
2337dbe94c Made &lossless part of the generated cache filename. 2016-08-09 13:22:33 +02:00
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
Mikael Roos
80610b31b9 generated new bundles 2015-10-21 01:13:36 +02:00
Mikael Roos
b639220d05 prepare to tag v0.7.7 2015-10-21 01:13:18 +02:00
Mikael Roos
ee9fdb8474 One can now add a HTTP header for Cache-Control in the config file, #109. 2015-10-21 01:12:10 +02:00
Mikael Roos
db5ce71926 Added hook in img,php before CImage is called, #123. 2015-10-21 00:51:56 +02:00
Mikael Roos
1bf57fe8ef Added hook in img,php before CImage is called, #123. 2015-10-21 00:51:48 +02:00
Mikael Roos
8c89166967 Added configuration for default jpeg quality and png compression in the config file, #107. 2015-10-21 00:30:01 +02:00
Mikael Roos
ce8ec325d3 Strip comments and whitespace in imgs.php. 2015-10-21 00:13:56 +02:00
Mikael Roos
ca9b4a4ce6 webroot/img/issue117/img.php?src=issue117%2Ftri_original.png 2015-10-21 00:05:14 +02:00
Mikael Roos
7c0f37628f Adding option &status to get an overview of the installed ond configured utilities, #116. 2015-10-21 00:04:37 +02:00
Mikael Roos
5fe8e399a1 * Added option to decide if resample or resize when copying images internally. &no-resample makes resize, instead of resample as is default.
* Verbose now correctly states if transparent color is detected.
* Removed that source png-files, containing less than 255 colors, is always saved as palette images since this migth depend on processing of the image.
2015-10-20 13:46:01 +02:00
Mikael Roos
9620c1eb75 Adding testcase for issue #117 2015-10-20 13:45:16 +02:00
Mikael Roos
f721ef4b35 Adding save-as as part of the generated cache filename, #121. 2015-10-20 10:26:09 +02:00
Mikael Roos
37b39fbecf Add extra fileds to json-response, #114. 2015-10-20 10:04:37 +02:00
Mikael Roos
553d2f3db1 Add header for Content-Length, #111. 2015-10-18 18:34:42 +02:00
Mikael Roos
9e2bd27c6e Add check for postprocessing tools in path in webroot/check_system.php, #104. 2015-10-18 18:13:12 +02:00
Mikael Roos
1bd6fc8a2c improving dummy image 2015-10-18 17:15:14 +02:00
Mikael Roos
39b6078d84 travis working again, unintentionally removed the cache dirs 2015-10-18 16:25:50 +02:00
Mikael Roos
e7e73fc38c testin travis 2015-10-18 16:22:42 +02:00
Mikael Roos
fa77908616 testin travis 2015-10-18 16:13:45 +02:00
Mikael Roos
0f05cd06e5 testin travis 2015-10-18 16:11:59 +02:00
Mikael Roos
3d773b502d testint travis 2015-10-18 16:04:48 +02:00
Mikael Roos
575c712bd0 testint travis 2015-10-18 16:02:27 +02:00
Mikael Roos
cdd159e142 testing travis 2015-10-18 15:52:06 +02:00
Mikael Roos
f21cd923f3 testing travis 2015-10-18 15:50:22 +02:00
Mikael Roos
18fb271961 add writable cache dir 2015-10-18 15:48:11 +02:00
Mikael Roos
1fdc701f3d prepare to test v0.7.5 2015-10-18 15:43:43 +02:00
Mikael Roos
dc6e9a8708 test tag 2015-10-18 14:52:17 +02:00
Mikael Roos
d9947251ab prepare to merge 2015-10-18 14:44:27 +02:00
Mikael Roos
0fb00df972 adding feature for creating dummy images, #101 2015-09-17 11:24:30 +02:00
Mikael Roos
f00b2e0cd3 adding feature for creating dummy images, #101 2015-09-17 11:22:50 +02:00
Mikael Roos
fd2ddadc44 Add png compression to generated cache filename, fix #103. 2015-09-16 09:51:04 +02:00
Mikael Roos
ea4794f4a2 remove commented code 2015-09-16 09:19:46 +02:00
Mikael Roos
7af0b6ef8a remove commented code 2015-09-16 09:18:51 +02:00
Mikael Roos
850fb76c8b cleanup unused variables 2015-09-16 09:09:30 +02:00
Mikael Roos
49f5f66ad3 calling setSource(null) should unset imageSrc and pathToImage 2015-09-16 08:26:28 +02:00
Mikael Roos
a787593533 Removing unneded internal variable this->imageFolder 2015-09-16 08:21:32 +02:00
97 changed files with 10669 additions and 7043 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;

116
CCache.php Normal file
View File

@@ -0,0 +1,116 @@
<?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 && defined('WINDOWS2WSL')) {
// Special case to solve Windows 2 WSL integration
$path = $this->path . "/" . $subdir;
if (mkdir($path)) {
return realpath($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

@@ -215,7 +215,7 @@ class CHttpGet
{
$type = isset($this->response['header']['Content-Type'])
? $this->response['header']['Content-Type']
: null;
: '';
return preg_match('#[a-z]+/[a-z]+#', $type)
? $type

File diff suppressed because it is too large Load Diff

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
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.

102
README.md
View File

@@ -1,13 +1,16 @@
[![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 +24,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).
@@ -41,18 +47,18 @@ There are several ways of installing. You either install the whole project which
###Install source from GitHub
### Install source from GitHub
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.4 released 2015-09-15.**
**Latest stable version is v0.7.18 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.4
git checkout v0.7.18
```
Make the cache-directory writable by the webserver.
@@ -62,7 +68,7 @@ chmod 777 cache
```
###Install all-included bundle
### Install all-included bundle
There are some all-included bundles of `img.php` that can be downloaded and used without dependency to the rest of the sourcecode.
@@ -75,14 +81,14 @@ 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.4/webroot/imgp.php
wget https://raw.githubusercontent.com/mosbth/cimage/v0.7.18/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.
###Install from Packagist
### Install from Packagist
You can install the package [`mos/cimage` from Packagist](https://packagist.org/packages/mos/cimage) using composer.
@@ -97,7 +103,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 +117,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 +130,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.
@@ -135,15 +141,15 @@ Get going quickly
###Check out the test page
### Check out the test page
Try it out by pointing your browser to the test file `webroot/test/test.php`. It will show some example images and you can review how they are created.
###Process your first image
### 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
@@ -155,20 +161,20 @@ and try to resize it to a thumbnail by adding the options
###What does "processing the image" involves?
### What does "processing the image" involves?
Add `&verbose` to the link to get a verbose output of what is happens during image processing. This is useful for developers and those who seek a deeper understanding on how it works behind the scene.
###Check your system
### Check your system
Open up `webroot/check_system.php` if you are uncertain that your system has the right extensions loaded.
###How does it work?
### How does it work?
Review the settings in `webroot/img_config.php` and check out `webroot/img.php` on how it uses `CImage`.
@@ -189,7 +195,7 @@ Basic usage
###Select the source
### Select the source
Open an image through `img.php` by using its `src` attribute.
@@ -197,7 +203,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:
@@ -205,13 +211,13 @@ All images are stored in a directory structure and you access them as:
###Resize using constraints on width and height
### Resize using constraints on width and height
Create a thumbnail of the image by applying constraints on width and height, or one of them.
| `&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.
@@ -219,17 +225,17 @@ Think of the constraints as a imaginary box where the image should fit. With `wi
###Resize to fit a certain dimension
### Resize to fit a certain dimension
Creating a thumbnail with a certain dimension of width and height, usually involves stretching or cropping the image to fit in the selected dimensions. Here is how you create a image that has the exact dimensions of 300x150 pixels, by either *stretching*, *cropping* or *fill to fit*.
| 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.
@@ -239,19 +245,19 @@ Fill to fit is useful when you have some image that must fit in a certain dimens
###List of parameters
### List of parameters
`img.php` supports a lot of parameters. Combine the parameters to get the desired behavior and resulting image. For example, take the original image, resize it using width, aspect-ratio and crop-to-fit, apply a sharpen effect, save the image as JPEG using quality 30.
> `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.
####Mandatory options and debugging
#### Mandatory options and debugging
Option `src` is the only mandatory option. The options in this section is useful for debugging or deciding what version of the target image is used.
@@ -266,7 +272,7 @@ Option `src` is the only mandatory option. The options in this section is useful
####Options for deciding width and height of target image
#### Options for deciding width and height of target image
These options are all affecting the final dimensions, width and height, of the resulting image.
@@ -279,7 +285,7 @@ These options are all affecting the final dimensions, width and height, of the r
####Options for resize strategy
#### Options for resize strategy
These options affect strategy to use when resizing an image into a target image that has both width and height set.
@@ -292,7 +298,7 @@ These options affect strategy to use when resizing an image into a target image
####Options for cropping part of image
#### Options for cropping part of image
These options enable to decide what part of image to crop out.
@@ -303,7 +309,7 @@ These options enable to decide what part of image to crop out.
####General processing options
#### General processing options
These options are general options affecting processing.
@@ -313,7 +319,7 @@ These options are general options affecting processing.
####Processing of image before resizing
#### Processing of image before resizing
This option are executed *before* the image is resized.
@@ -325,7 +331,7 @@ This option are executed *before* the image is resized.
####Processing of image after resizing
#### Processing of image after resizing
These options are executed *after* the image is resized.
@@ -343,7 +349,7 @@ These options are executed *after* the image is resized.
####Saving image, affecting quality and file size
#### Saving image, affecting quality and file size
Options for saving the target image.
@@ -399,7 +405,7 @@ Consult the file `webroot/img-config.php` for a complete list together with the
###Create and name the config file
### Create and name the config file
The file `img.php` looks for the config-file `img_config.php`, and uses it if its found. The three files where everything is included -- `imgd.php`, `imgp.php` and `imgs.php` -- includes an empty `$config`-array which can be overridden by saving a config-file in the same directory. If the script is `imgp.php` then name the config-file `imgp_config.php` and it will find it and use those settings.
@@ -429,7 +435,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:
@@ -464,19 +470,19 @@ Here are some thoughts when applying `img.php` on a live system.
###Select the proper mode
### Select the proper mode
Select the proper mode for `img.php`. Set it to "strict" or "production" to prevent outsiders to get information about your system. Use only "development" for internal use since its quite verbose in its nature of error reporting.
###Put the installation directory outside web root
### Put the installation directory outside web root
Edit the config file to put the installation directory -- and the cache directory -- outside of the web root. Best practice would be to store the installation directory and cache, outside of the web root. The only thing needed in the web root is `img.php` and `img_config.php` (if used) which can be placed, for example, in `/img/img.php` or just as `/img.php`.
###Friendly urls through `.htaccess`
### Friendly urls through `.htaccess`
Use `.htaccess`and rewrite rules (Apache) to get friendly image urls. Put `img.php` in the `/img` directory. Put the file `.htaccess` in the web root.
@@ -514,7 +520,7 @@ The result is good readable urls to your images. Its easy for the search engine
###Monitor cache size
### Monitor cache size
There is a utility `cache.bash` included for monitoring the size of the cache-directory. It generates an output like this.
@@ -552,13 +558,13 @@ Use it as a base if you feel the need to monitor the size och the cache-director
###Read-only cache
### Read-only cache
The cache directory need to be writable for `img.php` to create new files. But its possible to first create all cache-files and then set the directory to be read-only. This will give you a way of shutting of `img.php` from creating new cache files. `img.php` will then continue to work for all images having a cached version but will fail if someone tries to create a new, not previously cached, version of the image.
###Post-processing with external tools
### Post-processing with external tools
You can use external tools to post-process the images to optimize the file size. This option is available for JPEG and for PNG images. Post-processing is disabled by default, edit `img_config.php` to enable it.
@@ -568,7 +574,7 @@ These tools for post processing is not a part of `CImage` and `img.php`, you nee
###Allowing remote download of images
### Allowing remote download of images
You can allow `img.php` to download remote images. That can be enabled in the config-file. However, before doing so, consider the implications on allowing anyone to download a file, hopefully an image, to your server and then the possibility to access it through the webserver.

View File

@@ -1,8 +1,227 @@
Revision history
=====================================
<!--
[![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)
--->
v0.8.6 (2023-10-27)
-------------------------------------
* Fix deprecation notice on "Creation of dynamic property" for PHP 8.2.
v0.8.5 (2022-11-17)
-------------------------------------
* Enable configuration fix for solving Windows 2 WSL2 issue with is_readable/is_writable #189.
* Update CHttpGet.php for php 8.1 deprecated notice #188.
* Remove build status from README (since it is not up to date).
v0.8.4 (2022-05-30)
-------------------------------------
* Support PHP 8.1 and remove (more) deprecated messages when run in in development mode.
v0.8.3 (2022-05-24)
-------------------------------------
* Support PHP 8.1 and remove deprecated messages when run in in development mode.
* Generate prebuilt all include files for various settings
* Fix deprecated for PHP 8.1
* Fix deprecated for PHP 8.1
* Add php version as output in verbose mode
* Add PHP 81 as test environment
v0.8.2 (2021-10-27)
-------------------------------------
* Remove bad configuration.
v0.8.1 (2020-06-08)
-------------------------------------
* Updated version number in define.php.
v0.8.0 (2020-06-08)
-------------------------------------
* Enable to set JPEG image as interlaced, implement feature #177.
* Add function getValue() to read from querystring.
* Set PHP 7.0 as precondition (to prepare to update the codebase).
v0.7.23 (2020-05-06)
-------------------------------------
* Fix error in composer.json
v0.7.22 (2020-05-06)
-------------------------------------
* Update composer.json and move ext-gd from required to suggested to ease installation where cli does not have all extensions installed.
v0.7.21 (2020-01-15)
-------------------------------------
* Support PHP 7.4, some minor fixes with notices.
v0.7.20 (2017-11-06)
-------------------------------------
* Remove webroot/img/{round8.PNG,wider.JPEG,wider.JPG} to avoid unzip warning message when installing with composer.
* Adding docker-compose.yml #169.
v0.7.19 (2017-03-31)
-------------------------------------
* Move exception handler from functions.php to img.php #166.
* Correct XSS injection in `check_system.php`.
* Composer suggests ext-imagick and ext-curl.
v0.7.18 (2016-08-09)
-------------------------------------
* Made `&lossless` a requirement to not use the original image.
v0.7.17 (2016-08-09)
-------------------------------------
* Made `&lossless` part of the generated cache filename.
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)
-------------------------------------
* One can now add a HTTP header for Cache-Control in the config file, #109.
* Added hook in img,php before CImage is called, #123.
* Added configuration for default jpeg quality and png compression in the config file, #107.
* Strip comments and whitespace in imgs.php, #115.
* Bundle imgs.php did not have the correct mode.
* Adding option &status to get an overview of the installed on configured utilities, #116.
* Bug, all files saved as png-files, when not saving as specific file.
* Removed saving filename extension for alias images.
* Added option to decide if resample or resize when copying images internally. `&no-resample` makes resize, instead of resample as is default.
* Verbose now correctly states if transparent color is detected.
* Compare-tool now supports 6 images.
* Added option for dark background in the compare-tool.
* Removed that source png-files, containing less than 255 colors, is always saved as palette images since this migth depend on processing of the image.
* Adding save-as as part of the generated cache filename, #121.
* Add extra fields to json-response, #114.
* Add header for Content-Length, #111.
* Add check for postprocessing tools in path in `webroot/check_system.php`, #104.
v0.7.6 (2015-10-18)
-------------------------------------
* Adding testpage for dummy images `webroot/test/test_issue101-dummy.php`.
* Adding width and height when creating dummy image.
v0.7.5 (2015-10-18)
-------------------------------------
* Adding feature for creating dummy images `src=dummy`, #101.
* Add png compression to generated cache filename, fix #103.
* Removed file prefix from storing images in cache, breaking filenamestructure for cache images.
* Code cleaning in `CImage.php`.
v0.7.4 (2015-09-15)
@@ -31,14 +250,14 @@ v0.7.1 (2015-07-25)
* Using `CWhitelist` for checking hotlinking to images, fix #88.
* Added mode for `test` which enables logging verbose mode to file, fix #97.
* Improved codestyle and added `phpcs.xml` to start using phpcs to check code style, fix #95.
* Adding `composer.json` for publishing on packagist.
* Adding `composer.json` for publishing on packagist.
* Add permalink to setup for comparing images with `webroot/compare/compare.php`, fix #92.
* Allow space in filename by using `urlencode()` and allow space as valid filenam character. fix #91.
* Support redirections for remote images, fix #87, fix #90.
* Support redirections for remote images, fix #87, fix #90.
* Improving usage of Travis and Scrutinizer.
* Naming cache-file using md5 for remote images, fix #86.
* Loading images without depending on filename extension, fix #85.
* Adding unittest with phpunit #84, fix #13
* Adding unittest with phpunit #84, fix #13
* Adding support for whitelist of remote hostnames, #84
* Adding phpdoc, fix #48.
* Adding travis, fix #15.

6
SECURITY.md Normal file
View File

@@ -0,0 +1,6 @@
Security policy
======================
To report security vulnerabilities in the project, send en email to mikael.t.h.roos@gmail.com.
For other security related issues, please open an issue on the project.

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."
@@ -55,10 +59,16 @@ read answer
#
cat webroot/img_header.php > $TARGET_P
cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode' => 'development',|" > $TARGET_D
cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode' => 'development',|" > $TARGET_S
cat webroot/img_header.php | sed "s|//'mode' => 'production',|'mode' => 'strict',|" > $TARGET_S
$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,9 +84,17 @@ $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
php -w $TARGET_S > tmp && mv tmp $TARGET_S
$ECHO "\nDone."
$ECHO "\n"
$ECHO "\n"

4
cache/.gitignore vendored Normal file
View File

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

1
cache/README.md vendored
View File

@@ -1 +0,0 @@
This directory must be writable by the webserver.

View File

@@ -1,5 +1,5 @@
{
"name": "mos/cimage",
"name": "mos/cimage",
"type": "library",
"description": "Process, scale, resize, crop and filter images.",
"keywords": ["image", "imageprocessing", "gd"],
@@ -18,15 +18,27 @@
"docs": "http://dbwebb.se/opensource/cimage"
},
"require": {
"php": ">=5.3"
"php": ">=7.0"
},
"suggest": {
"ext-curl": "*",
"ext-exif": "*",
"ext-gd": "*",
"ext-imagick": "*"
},
"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.8.6 (2023-10-27)");
// 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);
}

97
docker-compose.yaml Normal file
View File

@@ -0,0 +1,97 @@
version: "3"
services:
cli:
image: anax/dev
volumes: [ ".:/home/anax/repo" ]
apache:
image: anax/dev:apache
volumes: [ ".:/home/anax/repo" ]
ports: [ "11000:80" ]
remserver:
image: anax/dev:apache
ports:
- "8090:80"
volumes: [ ".:/home/anax/repo" ]
php82:
image: anax/dev:php82
volumes: [ ".:/home/anax/repo" ]
php82-apache:
image: anax/dev:php82-apache
ports: [ "11082:80" ]
volumes: [ ".:/home/anax/repo" ]
php81:
image: anax/dev:php81
volumes: [ ".:/home/anax/repo" ]
php81-apache:
image: anax/dev:php81-apache
ports: [ "11081:80" ]
volumes: [ ".:/home/anax/repo" ]
php80:
image: anax/dev:php80
volumes: [ ".:/home/anax/repo" ]
php80-apache:
image: anax/dev:php80-apache
ports: [ "11080:80" ]
volumes: [ ".:/home/anax/repo" ]
php74:
image: anax/dev:php74
volumes: [ ".:/home/anax/repo" ]
php74-apache:
image: anax/dev:php74-apache
ports: [ "11074:80" ]
volumes: [ ".:/home/anax/repo" ]
php73:
image: anax/dev:php73
volumes: [ ".:/home/anax/repo" ]
php73-apache:
image: anax/dev:php73-apache
ports: [ "11073:80" ]
volumes: [ ".:/home/anax/repo" ]
php72:
image: anax/dev:php72
volumes: [ ".:/home/anax/repo" ]
php72-apache:
image: anax/dev:php72-apache
ports: [ "11072:80" ]
volumes: [ ".:/home/anax/repo" ]
php71:
image: anax/dev:php71
volumes: [ ".:/home/anax/repo" ]
php71-apache:
image: anax/dev:php71-apache
ports: [ "11071:80" ]
volumes: [ ".:/home/anax/repo" ]
php70:
image: anax/dev:php70
volumes: [ ".:/home/anax/repo" ]
php70:
image: anax/dev:php70-apache
ports: [ "11070:80" ]
volumes: [ ".:/home/anax/repo" ]
php56:
image: anax/dev:php56
volumes: [ ".:/home/anax/repo" ]
php56:
image: anax/dev:php56-apache
ports: [ "11056:80" ]
volumes: [ ".:/home/anax/repo" ]

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;
}
@@ -445,7 +550,7 @@ class CImage
/**
* Set whitelist for valid hostnames from where remote source can be
* Set whitelist for valid hostnames from where remote source can be
* downloaded.
*
* @param array $whitelist with regexp hostnames to allow download from.
@@ -455,14 +560,17 @@ 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;
}
/**
* Check if the hostname for the remote image, is on a whitelist,
* Check if the hostname for the remote image, is on a whitelist,
* if the whitelist is defined.
*
* @param string $src the remote source.
@@ -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);
}
@@ -1274,23 +1423,7 @@ 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,
* Load image from disk. Try to load image without verbose error message,
* if fail, load again and display error messages.
*
* @param string $src of image.
@@ -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,44 +1476,80 @@ 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;
$pngType = ord(file_get_contents($filename, false, null, 25, 1));
if ($this->verbose) {
$this->log("Checking png type of: " . $filename);
$this->log($this->getPngTypeAsString($pngType));
}
return $pngType;
}
/**
* 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:
$this->log("PNG is type 0, Greyscale.");
$text = "PNG is type 0, Greyscale$transparent";
break;
case self::PNG_RGB:
$this->log("PNG is type 2, RGB");
$text = "PNG is type 2, RGB$transparent";
break;
case self::PNG_RGB_PALETTE:
$this->log("PNG is type 3, RGB with palette");
$text = "PNG is type 3, RGB with palette$transparent";
break;
case self::PNG_GREYSCALE_ALPHA:
$this->Log("PNG is type 4, Greyscale with alpha channel");
$text = "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)");
$text = "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?");
$text = "PNG is UNKNOWN type, is it really a PNG image?";
}
return $pngType;
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

@@ -13,21 +13,21 @@ class CWhitelist
/**
* Set the whitelist from an array of strings, each item in the
* Set the whitelist from an array of strings, each item in the
* whitelist should be a regexp without the surrounding / or #.
*
* @param array $whitelist with all valid options,
* @param array $whitelist with all valid options,
* default is to clear the whitelist.
*
* @return $this
*/
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;
}
@@ -44,8 +44,8 @@ class CWhitelist
public function check($item, $whitelist = null)
{
if ($whitelist !== null) {
$this->set($whitelist);
}
$this->set($whitelist);
}
if (empty($item) or empty($this->whitelist)) {
return false;

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>

197
functions.php Normal file
View File

@@ -0,0 +1,197 @@
<?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");
}
/**
* 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 of input from query string or else $undefined.
*
* @param mixed $key as string or array of string values to look for in $_GET.
* @param mixed $undefined value to return when $key has no, or empty value in $_GET.
*
* @return mixed value as or $undefined.
*/
function getValue($key, $undefined)
{
$val = get($key);
if (is_null($val) || $val === "") {
return $undefined;
}
return $val;
}
/**
* 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, $arg = "")
{
global $verbose, $verboseFile;
static $log = array();
if (!($verbose || $verboseFile)) {
return;
}
if (is_null($msg)) {
return $log;
}
if (is_null($arg)) {
$arg = "null";
} elseif ($arg === false) {
$arg = "false";
} elseif ($arg === true) {
$arg = "true";
}
$log[] = $msg . $arg;
}
/**
* 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.");
}
}

100
test/CImageDummyTest.php Normal file
View File

@@ -0,0 +1,100 @@
<?php
/**
* A testclass
*
*/
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
*
* @return void
*/
public function testCreate1()
{
$img = new CImage();
$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), self::DUMMY . "_100_100", "Filename not as expected on dummy image.");
}
/**
* Test
*
* @return void
*/
public function testCreate2()
{
$img = new CImage();
$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), 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

@@ -4,3 +4,6 @@
*
*/
require __DIR__ . "/../autoload.php";
define('IMAGE_PATH', __DIR__ . '/../webroot/img/');
define('CACHE_PATH', __DIR__ . '/../cache/');

View File

@@ -2,17 +2,33 @@
echo 'Current PHP version: ' . phpversion() . '<br><br>';
echo 'Running on: ' . $_SERVER['SERVER_SOFTWARE'] . '<br><br>';
$no = extension_loaded('gd') ? null : 'NOT';
echo "Extension gd is $no loaded.<br>";
if (!$no) {
echo "<pre>", var_dump(gd_info()), "</pre>";
}
echo 'Running on: ' . htmlentities($_SERVER['SERVER_SOFTWARE']) . '<br><br>';
$no = extension_loaded('exif') ? null : 'NOT';
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");
echo "<br>pngout: ";
system("which pngout");
echo "<br>jpegtran: ";
system("which jpegtran");

View File

@@ -3,6 +3,12 @@
<head>
<style>
<?php
function e($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
?>
body {
}
@@ -29,7 +35,12 @@ input[type=text] {
.area {
float: left;
padding: 1em;
background-color: #fff;
background-color: #eee;
}
.invert {
background-color: #666;
color: white;
}
.json {
@@ -45,7 +56,7 @@ input[type=text] {
<body>
<h1>Compare images</h1>
<p>Add link to images and visually compare them. Change the link och press return to load the image. <a href="http://dbwebb.se/opensource/cimage">Read more...</a></p>
<p>Add link to images and visually compare them. Change the link och press return to load the image. Add <code>&amp;black</code> to the querystring to get a black background. <a href="http://dbwebb.se/opensource/cimage">Read more...</a></p>
<p><a id="permalink" href="?">Direct link to this setup.</a></p>
@@ -55,8 +66,11 @@ input[type=text] {
<label>Image 2: <input type="text" id="input2" data-id="2"></label> <img id="thumb2"></br>
<label>Image 3: <input type="text" id="input3" data-id="3"></label> <img id="thumb3"></br>
<label>Image 4: <input type="text" id="input4" data-id="4"></label> <img id="thumb4"></br>
<label>Image 5: <input type="text" id="input5" data-id="5"></label> <img id="thumb5"></br>
<label>Image 6: <input type="text" id="input6" data-id="6"></label> <img id="thumb6"></br>
<label><input type="checkbox" id="viewDetails">Show image details</label><br/>
<label><input type="checkbox" id="stack">Stack images?</label>
<label><input type="checkbox" id="stack">Stack images?</label><br/>
<label><input type="checkbox" id="bg">Dark background?</label>
</p>
</form>
@@ -65,6 +79,8 @@ input[type=text] {
<button id="button2" class="button" data-id="2">Image 2</button>
<button id="button3" class="button" data-id="3">Image 3</button>
<button id="button4" class="button" data-id="4">Image 4</button>
<button id="button5" class="button" data-id="5">Image 5</button>
<button id="button6" class="button" data-id="6">Image 6</button>
</div>
<div id="wrap">
@@ -93,6 +109,18 @@ input[type=text] {
<pre id="json4" class="json hidden"></pre>
</div>
<div id="area5" class="area">
<code>Image 5</code><br>
<img id="img5">
<pre id="json5" class="json hidden"></pre>
</div>
<div id="area6" class="area">
<code>Image 6</code><br>
<img id="img6">
<pre id="json6" class="json hidden"></pre>
</div>
</div>
@@ -106,12 +134,15 @@ if (isset($_GET['input1'])) {
// Use incoming from querystring as defaults
?>
CImage.compare({
"input1": "<?=$_GET['input1']?>",
"input2": "<?=$_GET['input2']?>",
"input3": "<?=$_GET['input3']?>",
"input4": "<?=$_GET['input4']?>",
"json": <?=$_GET['json']?>,
"stack": <?=$_GET['stack']?>
"input1": "<?=e($_GET['input1'])?>",
"input2": "<?=e($_GET['input2'])?>",
"input3": "<?=e($_GET['input3'])?>",
"input4": "<?=e($_GET['input4'])?>",
"input5": "<?=e($_GET['input5'])?>",
"input6": "<?=e($_GET['input6'])?>",
"json": <?=e($_GET['json'])?>,
"stack": <?=e($_GET['stack'])?>,
"bg": <?=e($_GET['bg'])?>
});
<?php
} elseif (isset($script)) {

View File

@@ -0,0 +1,16 @@
<?php
$script = <<<EOD
CImage.compare({
"input1": "../img.php?src=issue117/tri_original.png",
"input2": "../img.php?src=issue117/tri_imageresizing.png",
"input3": "../img.php?src=issue117/tri_cimage.png",
"input4": "../img.php?src=issue117/tri_imagemagick.png",
"input5": "../img.php?src=issue117/tri_original.png&w=190",
"input6": "../img.php?src=issue117/tri_original.png&w=190&no-resample",
"json": true,
"stack": false,
"bg": true
});
EOD;
include __DIR__ . "/compare.php";

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,33 +8,6 @@
*
*/
$version = "v0.7.4 (2015-09-15)";
/**
* 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.
*/
@@ -44,95 +17,13 @@ set_exception_handler(function ($exception) {
. $exception->getMessage()
. "</p><pre>"
. $exception->getTraceAsString()
. "</pre>"
. "</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;
}
/**
* Get configuration options from file, if the file exists, else use $config
* if its defined or create an empty $config.
@@ -145,6 +36,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 +62,14 @@ 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);
/**
* status - do a verbose dump of the configuration
*/
$status = getDefined('status', true, false);
@@ -168,7 +84,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
@@ -178,14 +94,16 @@ if ($mode == 'strict') {
ini_set('display_errors', 0);
ini_set('log_errors', 1);
$verbose = false;
$status = false;
$verboseFile = false;
} elseif ($mode == 'production') {
error_reporting(-1);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
$verbose = false;
$status = false;
$verboseFile = false;
} elseif ($mode == 'development') {
@@ -202,7 +120,7 @@ if ($mode == 'strict') {
ini_set('log_errors', 0);
} else {
errorPage("Unknown mode: $mode");
errorPage("Unknown mode: $mode", 500);
}
verbose("mode = $mode");
@@ -235,7 +153,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;
@@ -251,7 +169,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");
@@ -268,16 +186,16 @@ $hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
$refererHost = parse_url($referer, PHP_URL_HOST);
$refererHost = parse_url($referer ?? "", PHP_URL_HOST);
if (!$allowHotlinking) {
if ($passwordMatch) {
; // Always allow when password match
verbose("Hotlinking since passwordmatch");
} elseif ($passwordMatch === false) {
errorPage("Hotlinking/leeching not allowed when password missmatch.");
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.");
@@ -288,11 +206,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);
}
}
@@ -303,24 +221,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();
}
@@ -332,8 +284,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);
@@ -365,37 +319,80 @@ if (isset($shortcut)
/**
* src - the source image file.
*/
$srcImage = urldecode(get('src'))
or errorPage('Must set src-attribute.');
$srcImage = urldecode(get('src', ""))
or errorPage('Must set src-attribute.', 404);
// Get settings for src-alt as backup image
$srcAltImage = urldecode(get('src-alt', ""));
$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-/_ \.:]+$#');
preg_match($validFilename, $srcImage)
or errorPage('Filename contains invalid characters.');
// Source is remote
$remoteSource = false;
if ($allowRemote && $img->isRemoteSource($srcImage)) {
// Dummy image feature
$dummyEnabled = getConfig('dummy_enabled', true);
$dummyFilename = getConfig('dummy_filename', 'dummy');
$dummyImage = false;
preg_match($validFilename, $srcImage)
or errorPage('Source filename contains invalid characters.', 404);
if ($dummyEnabled && $srcImage === $dummyFilename) {
// Prepare to create a dummy image and use it as the source image.
$dummyImage = true;
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
// If source is a remote file, ignore local file checks.
$remoteSource = true;
} 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
);
}
@@ -443,13 +440,13 @@ if (isset($sizes[$newWidth])) {
}
// Support width as % of original width
if ($newWidth[strlen($newWidth)-1] == '%') {
if ($newWidth && $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");
@@ -468,13 +465,13 @@ if (isset($sizes[$newHeight])) {
}
// height
if ($newHeight[strlen($newHeight)-1] == '%') {
if ($newHeight && $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");
@@ -499,7 +496,7 @@ $aspectRatioConstant = getConfig('aspect_ratio_constant', function () {
// Check to replace predefined aspect ratio
$aspectRatios = call_user_func($aspectRatioConstant);
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
$negateAspectRatio = ($aspectRatio && $aspectRatio[0] == '!') ? true : false;
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
if (isset($aspectRatios[$aspectRatio])) {
@@ -512,7 +509,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");
@@ -548,6 +545,19 @@ verbose("bgColor = $bgColor");
/**
* Do or do not resample image when resizing.
*/
$resizeStrategy = getDefined(array('no-resample'), true, false);
if ($resizeStrategy) {
$img->setCopyResizeStrategy($img::RESIZE);
verbose("Setting = Resize instead of resample");
}
/**
* fill-to-fit, ff - affecting the resulting image width, height and resize options
*/
@@ -599,28 +609,30 @@ 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
*/
$quality = get(array('quality', 'q'));
$qualityDefault = getConfig('jpg_quality', null);
is_null($quality)
or ($quality > 0 and $quality <= 100)
or errorPage('Quality out of range');
or errorPage('Quality out of range', 404);
if (is_null($quality) && !is_null($qualityDefault)) {
$quality = $qualityDefault;
}
verbose("quality = $quality");
@@ -630,11 +642,15 @@ verbose("quality = $quality");
* compress, co - what strategy to use when compressing png images
*/
$compress = get(array('compress', 'co'));
$compressDefault = getConfig('png_compression', null);
is_null($compress)
or ($compress > 0 and $compress <= 9)
or errorPage('Compress out of range');
or errorPage('Compress out of range', 404);
if (is_null($compress) && !is_null($compressDefault)) {
$compress = $compressDefault;
}
verbose("compress = $compress");
@@ -656,7 +672,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");
@@ -705,7 +721,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");
@@ -718,7 +734,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");
@@ -840,6 +856,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',
@@ -852,6 +871,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.
@@ -867,13 +895,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");
@@ -881,9 +909,203 @@ verbose("alias = $alias");
/**
* Get the cachepath from config.
* Add cache control HTTP header.
*/
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
$cacheControl = getConfig('cache_control', null);
if ($cacheControl) {
verbose("cacheControl = $cacheControl");
$img->addHTTPHeader("Cache-Control", $cacheControl);
}
/**
* interlace - Enable configuration for interlaced progressive JPEG images.
*/
$interlaceConfig = getConfig('interlace', null);
$interlaceValue = getValue('interlace', null);
$interlaceDefined = getDefined('interlace', true, null);
$interlace = $interlaceValue ?? $interlaceDefined ?? $interlaceConfig;
verbose("interlace (configfile) = ", $interlaceConfig);
verbose("interlace = ", $interlace);
/**
* Prepare a dummy image and use it as source image.
*/
if ($dummyImage === true) {
$dummyDir = $cache->getPathToSubdir("dummy");
$img->setSaveFolder($dummyDir)
->setSource($dummyFilename, $dummyDir)
->setOptions(
array(
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'bgColor' => $bgColor,
)
)
->setJpegQuality($quality)
->setPngCompression($compress)
->createDummyImage()
->generateFilename(null, false)
->save(null, null, false);
$srcImage = $img->getTarget();
$imagePath = null;
verbose("src (updated) = $srcImage");
}
/**
* Prepare a sRGB version of the image and use it as source image.
*/
$srgbDefault = getConfig('srgb_default', false);
$srgbColorProfile = getConfig('srgb_colorprofile', __DIR__ . '/../icc/sRGB_IEC61966-2-1_black_scaled.icc');
$srgb = getDefined('srgb', true, null);
if ($srgb || $srgbDefault) {
$filename = $img->convert2sRGBColorSpace(
$srcImage,
$imagePath,
$cache->getPathToSubdir("srgb"),
$srgbColorProfile,
$useCache
);
if ($filename) {
$srcImage = $img->getTarget();
$imagePath = null;
verbose("srgb conversion and saved to cache = $srcImage");
} else {
verbose("srgb not op");
}
}
/**
* Display status
*/
if ($status) {
$text = "img.php version = " . CIMAGE_VERSION . "\n";
$text .= "PHP version = " . PHP_VERSION . "\n";
$text .= "Running on: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
$text .= "Allow remote images = $allowRemote\n";
$res = $cache->getStatusOfSubdir("");
$text .= "Cache $res\n";
$res = $cache->getStatusOfSubdir("remote");
$text .= "Cache remote $res\n";
$res = $cache->getStatusOfSubdir("dummy");
$text .= "Cache dummy $res\n";
$res = $cache->getStatusOfSubdir("srgb");
$text .= "Cache srgb $res\n";
$res = $cache->getStatusOfSubdir($fastTrackCache);
$text .= "Cache fasttrack $res\n";
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
$no = extension_loaded('exif') ? null : 'NOT';
$text .= "Extension exif is $no loaded.<br>";
$no = extension_loaded('curl') ? null : 'NOT';
$text .= "Extension curl is $no loaded.<br>";
$no = extension_loaded('imagick') ? null : 'NOT';
$text .= "Extension imagick is $no loaded.<br>";
$no = extension_loaded('gd') ? null : 'NOT';
$text .= "Extension gd is $no loaded.<br>";
$text .= checkExternalCommand("PNG LOSSY", $postProcessing["png_lossy"], $postProcessing["png_lossy_cmd"]);
$text .= checkExternalCommand("PNG FILTER", $postProcessing["png_filter"], $postProcessing["png_filter_cmd"]);
$text .= checkExternalCommand("PNG DEFLATE", $postProcessing["png_deflate"], $postProcessing["png_deflate_cmd"]);
$text .= checkExternalCommand("JPEG OPTIMIZE", $postProcessing["jpeg_optimize"], $postProcessing["jpeg_optimize_cmd"]);
if (!$no) {
$text .= print_r(gd_info(), 1);
}
echo <<<EOD
<!doctype html>
<html lang=en>
<meta charset=utf-8>
<title>CImage status</title>
<pre>$text</pre>
EOD;
exit;
}
/**
* Log verbose details to file
*/
if ($verboseFile) {
$img->setVerboseToFile("$cachePath/log.txt");
}
/**
* Hook after img.php configuration and before processing with CImage
*/
$hookBeforeCImage = getConfig('hook_before_CImage', null);
if (is_callable($hookBeforeCImage)) {
verbose("hookBeforeCImage activated");
$allConfig = $hookBeforeCImage($img, array(
// Options for calculate dimensions
'newWidth' => $newWidth,
'newHeight' => $newHeight,
'aspectRatio' => $aspectRatio,
'keepRatio' => $keepRatio,
'cropToFit' => $cropToFit,
'fillToFit' => $fillToFit,
'crop' => $crop,
'area' => $area,
'upscale' => $upscale,
// Pre-processing, before resizing is done
'scale' => $scale,
'rotateBefore' => $rotateBefore,
'autoRotate' => $autoRotate,
// General processing options
'bgColor' => $bgColor,
// Post-processing, after resizing is done
'palette' => $palette,
'filters' => $filters,
'sharpen' => $sharpen,
'emboss' => $emboss,
'blur' => $blur,
'convolve' => $convolve,
'rotateAfter' => $rotateAfter,
'interlace' => $interlace,
// Output format
'outputFormat' => $outputFormat,
'dpr' => $dpr,
// Other
'postProcessing' => $postProcessing,
'lossy' => $lossy,
));
verbose(print_r($allConfig, 1));
extract($allConfig);
}
@@ -914,7 +1136,7 @@ if ($verbose) {
window.getDetails = function (url, id) {
$.getJSON(url, function(data) {
element = document.getElementById(id);
element.innerHTML = "filename: " + data.filename + "\\nmime type: " + data.mimeType + "\\ncolors: " + data.colors + "\\nsize: " + data.size + "\\nwidth: " + data.width + "\\nheigh: " + data.height + "\\naspect-ratio: " + data.aspectRatio;
element.innerHTML = "filename: " + data.filename + "\\nmime type: " + data.mimeType + "\\ncolors: " + data.colors + "\\nsize: " + data.size + "\\nwidth: " + data.width + "\\nheigh: " + data.height + "\\naspect-ratio: " + data.aspectRatio + ( data.pngType ? "\\npng-type: " + data.pngType : '');
});
}
</script>
@@ -925,18 +1147,10 @@ EOD;
/**
* Log verbose details to file
* Load, process and output the image
*/
if ($verboseFile) {
$img->setVerboseToFile("$cachePath/log.txt");
}
/**
* Load, process and output the image
*/
$img->log("Incoming arguments: " . print_r(verbose(), 1))
$img->log("PHP version: " . phpversion())
->log("Incoming arguments: " . print_r(verbose(), 1))
->setSaveFolder($cachePath)
->useCache($useCache)
->setSource($srcImage, $imagePath)
@@ -969,10 +1183,14 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
'blur' => $blur,
'convolve' => $convolve,
'rotateAfter' => $rotateAfter,
'interlace' => $interlace,
// 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -5,28 +5,63 @@
* 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");
}
/**
* Set this if you work with a webserver in Windows and try to access files
* within WSL2.
* The issue seems to be with functions like `is_writable()` and
* `is_readable()`.
* When WINDOWS2WSL is defined (to any value) it ignores these functions.
*/
#define('WINDOWS2WSL', 1);
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',
//'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,13 +70,41 @@ 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/',
//'alias_path' => __DIR__ . '/img/alias/',
'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',
@@ -62,7 +125,7 @@ return array(
* password_type: 'text' // use plain password, not encoded,
*/
//'password_always' => false, // always require password,
//'password' => false, // "secret-password",
//'password' => "moped", // "secret-password",
//'password_type' => 'text', // supports 'text', 'md5', 'hash',
@@ -97,6 +160,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.
*
@@ -109,10 +186,98 @@ return array(
/**
* 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,
/**
* 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.
* 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 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_enabled' => true,
//'dummy_filename' => 'dummy',
/**
* 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
@@ -165,8 +330,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'
*
@@ -178,6 +351,9 @@ return array(
*/
/*
'postprocessing' => array(
'png_lossy' => null,
'png_lossy_cmd' => '/usr/local/bin/pngquant --force --output',
'png_filter' => false,
'png_filter_cmd' => '/usr/local/bin/optipng -q',
@@ -303,7 +479,7 @@ return array(
/**
* default options for ascii image.
* Default options for ascii image.
*
* Default values as specified below in the array.
* ascii-options:
@@ -318,6 +494,18 @@ return array(
"scale" => 14,
"luminanceStrategy" => 3,
"customCharacterSet" => null,
);
},*/
), */
/**
* Default options for creating interlaced progressive JPEG images. Set
* to true to always render jpeg images as interlaced. This setting can
* be overridden by using `?interlace`, `?interlace=true` or
* `?interlace=false`.
*
* Default values are:
* interlace: false
*/
/*'interlace' => false,*/
);

View File

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

1982
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

1982
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

@@ -25,8 +25,11 @@ window.CImage = (function() {
input2 = document.getElementById("input2"),
input3 = document.getElementById("input3"),
input4 = document.getElementById("input4"),
input5 = document.getElementById("input5"),
input6 = document.getElementById("input6"),
details = document.getElementById("viewDetails"),
stack = document.getElementById("stack"),
bg = document.getElementById("bg"),
permalink = document.getElementById("permalink");
link = "?";
@@ -34,8 +37,11 @@ window.CImage = (function() {
link += "input2=" + encodeURIComponent(input2.value) + "&";
link += "input3=" + encodeURIComponent(input3.value) + "&";
link += "input4=" + encodeURIComponent(input4.value) + "&";
link += "input5=" + encodeURIComponent(input5.value) + "&";
link += "input6=" + encodeURIComponent(input6.value) + "&";
link += "json=" + encodeURIComponent(details.checked) + "&";
link += "stack=" + encodeURIComponent(stack.checked);
link += "stack=" + encodeURIComponent(stack.checked) + "&";
link += "bg=" + encodeURIComponent(bg.checked);
permalink.href = link;
}
@@ -69,7 +75,7 @@ window.CImage = (function() {
area.classList.remove("hidden");
$.getJSON(this.value + "&json", function(data) {
json.innerHTML = "filename: " + data.filename + "\ncolors: " + data.colors + "\nsize: " + data.size + "\nwidth: " + data.width + "\nheigh: " + data.height + "\naspect-ratio: " + data.aspectRatio;
json.innerHTML = "filename: " + data.filename + "\ncolors: " + data.colors + "\nsize: " + data.size + "\nwidth: " + data.width + "\nheigh: " + data.height + "\naspect-ratio: " + data.aspectRatio + "\npng-type: " + data.pngType;
})
.fail(function() {
json.innerHTML = "Details not available."
@@ -95,14 +101,19 @@ window.CImage = (function() {
input2 = document.getElementById("input2"),
input3 = document.getElementById("input3"),
input4 = document.getElementById("input4"),
input5 = document.getElementById("input5"),
input6 = document.getElementById("input6"),
details = document.getElementById("viewDetails"),
stack = document.getElementById("stack"),
bg = document.getElementById("bg"),
buttons = document.getElementById("buttonWrap");
input1.addEventListener("change", compareLoadImage);
input2.addEventListener("change", compareLoadImage);
input3.addEventListener("change", compareLoadImage);
input4.addEventListener("change", compareLoadImage);
input5.addEventListener("change", compareLoadImage);
input6.addEventListener("change", compareLoadImage);
// Toggle json
details.addEventListener("change", function() {
@@ -129,6 +140,23 @@ window.CImage = (function() {
details.dispatchEvent(myEvent);
}
// Toggle background color
bg.addEventListener("change", function() {
var elements = document.querySelectorAll(".area");
forEach(elements, function (index, element) {
element.classList.toggle("invert");
});
});
// Check background
if (options.bg === true) {
bg.setAttribute("checked", "checked");
bg.classList.toggle("invert");
myEvent = new CustomEvent("change");
bg.dispatchEvent(myEvent);
}
// Toggle stack
stack.addEventListener("change", function() {
var element,
@@ -200,11 +228,15 @@ window.CImage = (function() {
input2.value = options.input2 || null;
input3.value = options.input3 || null;
input4.value = options.input4 || null;
input5.value = options.input5 || null;
input6.value = options.input6 || null;
compareLoadImage.call(input1);
compareLoadImage.call(input2);
compareLoadImage.call(input3);
compareLoadImage.call(input4);
compareLoadImage.call(input5);
compareLoadImage.call(input6);
console.log(options);
}

View File

@@ -0,0 +1,36 @@
<?php
// Include config for all testcases
include __DIR__ . "/config.php";
// The title of the test case
$title = "Testing issue 100 - Dummy images";
// Provide a short description of the testcase.
$description = "Create dummy images.";
// Use these images in the test
$images = array(
'dummy',
);
// For each image, apply these testcases
$testcase = array(
'&nc&so',
'&nc&width=300',
'&nc&height=300',
'&nc&width=300&height=300',
'&nc&bgc=006600',
);
// Apply testcases and present results
include __DIR__ . "/template.php";

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',

22
webroot/tests.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
$links = [
"img.php?src=car.png&v",
"img.php?src=car.png&w=700&v",
];
?><!doctype html>
<html>
<head>
<title>Links to use for testing</title>
</head>
<body>
<h1>Links useful for testing</h1>
<p>A collection of linkt to use to test various aspects of the cimage process.</p>
<ul>
<?php foreach ($links as $link) : ?>
<li><a href="<?= $link ?>"><?= $link ?></a></li>
<?php endforeach; ?>
</ul>
</body>
</html>