mirror of
https://github.com/mosbth/cimage.git
synced 2025-08-26 09:04:26 +02:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
daf39105fb | ||
|
026e01b2cd | ||
|
0f0d954e61 | ||
|
58d83ba494 | ||
|
4f8fb82baf | ||
|
1bd8965535 | ||
|
081601ebbb | ||
|
401478c839 | ||
|
f0ab9479d6 | ||
|
9ff7a61ca9 | ||
|
3170beb832 | ||
|
8001f72a1a | ||
|
0f9e0220f1 | ||
|
e59ef91991 | ||
|
2337dbe94c | ||
|
c5de59a754 | ||
|
547259cd11 | ||
|
fbaf05d0d4 | ||
|
3d2c74e9df | ||
|
74428f066c | ||
|
00ab2d7ca6 | ||
|
d5546b669b | ||
|
53fb8da987 | ||
|
226f8adbeb | ||
|
29d18c4b3c | ||
|
d697809a69 | ||
|
8667a9ec79 | ||
|
ca6118b355 | ||
|
cf2fc3de4f | ||
|
276f46fce2 | ||
|
0f3c1b4bde | ||
|
f2153e27a8 | ||
|
7e5937d7ec | ||
|
3c77a63fbc | ||
|
13da8b0573 | ||
|
52ce33d928 | ||
|
5a09c38f5d | ||
|
679714422d | ||
|
ec72246e9c | ||
|
389c3c48ee | ||
|
fcedac6e62 | ||
|
3daa8549ab | ||
|
6a93f843be | ||
|
f9b149eb5d | ||
|
e41e23c007 | ||
|
5673ce4f55 | ||
|
9bf94e9cf6 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,16 +1,17 @@
|
||||
# Cache files
|
||||
cache/*
|
||||
|
||||
# Test
|
||||
# Test & build
|
||||
build/
|
||||
coverage/
|
||||
coverage.clover
|
||||
|
||||
# Composer
|
||||
composer.lock
|
||||
vendor
|
||||
#vendor/
|
||||
|
||||
# Build and test
|
||||
build/
|
||||
/.bin
|
||||
|
||||
# Mac OS
|
||||
.DS_Store
|
||||
|
@@ -2,12 +2,12 @@
|
||||
<ruleset name="PHPCS rule set">
|
||||
<description>Custom rule set.</description>
|
||||
|
||||
<file>.</file>
|
||||
<file>src</file>
|
||||
<file>test</file>
|
||||
<file>autoload.php</file>
|
||||
|
||||
<exclude-pattern>docs/*</exclude-pattern>
|
||||
<exclude-pattern>coverage/*</exclude-pattern>
|
||||
<exclude-pattern>build/*</exclude-pattern>
|
||||
<exclude-pattern>test/config.php</exclude-pattern>
|
||||
<exclude-pattern>webroot/imgs.php</exclude-pattern>
|
||||
<exclude-pattern>webroot/imgp.php</exclude-pattern>
|
||||
<exclude-pattern>webroot/imgd.php</exclude-pattern>
|
26
.phpunit.xml
Normal file
26
.phpunit.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpunit
|
||||
bootstrap="test/config.php">
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="all">
|
||||
<directory>test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src/</directory>
|
||||
<exclude>
|
||||
<directory suffix=".php">test</directory>
|
||||
<directory suffix=".php">webroot</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-html" target="build/coverage" charset="UTF-8" highlight="true" lowUpperBound="35" highLowerBound="70" />
|
||||
<log type="coverage-clover" target="build/coverage.clover" />
|
||||
</logging>
|
||||
|
||||
</phpunit>
|
@@ -10,37 +10,45 @@ filter:
|
||||
- webroot/imgs.php
|
||||
- webroot/test/
|
||||
|
||||
checks:
|
||||
php:
|
||||
code_rating: true
|
||||
duplication: true
|
||||
#checks:
|
||||
# php:
|
||||
# code_rating: true
|
||||
# duplication: true
|
||||
|
||||
tools:
|
||||
#tools:
|
||||
# Copy/Paste Detector
|
||||
php_cpd: true
|
||||
#php_cpd: true
|
||||
|
||||
# Metrics
|
||||
php_pdepend: true
|
||||
#php_pdepend: true
|
||||
|
||||
# Some Metrics + Bug Detection/Auto-Fixes
|
||||
php_analyzer: true
|
||||
#php_analyzer: true
|
||||
|
||||
php_code_sniffer:
|
||||
config:
|
||||
standard: "PSR2"
|
||||
#php_code_sniffer:
|
||||
# config:
|
||||
# standard: "PSR2"
|
||||
|
||||
php_sim:
|
||||
min_mass: 16 # Defaults to 16
|
||||
#php_sim:
|
||||
# min_mass: 16 # Defaults to 16
|
||||
|
||||
php_mess_detector:
|
||||
#php_mess_detector:
|
||||
#config:
|
||||
# ruleset: ../your-phpmd-ruleset/ruleset.xml
|
||||
|
||||
|
||||
|
||||
build:
|
||||
|
||||
dependencies:
|
||||
before:
|
||||
-
|
||||
command: 'mkdir build'
|
||||
|
||||
tests:
|
||||
override:
|
||||
-
|
||||
command: 'phpunit'
|
||||
command: 'phpunit --configuration .phpunit.xml'
|
||||
coverage:
|
||||
file: 'coverage.clover'
|
||||
file: 'build/coverage.clover'
|
||||
format: 'php-clover'
|
||||
|
46
.travis.yml
46
.travis.yml
@@ -4,9 +4,10 @@ php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- "7.0"
|
||||
- "7.1"
|
||||
- hhvm
|
||||
- nightly
|
||||
- "7.0"
|
||||
|
||||
|
||||
|
||||
@@ -35,50 +36,13 @@ matrix:
|
||||
|
||||
|
||||
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
|
||||
- make install
|
||||
- make check
|
||||
|
||||
|
||||
|
||||
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
|
||||
- make test
|
||||
|
||||
|
||||
|
||||
|
227
Makefile
Normal file
227
Makefile
Normal file
@@ -0,0 +1,227 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Detect OS
|
||||
OS = $(shell uname -s)
|
||||
|
||||
# Defaults
|
||||
ECHO = echo
|
||||
|
||||
# Make adjustments based on OS
|
||||
# http://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux/27776822#27776822
|
||||
ifneq (, $(findstring CYGWIN, $(OS)))
|
||||
ECHO = /bin/echo -e
|
||||
endif
|
||||
|
||||
# Colors and helptext
|
||||
NO_COLOR = \033[0m
|
||||
ACTION = \033[32;01m
|
||||
OK_COLOR = \033[32;01m
|
||||
ERROR_COLOR = \033[31;01m
|
||||
WARN_COLOR = \033[33;01m
|
||||
|
||||
# Which makefile am I in?
|
||||
WHERE-AM-I = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||
THIS_MAKEFILE := $(call WHERE-AM-I)
|
||||
|
||||
# Echo some nice helptext based on the target comment
|
||||
HELPTEXT = $(ECHO) "$(ACTION)--->" `egrep "^\# target: $(1) " $(THIS_MAKEFILE) | sed "s/\# target: $(1)[ ]*-[ ]* / /g"` "$(NO_COLOR)"
|
||||
|
||||
# Add local bin path for test tools
|
||||
#PATH := "./.bin:./vendor/bin:./node_modules/.bin:$(PATH)"
|
||||
#SHELL := env PATH=$(PATH) $(SHELL)
|
||||
PHPUNIT := .bin/phpunit
|
||||
PHPLOC := .bin/phploc
|
||||
PHPCS := .bin/phpcs
|
||||
PHPCBF := .bin/phpcbf
|
||||
PHPMD := .bin/phpmd
|
||||
PHPDOC := .bin/phpdoc
|
||||
BEHAT := .bin/behat
|
||||
|
||||
|
||||
|
||||
# target: help - Displays help.
|
||||
.PHONY: help
|
||||
help:
|
||||
@$(call HELPTEXT,$@)
|
||||
@$(ECHO) "Usage:"
|
||||
@$(ECHO) " make [target] ..."
|
||||
@$(ECHO) "target:"
|
||||
@egrep "^# target:" $(THIS_MAKEFILE) | sed 's/# target: / /g'
|
||||
|
||||
|
||||
|
||||
# target: prepare - Prepare for tests and build
|
||||
.PHONY: prepare
|
||||
prepare:
|
||||
@$(call HELPTEXT,$@)
|
||||
[ -d .bin ] || mkdir .bin
|
||||
[ -d build ] || mkdir build
|
||||
rm -rf build/*
|
||||
|
||||
|
||||
|
||||
# target: clean - Removes generated files and directories.
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(call HELPTEXT,$@)
|
||||
rm -rf build
|
||||
|
||||
|
||||
|
||||
# target: clean-all - Removes generated files and directories.
|
||||
.PHONY: clean-all
|
||||
clean-all:
|
||||
@$(call HELPTEXT,$@)
|
||||
rm -rf .bin build vendor composer.lock
|
||||
|
||||
|
||||
|
||||
# target: check - Check version of installed tools.
|
||||
.PHONY: check
|
||||
check: check-tools-php
|
||||
@$(call HELPTEXT,$@)
|
||||
|
||||
|
||||
|
||||
# target: test - Run all tests.
|
||||
.PHONY: test
|
||||
test: phpunit phpcs phpmd phploc behat
|
||||
@$(call HELPTEXT,$@)
|
||||
composer validate
|
||||
|
||||
|
||||
|
||||
# target: doc - Generate documentation.
|
||||
.PHONY: doc
|
||||
doc: phpdoc
|
||||
@$(call HELPTEXT,$@)
|
||||
|
||||
|
||||
|
||||
# target: build - Do all build
|
||||
.PHONY: build
|
||||
build: test doc #less-compile less-minify js-minify
|
||||
@$(call HELPTEXT,$@)
|
||||
|
||||
|
||||
|
||||
# target: install - Install all tools
|
||||
.PHONY: install
|
||||
install: prepare install-tools-php
|
||||
@$(call HELPTEXT,$@)
|
||||
|
||||
|
||||
|
||||
# target: update - Update the codebase and tools.
|
||||
.PHONY: update
|
||||
update:
|
||||
@$(call HELPTEXT,$@)
|
||||
git pull
|
||||
composer update
|
||||
|
||||
|
||||
|
||||
# target: tag-prepare - Prepare to tag new version.
|
||||
.PHONY: tag-prepare
|
||||
tag-prepare:
|
||||
@$(call HELPTEXT,$@)
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
# PHP
|
||||
#
|
||||
|
||||
# target: install-tools-php - Install PHP development tools.
|
||||
.PHONY: install-tools-php
|
||||
install-tools-php:
|
||||
@$(call HELPTEXT,$@)
|
||||
curl -Lso $(PHPDOC) https://www.phpdoc.org/phpDocumentor.phar && chmod 755 $(PHPDOC)
|
||||
|
||||
curl -Lso $(PHPCS) https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar && chmod 755 $(PHPCS)
|
||||
|
||||
curl -Lso $(PHPCBF) https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar && chmod 755 $(PHPCBF)
|
||||
|
||||
curl -Lso $(PHPMD) http://static.phpmd.org/php/latest/phpmd.phar && chmod 755 $(PHPMD)
|
||||
|
||||
curl -Lso $(PHPUNIT) https://phar.phpunit.de/phpunit-5.7.9.phar && chmod 755 $(PHPUNIT)
|
||||
|
||||
curl -Lso $(PHPLOC) https://phar.phpunit.de/phploc.phar && chmod 755 $(PHPLOC)
|
||||
|
||||
curl -Lso $(BEHAT) https://github.com/Behat/Behat/releases/download/v3.3.0/behat.phar && chmod 755 $(BEHAT)
|
||||
|
||||
composer install
|
||||
|
||||
|
||||
|
||||
|
||||
# target: check-tools-php - Check versions of PHP tools.
|
||||
.PHONY: check-tools-php
|
||||
check-tools-php:
|
||||
@$(call HELPTEXT,$@)
|
||||
which $(PHPUNIT) && $(PHPUNIT) --version
|
||||
which $(PHPLOC) && $(PHPLOC) --version
|
||||
which $(PHPCS) && $(PHPCS) --version && echo
|
||||
which $(PHPMD) && $(PHPMD) --version && echo
|
||||
which $(PHPCBF) && $(PHPCBF) --version && echo
|
||||
which $(PHPDOC) && $(PHPDOC) --version && echo
|
||||
which $(BEHAT) && $(BEHAT) --version && echo
|
||||
|
||||
|
||||
|
||||
# target: phpunit - Run unit tests for PHP.
|
||||
.PHONY: phpunit
|
||||
phpunit: prepare
|
||||
@$(call HELPTEXT,$@)
|
||||
$(PHPUNIT) --configuration .phpunit.xml
|
||||
|
||||
|
||||
|
||||
# target: phpcs - Codestyle for PHP.
|
||||
.PHONY: phpcs
|
||||
phpcs: prepare
|
||||
@$(call HELPTEXT,$@)
|
||||
$(PHPCS) --standard=.phpcs.xml | tee build/phpcs
|
||||
|
||||
|
||||
|
||||
# target: phpcbf - Fix codestyle for PHP.
|
||||
.PHONY: phpcbf
|
||||
phpcbf:
|
||||
@$(call HELPTEXT,$@)
|
||||
$(PHPCBF) --standard=.phpcs.xml
|
||||
|
||||
|
||||
|
||||
# target: phpmd - Mess detector for PHP.
|
||||
.PHONY: phpmd
|
||||
phpmd: prepare
|
||||
@$(call HELPTEXT,$@)
|
||||
- $(PHPMD) . text .phpmd.xml | tee build/phpmd
|
||||
|
||||
|
||||
|
||||
# target: phploc - Code statistics for PHP.
|
||||
.PHONY: phploc
|
||||
phploc: prepare
|
||||
@$(call HELPTEXT,$@)
|
||||
$(PHPLOC) src > build/phploc
|
||||
|
||||
|
||||
|
||||
# target: phpdoc - Create documentation for PHP.
|
||||
.PHONY: phpdoc
|
||||
phpdoc:
|
||||
@$(call HELPTEXT,$@)
|
||||
$(PHPDOC) --config=.phpdoc.xml
|
||||
|
||||
|
||||
|
||||
# target: behat - Run behat for feature tests.
|
||||
.PHONY: behat
|
||||
behat:
|
||||
@$(call HELPTEXT,$@)
|
||||
$(BEHAT)
|
16
README.md
16
README.md
@@ -2,8 +2,14 @@ Image conversion on the fly using PHP
|
||||
=====================================
|
||||
|
||||
[](https://gitter.im/mosbth/cimage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/mosbth/cimage)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
||||
[](https://travis-ci.org/mosbth/cimage)
|
||||
[](https://circleci.com/gh/mosbth/cimage)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/resize)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/?branch=resize)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/?branch=resize)
|
||||
[](https://insight.sensiolabs.com/projects/ebc10d27-449d-42ca-b380-ba5ecb7813ba)
|
||||
|
||||
|
||||
|
||||
About
|
||||
-------------------------------------
|
||||
@@ -49,14 +55,14 @@ There are several ways of installing. You either install the whole project which
|
||||
|
||||
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
|
||||
|
||||
**Latest stable version is v0.7.16 released 2016-08-09.**
|
||||
**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.16
|
||||
git checkout v0.7.18
|
||||
```
|
||||
|
||||
Make the cache-directory writable by the webserver.
|
||||
@@ -79,7 +85,7 @@ There are some all-included bundles of `img.php` that can be downloaded and used
|
||||
Dowload the version of your choice like this.
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/mosbth/cimage/v0.7.16/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.
|
||||
|
36
REVISION.md
36
REVISION.md
@@ -1,8 +1,40 @@
|
||||
Revision history
|
||||
=====================================
|
||||
|
||||
[](https://travis-ci.org/mosbth/cimage)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
||||
|
||||
|
||||
v0.8.* (2015-12-05) (branch resize)
|
||||
-------------------------------------
|
||||
|
||||
* Improving build phase using travis and scrutinizer.
|
||||
* Code validating with phpunit and phpcs.
|
||||
* Moved classes to src/, adding namespace and (only) support PSR-4.
|
||||
* Require PHP 5.4.
|
||||
|
||||
|
||||
v0.7.9* (2015-12-07)
|
||||
-------------------------------------
|
||||
|
||||
* Fix strict mode only reporting 404 when failure, #127.
|
||||
|
||||
|
||||
v0.7.19* (2016-08-31)
|
||||
-------------------------------------
|
||||
|
||||
* 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)
|
||||
|
13
circle.yml
Normal file
13
circle.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
machine:
|
||||
php:
|
||||
#version: 5.6.18
|
||||
|
||||
|
||||
|
||||
test:
|
||||
pre:
|
||||
- make install
|
||||
- make check
|
||||
|
||||
override:
|
||||
- make test
|
@@ -1,42 +1,39 @@
|
||||
{
|
||||
"name": "mos/cimage",
|
||||
"name": "mos/cimage",
|
||||
"type": "library",
|
||||
"description": "Process, scale, resize, crop and filter images.",
|
||||
"keywords": ["image", "imageprocessing", "gd"],
|
||||
"homepage": "http://dbwebb.se/opensource/cimage",
|
||||
"description": "Serverside image processing with PHP GD. Process, scale, resize, crop and filter images.",
|
||||
"keywords": ["image", "imageprocessing", "gd", "crop", "resize"],
|
||||
"homepage": "https://cimage.se/",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mikael Roos",
|
||||
"email": "me@mikaelroos.se",
|
||||
"email": "mos@dbwebb.se",
|
||||
"homepage": "http://mikaelroos.se",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/mosbth/cimage",
|
||||
"issues": "https://github.com/mosbth/cimage/issues",
|
||||
"docs": "http://dbwebb.se/opensource/cimage"
|
||||
"docs": "https://cimage.se/doc"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3",
|
||||
"ext-gd": "*"
|
||||
"php": ">=5.4",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-exif": "*"
|
||||
"ext-exif": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-imagick": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"defines.php",
|
||||
"functions.php"
|
||||
],
|
||||
"classmap": [
|
||||
"CImage.php",
|
||||
"CHttpGet.php",
|
||||
"CRemoteImage.php",
|
||||
"CWhitelist.php",
|
||||
"CAsciiArt.php",
|
||||
"CCache.php",
|
||||
"CFastTrackCache.php"
|
||||
"psr-4": {
|
||||
"Mos\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/defines.php",
|
||||
"src/functions.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
20
composer.lock
generated
Normal file
20
composer.lock
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "336411b967cf65e460236df4df7e340a",
|
||||
"packages": [],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=5.4",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"platform-dev": []
|
||||
}
|
208
features/bootstrap/FeatureContext.php
Normal file
208
features/bootstrap/FeatureContext.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
use Behat\Behat\Tester\Exception\PendingException;
|
||||
use Behat\Behat\Context\Context;
|
||||
use Behat\Behat\Context\SnippetAcceptingContext;
|
||||
use Behat\Gherkin\Node\PyStringNode;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
|
||||
require __DIR__ . "/assert.php";
|
||||
|
||||
/**
|
||||
* Defines application features from the specific context.
|
||||
*/
|
||||
class FeatureContext implements Context, SnippetAcceptingContext
|
||||
{
|
||||
private $url = null;
|
||||
|
||||
private $headers = [];
|
||||
private $imageString = null;
|
||||
private $image = null;
|
||||
private $imageJSON = null;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes context.
|
||||
*
|
||||
* Every scenario gets its own context instance.
|
||||
* You can also pass arbitrary arguments to the
|
||||
* context constructor through behat.yml.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Given Set mode :arg1
|
||||
*/
|
||||
public function setMode($arg1 = null)
|
||||
{
|
||||
$this->url = "http://localhost/git/cimage/webroot/";
|
||||
switch ($arg1) {
|
||||
case "development":
|
||||
$this->url .= "imgd.php";
|
||||
break;
|
||||
case "production":
|
||||
$this->url .= "imgp.php";
|
||||
break;
|
||||
case "strict":
|
||||
$this->url .= "imgs.php";
|
||||
break;
|
||||
default:
|
||||
$this->url .= "img.php";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Given Set src :arg1
|
||||
*/
|
||||
public function setSrc($arg1)
|
||||
{
|
||||
if (is_null($this->url)) {
|
||||
$this->setMode();
|
||||
}
|
||||
|
||||
$this->url .= "?src=$arg1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @When Get image
|
||||
*/
|
||||
public function getImage()
|
||||
{
|
||||
//echo $this->url;
|
||||
$res = file_get_contents($this->url);
|
||||
assertNotEquals(false, $res);
|
||||
|
||||
$this->imageString = $res;
|
||||
$this->headers = $http_response_header;
|
||||
|
||||
if (is_null($this->imageJSON)) {
|
||||
$this->getImageAsJson();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @When Get image as JSON
|
||||
*/
|
||||
public function getImageAsJson()
|
||||
{
|
||||
$res = file_get_contents($this->url . "&json");
|
||||
assertNotEquals(false, $res);
|
||||
|
||||
$res = json_decode($res, true);
|
||||
assertNotEquals(null, $res);
|
||||
|
||||
$this->imageJSON = $res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @When Get headers for image
|
||||
*/
|
||||
public function getHeadersForImage()
|
||||
{
|
||||
//echo $this->url;
|
||||
$res = get_headers($this->url);
|
||||
assertNotEquals(false, $res);
|
||||
|
||||
$this->headers = $http_response_header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Then Returns status code :arg1
|
||||
*/
|
||||
public function returnsStatusCode($arg1)
|
||||
{
|
||||
assertNotEquals(
|
||||
false,
|
||||
strpos($this->headers[0], $arg1)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function compareImageJsonToHeaders()
|
||||
{
|
||||
$contentLength = "Content-Length: " . $this->imageJSON["size"];
|
||||
assertContains(
|
||||
$contentLength,
|
||||
$this->headers
|
||||
);
|
||||
|
||||
$contentType = "Content-Type: " . $this->imageJSON["mimeType"];
|
||||
assertContains(
|
||||
$contentType,
|
||||
$this->headers
|
||||
);
|
||||
|
||||
$lastModified = "Last-Modified: " . $this->imageJSON["cacheGmdate"] . " GMT";
|
||||
assertContains(
|
||||
$lastModified,
|
||||
$this->headers
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function compareImageJsonToSavedJson($file)
|
||||
{
|
||||
$res = file_get_contents("$file.json");
|
||||
assertNotEquals(false, $res);
|
||||
|
||||
$res = json_decode($res, true);
|
||||
assertNotEquals(null, $res);
|
||||
|
||||
$keys = [
|
||||
"mimeType",
|
||||
"width",
|
||||
"height",
|
||||
"size",
|
||||
"colors",
|
||||
"pngType",
|
||||
];
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $res)
|
||||
&& array_key_exists($key, $this->imageJSON)
|
||||
) {
|
||||
assertEquals(
|
||||
$res[$key],
|
||||
$this->imageJSON[$key]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @Then Compares to image :arg1
|
||||
*/
|
||||
public function comparesToImage($arg1)
|
||||
{
|
||||
$base = __DIR__ . "/../img";
|
||||
$res = file_get_contents("$base/$arg1");
|
||||
assertNotEquals(false, $res);
|
||||
|
||||
assertEquals($this->imageString, $res);
|
||||
|
||||
$this->compareImageJsonToHeaders();
|
||||
$this->compareImageJsonToSavedJson("$base/$arg1");
|
||||
}
|
||||
}
|
32
features/bootstrap/assert.php
Normal file
32
features/bootstrap/assert.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Assert functions.
|
||||
*/
|
||||
function assertNotEquals($expected, $actual)
|
||||
{
|
||||
if (!($expected !== $actual)) {
|
||||
throw new Exception("Failed asserting that '$expected' is not equal to '$actual'.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
function assertEquals($expected, $actual)
|
||||
{
|
||||
if (!($expected === $actual)) {
|
||||
throw new Exception("Failed asserting that '$expected' is equal to '$actual'.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check that $needle is an element of $haystack.
|
||||
*/
|
||||
|
||||
function assertContains($needle, $haystack)
|
||||
{
|
||||
if (!in_array($needle, $haystack)) {
|
||||
throw new Exception("Failed asserting that '$needle' is not in haystack.");
|
||||
}
|
||||
}
|
8
features/dummy.feature
Normal file
8
features/dummy.feature
Normal file
@@ -0,0 +1,8 @@
|
||||
Feature: dummy
|
||||
Display an dummy image without using an existing image on file.
|
||||
|
||||
Scenario: Set source to be dummy
|
||||
Given Set src "dummy"
|
||||
When Get image
|
||||
Then Returns status code "200"
|
||||
And Compares to image "dummy"
|
BIN
features/img/dummy
Normal file
BIN
features/img/dummy
Normal file
Binary file not shown.
After Width: | Height: | Size: 334 B |
19
features/img/dummy.json
Normal file
19
features/img/dummy.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"src": "dummy_100_100_q60_co-1",
|
||||
"srcGmdate": "Fri, 03 Jun 2016 07:38:56",
|
||||
"cache": "_._dummy_100_100_q60_co-1_q60_co-1",
|
||||
"cacheGmdate": "Fri, 03 Jun 2016 07:38:56",
|
||||
"filename": "_._dummy_100_100_q60_co-1_q60_co-1",
|
||||
"mimeType": "image/png",
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"aspectRatio": 1,
|
||||
"size": 334,
|
||||
"colors": 1,
|
||||
"includedFiles": 6,
|
||||
"memoryPeek": "0.341 MB",
|
||||
"memoryCurrent": "0.316 MB",
|
||||
"memoryLimit": "128M",
|
||||
"loadTime": "0.01s",
|
||||
"pngType": "PNG is type 6, RGB with alpha channel (PNG 32-bit)"
|
||||
}
|
BIN
features/img/test_100x100.png
Normal file
BIN
features/img/test_100x100.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 392 B |
19
features/img/test_100x100.png.json
Normal file
19
features/img/test_100x100.png.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"src": "test_100x100.png",
|
||||
"srcGmdate": "Fri, 03 Jun 2016 08:12:39",
|
||||
"cache": "_._test_100x100.png_q60_co-1",
|
||||
"cacheGmdate": "Fri, 03 Jun 2016 08:19:37",
|
||||
"filename": "_._test_100x100.png_q60_co-1",
|
||||
"mimeType": "image/png",
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"aspectRatio": 1,
|
||||
"size": 392,
|
||||
"colors": 6,
|
||||
"includedFiles": 6,
|
||||
"memoryPeek": "0.339 MB",
|
||||
"memoryCurrent": "0.316 MB",
|
||||
"memoryLimit": "128M",
|
||||
"loadTime": "0.012s",
|
||||
"pngType": "PNG is type 6, RGB with alpha channel (PNG 32-bit)"
|
||||
}
|
13
features/src.feature
Normal file
13
features/src.feature
Normal file
@@ -0,0 +1,13 @@
|
||||
Feature: src
|
||||
Display an image by selecting its source.
|
||||
|
||||
Scenario: Source is not a valid image name
|
||||
Given Set src "NO_IMAGE"
|
||||
When Get headers for image
|
||||
Then Returns status code "404"
|
||||
|
||||
Scenario: Get only source image
|
||||
Given Set src "test_100x100.png"
|
||||
When Get image
|
||||
Then Returns status code "200"
|
||||
And Compares to image "test_100x100.png"
|
@@ -16,8 +16,7 @@ require_once __DIR__ . "/functions.php";
|
||||
* @return void
|
||||
*/
|
||||
spl_autoload_register(function ($class) {
|
||||
//$path = CIMAGE_SOURCE_PATH . "/{$class}.php";
|
||||
$path = __DIR__ . "/{$class}.php";
|
||||
$path = __DIR__ . "/src/CImage/{$class}.php";
|
||||
if (is_file($path)) {
|
||||
require($path);
|
||||
}
|
22
phpunit.xml
22
phpunit.xml
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpunit
|
||||
bootstrap="test/config.php">
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="all">
|
||||
<directory>test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-html" target="coverage" charset="UTF-8" highlight="true" lowUpperBound="35" highLowerBound="70" />
|
||||
<log type="coverage-clover" target="coverage.clover" />
|
||||
</logging>
|
||||
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<file>*.php</file>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
</phpunit>
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Create an ASCII version of an image.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Deal with the cache directory and cached items.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Enable a fast track cache with a json representation of the image delivery.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
@@ -223,8 +226,8 @@ class CImage
|
||||
/**
|
||||
* Path to command to optimize jpeg images, for example jpegtran or null.
|
||||
*/
|
||||
private $jpegOptimize;
|
||||
private $jpegOptimizeCmd;
|
||||
private $jpegOptimize;
|
||||
private $jpegOptimizeCmd;
|
||||
|
||||
|
||||
|
||||
@@ -354,6 +357,7 @@ class CImage
|
||||
/**
|
||||
* Used with option area to set which parts of the image to use.
|
||||
*/
|
||||
private $area;
|
||||
private $offset;
|
||||
|
||||
|
||||
@@ -428,10 +432,15 @@ class CImage
|
||||
*/
|
||||
const RESIZE = 1;
|
||||
const RESAMPLE = 2;
|
||||
private $copyStrategy = NULL;
|
||||
private $copyStrategy = null;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Class for image resizer.
|
||||
*/
|
||||
private $imageResizer = null;
|
||||
|
||||
/**
|
||||
* Properties, the class is mutable and the method setOptions()
|
||||
* decides (partly) what properties are created.
|
||||
@@ -463,10 +472,12 @@ class CImage
|
||||
{
|
||||
$this->setSource($imageSrc, $imageFolder);
|
||||
$this->setTarget($saveFolder, $saveName);
|
||||
$this->imageResizer = new CImageResizer(array($this, 'log'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Inject object and use it, must be available as member.
|
||||
*
|
||||
@@ -981,9 +992,11 @@ class CImage
|
||||
if (!$this->fileType) {
|
||||
throw new Exception("Loading image details, the file doesn't seem to be a valid image.");
|
||||
}
|
||||
|
||||
$this->imageResizer->setSource($this->width, $this->height);
|
||||
|
||||
if ($this->verbose) {
|
||||
$this->log("Loading image details for: {$file}");
|
||||
$this->log("#Loading image details for: {$file}");
|
||||
$this->log(" Image width x height (type): {$this->width} x {$this->height} ({$this->fileType}).");
|
||||
$this->log(" Image filesize: " . filesize($file) . " bytes.");
|
||||
$this->log(" Image mimetype: " . $this->getMimeType());
|
||||
@@ -1012,74 +1025,18 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Init new width and height and do some sanity checks on constraints, before any
|
||||
* processing can be done.
|
||||
* Init new width and height and do some sanity checks on constraints,
|
||||
* before anyprocessing can be done.
|
||||
*
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function initDimensions()
|
||||
{
|
||||
$this->log("Init dimension (before) newWidth x newHeight is {$this->newWidth} x {$this->newHeight}.");
|
||||
|
||||
// width as %
|
||||
if ($this->newWidth[strlen($this->newWidth)-1] == '%') {
|
||||
$this->newWidth = $this->width * substr($this->newWidth, 0, -1) / 100;
|
||||
$this->log("Setting new width based on % to {$this->newWidth}");
|
||||
}
|
||||
|
||||
// height as %
|
||||
if ($this->newHeight[strlen($this->newHeight)-1] == '%') {
|
||||
$this->newHeight = $this->height * substr($this->newHeight, 0, -1) / 100;
|
||||
$this->log("Setting new height based on % to {$this->newHeight}");
|
||||
}
|
||||
|
||||
is_null($this->aspectRatio) or is_numeric($this->aspectRatio) or $this->raiseError('Aspect ratio out of range');
|
||||
|
||||
// width & height from aspect ratio
|
||||
if ($this->aspectRatio && is_null($this->newWidth) && is_null($this->newHeight)) {
|
||||
if ($this->aspectRatio >= 1) {
|
||||
$this->newWidth = $this->width;
|
||||
$this->newHeight = $this->width / $this->aspectRatio;
|
||||
$this->log("Setting new width & height based on width & aspect ratio (>=1) to (w x h) {$this->newWidth} x {$this->newHeight}");
|
||||
|
||||
} else {
|
||||
$this->newHeight = $this->height;
|
||||
$this->newWidth = $this->height * $this->aspectRatio;
|
||||
$this->log("Setting new width & height based on width & aspect ratio (<1) to (w x h) {$this->newWidth} x {$this->newHeight}");
|
||||
}
|
||||
|
||||
} elseif ($this->aspectRatio && is_null($this->newWidth)) {
|
||||
$this->newWidth = $this->newHeight * $this->aspectRatio;
|
||||
$this->log("Setting new width based on aspect ratio to {$this->newWidth}");
|
||||
|
||||
} elseif ($this->aspectRatio && is_null($this->newHeight)) {
|
||||
$this->newHeight = $this->newWidth / $this->aspectRatio;
|
||||
$this->log("Setting new height based on aspect ratio to {$this->newHeight}");
|
||||
}
|
||||
|
||||
// Change width & height based on dpr
|
||||
if ($this->dpr != 1) {
|
||||
if (!is_null($this->newWidth)) {
|
||||
$this->newWidth = round($this->newWidth * $this->dpr);
|
||||
$this->log("Setting new width based on dpr={$this->dpr} - w={$this->newWidth}");
|
||||
}
|
||||
if (!is_null($this->newHeight)) {
|
||||
$this->newHeight = round($this->newHeight * $this->dpr);
|
||||
$this->log("Setting new height based on dpr={$this->dpr} - h={$this->newHeight}");
|
||||
}
|
||||
}
|
||||
|
||||
// Check values to be within domain
|
||||
is_null($this->newWidth)
|
||||
or is_numeric($this->newWidth)
|
||||
or $this->raiseError('Width not numeric');
|
||||
|
||||
is_null($this->newHeight)
|
||||
or is_numeric($this->newHeight)
|
||||
or $this->raiseError('Height not numeric');
|
||||
|
||||
$this->log("Init dimension (after) newWidth x newHeight is {$this->newWidth} x {$this->newHeight}.");
|
||||
$this->imageResizer->setBaseWidthHeight($this->newWidth, $this->newHeight)
|
||||
->setBaseAspecRatio($this->aspectRatio)
|
||||
->setBaseDevicePixelRate($this->dpr)
|
||||
->prepareTargetDimensions();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1093,6 +1050,31 @@ class CImage
|
||||
*/
|
||||
public function calculateNewWidthAndHeight()
|
||||
{
|
||||
$imres = $this->imageResizer;
|
||||
$strategy = null;
|
||||
|
||||
$strategy = $imres::KEEP_RATIO;
|
||||
|
||||
if ($this->keepRatio == false) {
|
||||
$strategy = $imres::STRETCH;
|
||||
}
|
||||
|
||||
if ($this->cropToFit == true) {
|
||||
$strategy = $imres::CROP_TO_FIT;
|
||||
}
|
||||
|
||||
if ($this->fillToFit == true) {
|
||||
$strategy = $imres::FILL_TO_FIT;
|
||||
}
|
||||
|
||||
$imres->setResizeStrategy($strategy)
|
||||
->allowUpscale($this->upscale)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
//$this->newWidth = $imres->getTargetWidth();
|
||||
//$this->newHeight = $imres->getTargetHeight();
|
||||
|
||||
/*
|
||||
// Crop, use cropped width and height as base for calulations
|
||||
$this->log("Calculate new width and height.");
|
||||
$this->log("Original width x height is {$this->width} x {$this->height}.");
|
||||
@@ -1220,18 +1202,12 @@ class CImage
|
||||
$this->newHeight = round(isset($this->newHeight) ? $this->newHeight : $this->crop['height']);
|
||||
}
|
||||
|
||||
// Fill to fit, ensure to set new width and height
|
||||
/*if ($this->fillToFit) {
|
||||
$this->log("FillToFit.");
|
||||
$this->newWidth = round(isset($this->newWidth) ? $this->newWidth : $this->crop['width']);
|
||||
$this->newHeight = round(isset($this->newHeight) ? $this->newHeight : $this->crop['height']);
|
||||
}*/
|
||||
|
||||
// No new height or width is set, use existing measures.
|
||||
$this->newWidth = round(isset($this->newWidth) ? $this->newWidth : $this->width);
|
||||
$this->newHeight = round(isset($this->newHeight) ? $this->newHeight : $this->height);
|
||||
$this->log("Calculated new width x height as {$this->newWidth} x {$this->newHeight}.");
|
||||
|
||||
*/
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1244,7 +1220,10 @@ class CImage
|
||||
*/
|
||||
public function reCalculateDimensions()
|
||||
{
|
||||
$this->log("Re-calculate image dimensions, newWidth x newHeigh was: " . $this->newWidth . " x " . $this->newHeight);
|
||||
$this->log("Re-calculate image dimensions, newWidth x newHeigh was: "
|
||||
. $this->newWidth
|
||||
. " x "
|
||||
. $this->newHeight);
|
||||
|
||||
$this->newWidth = $this->newWidthOrig;
|
||||
$this->newHeight = $this->newHeightOrig;
|
||||
@@ -1365,6 +1344,7 @@ class CImage
|
||||
&& !$this->autoRotate
|
||||
&& !$this->bgColor
|
||||
&& ($this->upscale === self::UPSCALE_DEFAULT)
|
||||
&& !$this->lossy
|
||||
) {
|
||||
$this->log("Using original image.");
|
||||
$this->output($this->pathToImage);
|
||||
@@ -1390,6 +1370,7 @@ class CImage
|
||||
$filename = basename($this->pathToImage);
|
||||
$cropToFit = $this->cropToFit ? '_cf' : null;
|
||||
$fillToFit = $this->fillToFit ? '_ff' : null;
|
||||
$stretch = $this->keepRatio === false ? '_st' : null;
|
||||
$crop_x = $this->crop_x ? "_x{$this->crop_x}" : null;
|
||||
$crop_y = $this->crop_y ? "_y{$this->crop_y}" : null;
|
||||
$scale = $this->scale ? "_s{$this->scale}" : null;
|
||||
@@ -1398,6 +1379,7 @@ class CImage
|
||||
$compress = $this->compress ? "_co{$this->compress}" : null;
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -1457,14 +1439,14 @@ class CImage
|
||||
$subdir = ($subdir == '.') ? '_.' : $subdir;
|
||||
$subdir .= '_';
|
||||
}
|
||||
|
||||
|
||||
$file = $prefix . $subdir . $filename . $width . $height
|
||||
. $offset . $crop . $cropToFit . $fillToFit
|
||||
. $offset . $crop . $cropToFit . $fillToFit . $stretch
|
||||
. $crop_x . $crop_y . $upscale
|
||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette
|
||||
. $optimize . $compress
|
||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
|
||||
. $convolve . $copyStrat . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -1507,8 +1489,7 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Load image from disk. Try to load image without verbose error message,
|
||||
* if fail, load again and display error messages.
|
||||
* Load image from disk.
|
||||
*
|
||||
* @param string $src of image.
|
||||
* @param string $dir as base directory where images are.
|
||||
@@ -1608,7 +1589,6 @@ class CImage
|
||||
}
|
||||
|
||||
switch ($pngType) {
|
||||
|
||||
case self::PNG_GREYSCALE:
|
||||
$text = "PNG is type 0, Greyscale$transparent";
|
||||
break;
|
||||
@@ -1714,11 +1694,11 @@ class CImage
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCopyResizeStrategy($strategy)
|
||||
{
|
||||
$this->copyStrategy = $strategy;
|
||||
return $this;
|
||||
}
|
||||
public function setCopyResizeStrategy($strategy)
|
||||
{
|
||||
$this->copyStrategy = $strategy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1729,7 +1709,7 @@ class CImage
|
||||
*/
|
||||
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) {
|
||||
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 {
|
||||
@@ -1747,13 +1727,35 @@ class CImage
|
||||
*/
|
||||
public function resize()
|
||||
{
|
||||
$res = $this->imageResizer;
|
||||
|
||||
$this->log("### Starting to Resize()");
|
||||
$this->log("Upscale = '$this->upscale'");
|
||||
$this->log(" Upscale = '$this->upscale'");
|
||||
|
||||
$sw = $res->getSourceWidth();
|
||||
$sh = $res->getSourceHeight();
|
||||
$tw = $res->getTargetWidth();
|
||||
$th = $res->getTargetHeight();
|
||||
$cx = $res->getCropX();
|
||||
$cy = $res->getCropY();
|
||||
$cw = $res->getCropWidth();
|
||||
$ch = $res->getCropHeight();
|
||||
$dx = $res->getDestinationX();
|
||||
$dy = $res->getDestinationY();
|
||||
$dw = $res->getDestinationWidth();
|
||||
$dh = $res->getDestinationHeight();
|
||||
|
||||
$img = $this->CreateImageKeepTransparency($tw, $th);
|
||||
$this->imageCopyResampled($img, $this->image, $dx, $dy, $cx, $cy, $dw, $dh, $cw, $ch);
|
||||
$this->image = $img;
|
||||
$this->width = $tw;
|
||||
$this->height = $th;
|
||||
|
||||
return $this;
|
||||
|
||||
|
||||
// Only use a specified area of the image, $this->offset is defining the area to use
|
||||
if (isset($this->offset)) {
|
||||
|
||||
$this->log("Offset for area to use, cropping it width={$this->offset['width']}, height={$this->offset['height']}, start_x={$this->offset['left']}, start_y={$this->offset['top']}");
|
||||
$img = $this->CreateImageKeepTransparency($this->offset['width'], $this->offset['height']);
|
||||
imagecopy($img, $this->image, 0, 0, $this->offset['left'], $this->offset['top'], $this->offset['width'], $this->offset['height']);
|
||||
@@ -1763,7 +1765,6 @@ class CImage
|
||||
}
|
||||
|
||||
if ($this->crop) {
|
||||
|
||||
// Do as crop, take only part of image
|
||||
$this->log("Cropping area width={$this->crop['width']}, height={$this->crop['height']}, start_x={$this->crop['start_x']}, start_y={$this->crop['start_y']}");
|
||||
$img = $this->CreateImageKeepTransparency($this->crop['width'], $this->crop['height']);
|
||||
@@ -1780,11 +1781,10 @@ class CImage
|
||||
}
|
||||
|
||||
if ($this->cropToFit) {
|
||||
|
||||
// Resize by crop to fit
|
||||
$this->log("Resizing using strategy - Crop to fit");
|
||||
|
||||
if (!$this->upscale
|
||||
if (!$this->upscale
|
||||
&& ($this->width < $this->newWidth || $this->height < $this->newHeight)) {
|
||||
$this->log("Resizing - smaller image, do not upscale.");
|
||||
|
||||
@@ -1820,20 +1820,28 @@ class CImage
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, $cropX, $cropY, $this->width, $this->height);
|
||||
} else {
|
||||
$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
||||
$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
|
||||
$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
|
||||
$cropX = $imgres->getCropX();
|
||||
$cropY = $imgres->getCropY();
|
||||
$cropWidth = $imgres->getCropWidth();
|
||||
$cropHeight = $imgres->getCropHeight();
|
||||
$this->log(" Crop from $cropX x $cropY by $cropWidth x $cropHeight.");
|
||||
|
||||
|
||||
//$cropX = round(($this->cropWidth/2) - ($this->newWidth/2));
|
||||
//$cropY = round(($this->cropHeight/2) - ($this->newHeight/2));
|
||||
|
||||
//$imgPreCrop = $this->CreateImageKeepTransparency($this->cropWidth, $this->cropHeight);
|
||||
$imgPreCrop = $this->CreateImageKeepTransparency($cropWidth, $cropHeight);
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
$this->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);
|
||||
$this->imageCopyResampled($imgPreCrop, $this->image, 0, 0, 0, 0, $cropWidth, $cropHeight, $this->width, $this->height);
|
||||
imagecopy($imageResized, $imgPreCrop, 0, 0, $cropX, $cropY, $this->newWidth, $this->newHeight);
|
||||
}
|
||||
|
||||
$this->image = $imageResized;
|
||||
$this->width = $this->newWidth;
|
||||
$this->height = $this->newHeight;
|
||||
|
||||
} elseif ($this->fillToFit) {
|
||||
|
||||
// Resize by fill to fit
|
||||
$this->log("Resizing using strategy - Fill to fit");
|
||||
|
||||
@@ -1853,13 +1861,11 @@ class CImage
|
||||
if (!$this->upscale
|
||||
&& ($this->width < $this->newWidth && $this->height < $this->newHeight)
|
||||
) {
|
||||
|
||||
$this->log("Resizing - smaller image, do not upscale.");
|
||||
$posX = round(($this->newWidth - $this->width) / 2);
|
||||
$posY = round(($this->newHeight - $this->height) / 2);
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
imagecopy($imageResized, $this->image, $posX, $posY, 0, 0, $this->width, $this->height);
|
||||
|
||||
} else {
|
||||
$imgPreFill = $this->CreateImageKeepTransparency($this->fillWidth, $this->fillHeight);
|
||||
$imageResized = $this->CreateImageKeepTransparency($this->newWidth, $this->newHeight);
|
||||
@@ -1870,9 +1876,7 @@ class CImage
|
||||
$this->image = $imageResized;
|
||||
$this->width = $this->newWidth;
|
||||
$this->height = $this->newHeight;
|
||||
|
||||
} elseif (!($this->newWidth == $this->width && $this->newHeight == $this->height)) {
|
||||
|
||||
// Resize it
|
||||
$this->log("Resizing, new height and/or width");
|
||||
|
||||
@@ -1937,12 +1941,10 @@ class CImage
|
||||
|
||||
// Apply filters
|
||||
if (isset($this->filters) && is_array($this->filters)) {
|
||||
|
||||
foreach ($this->filters as $filter) {
|
||||
$this->log("Applying filter {$filter['type']}.");
|
||||
|
||||
switch ($filter['argc']) {
|
||||
|
||||
case 0:
|
||||
imagefilter($this->image, $filter['type']);
|
||||
break;
|
||||
@@ -2287,7 +2289,6 @@ class CImage
|
||||
$img = isset($img) ? $img : $this->image;
|
||||
|
||||
if ($this->bgColorDefault) {
|
||||
|
||||
$red = $this->bgColorDefault['red'];
|
||||
$green = $this->bgColorDefault['green'];
|
||||
$blue = $this->bgColorDefault['blue'];
|
||||
@@ -2300,7 +2301,6 @@ class CImage
|
||||
}
|
||||
|
||||
return $color;
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -2328,16 +2328,13 @@ class CImage
|
||||
: -1;
|
||||
|
||||
if ($index != -1) {
|
||||
|
||||
imagealphablending($img, true);
|
||||
$transparent = imagecolorsforindex($this->image, $index);
|
||||
$color = imagecolorallocatealpha($img, $transparent['red'], $transparent['green'], $transparent['blue'], $transparent['alpha']);
|
||||
imagefill($img, 0, 0, $color);
|
||||
$index = imagecolortransparent($img, $color);
|
||||
$this->Log("Detected transparent color = " . implode(", ", $transparent) . " at index = $index");
|
||||
|
||||
} elseif ($this->bgColorDefault) {
|
||||
|
||||
$color = $this->getBackgroundColor($img);
|
||||
imagefill($img, 0, 0, $color);
|
||||
$this->Log("Filling image with background color.");
|
||||
@@ -2363,7 +2360,7 @@ class CImage
|
||||
$this->jpegOptimizeCmd = null;
|
||||
}
|
||||
|
||||
if (array_key_exists("png_lossy", $options)
|
||||
if (array_key_exists("png_lossy", $options)
|
||||
&& $options['png_lossy'] !== false) {
|
||||
$this->pngLossy = $options['png_lossy'];
|
||||
$this->pngLossyCmd = $options['png_lossy_cmd'];
|
||||
@@ -2432,8 +2429,7 @@ class CImage
|
||||
|
||||
$type = $this->getTargetImageExtension();
|
||||
$this->Log("Saving image as " . $type);
|
||||
switch($type) {
|
||||
|
||||
switch ($type) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
$this->Log("Saving image as JPEG to cache using quality = {$this->quality}.");
|
||||
@@ -2553,7 +2549,7 @@ class CImage
|
||||
$this->log("# Converting image to sRGB colorspace.");
|
||||
}
|
||||
|
||||
if (!class_exists("Imagick")) {
|
||||
if (!class_exists("\Imagick")) {
|
||||
$this->log(" Ignoring since Imagemagick is not installed.");
|
||||
return false;
|
||||
}
|
||||
@@ -2574,10 +2570,10 @@ class CImage
|
||||
}
|
||||
}
|
||||
|
||||
// Only covert if cachedir is writable
|
||||
// Only convert if cachedir is writable
|
||||
if (is_writable($this->saveFolder)) {
|
||||
// Load file and check if conversion is needed
|
||||
$image = new Imagick($this->pathToImage);
|
||||
$image = new \Imagick($this->pathToImage);
|
||||
$colorspace = $image->getImageColorspace();
|
||||
$this->log(" Current colorspace: " . $colorspace);
|
||||
|
||||
@@ -2585,13 +2581,13 @@ class CImage
|
||||
$hasICCProfile = (array_search('icc', $profiles) !== false);
|
||||
$this->log(" Has ICC color profile: " . ($hasICCProfile ? "YES" : "NO"));
|
||||
|
||||
if ($colorspace != Imagick::COLORSPACE_SRGB || $hasICCProfile) {
|
||||
if ($colorspace != \Imagick::COLORSPACE_SRGB || $hasICCProfile) {
|
||||
$this->log(" Converting to sRGB.");
|
||||
|
||||
$sRGBicc = file_get_contents($iccFile);
|
||||
$image->profileImage('icc', $sRGBicc);
|
||||
|
||||
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
|
||||
$image->transformImageColorspace(\Imagick::COLORSPACE_SRGB);
|
||||
$image->writeImage($this->cacheFileName);
|
||||
return $this->cacheFileName;
|
||||
}
|
||||
@@ -2705,7 +2701,6 @@ class CImage
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
|
||||
&& strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
|
||||
|
||||
if ($this->verbose) {
|
||||
$this->log("304 not modified");
|
||||
$this->verboseOutput();
|
||||
@@ -2716,9 +2711,7 @@ class CImage
|
||||
if (CIMAGE_DEBUG) {
|
||||
trace(__CLASS__ . " 304");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$this->loadImageDetails($file);
|
||||
$mime = $this->getMimeType();
|
||||
$size = filesize($file);
|
838
src/CImage/CImageResizer.php
Normal file
838
src/CImage/CImageResizer.php
Normal file
@@ -0,0 +1,838 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Resize and crop images.
|
||||
*
|
||||
* @author Mikael Roos mos@dbwebb.se
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*/
|
||||
class CImageResizer
|
||||
{
|
||||
/**
|
||||
* Log function.
|
||||
*/
|
||||
private $log;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Source image dimensions, calculated from loaded image.
|
||||
*/
|
||||
private $srcWidth;
|
||||
private $srcHeight;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set as expected target image/canvas dimensions.
|
||||
*/
|
||||
private $targetWidth;
|
||||
private $targetHeight;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Where should the image go on the canvas.
|
||||
*/
|
||||
private $destinationX;
|
||||
private $destinationY;
|
||||
private $destinationWidth;
|
||||
private $destinationHeight;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Which parts to crop from the source.
|
||||
*/
|
||||
private $cropX;
|
||||
private $cropY;
|
||||
private $cropWidth;
|
||||
private $cropHeight;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change target height & width when different dpr, dpr 2 means double
|
||||
* image dimensions.
|
||||
*/
|
||||
private $dpr = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set aspect ratio for the target image.
|
||||
*/
|
||||
private $aspectRatio;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Array with details on how to crop.
|
||||
* Array contains xxxxxx
|
||||
*/
|
||||
public $crop;
|
||||
public $cropOrig; // Save original value?
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Area to use for target image, crop out parts not in area.
|
||||
* Array with top, right, bottom, left percentage values to crop out.
|
||||
*/
|
||||
private $area;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pixel offset in source image to decide which part of image is used.
|
||||
* Array with top, right, bottom, left percentage values to crop out.
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize strategy, image should keep its original ratio.
|
||||
*/
|
||||
const KEEP_RATIO = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize strategy, image should crop and fill area.
|
||||
*/
|
||||
const CROP_TO_FIT = 2;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize strategy, image should fit in area and fill remains.
|
||||
*/
|
||||
const FILL_TO_FIT = 3;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize strategy, image should stretch to fit in area.
|
||||
*/
|
||||
const STRETCH = 4;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The currently selected resize strategy.
|
||||
*/
|
||||
private $resizeStrategy = self::KEEP_RATIO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow upscale of smaller images by default, set to false to disallow.
|
||||
*/
|
||||
private $upscale = true;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor, set log function to use for verbose logging or null
|
||||
* to disable logging.
|
||||
*
|
||||
* @param callable $log function to call for logging.
|
||||
*/
|
||||
public function __construct($log = null)
|
||||
{
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Log string using logger.
|
||||
*
|
||||
* @param string $str to log.
|
||||
*/
|
||||
public function log($str)
|
||||
{
|
||||
if ($this->log) {
|
||||
call_user_func($this->log, $str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set source dimensions.
|
||||
*
|
||||
* @param integer $width of source image.
|
||||
* @param integer $height of source image.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSource($width, $height)
|
||||
{
|
||||
$this->srcWidth = $width;
|
||||
$this->srcHeight = $height;
|
||||
$this->log("# Source image dimension: {$this->srcWidth}x{$this->srcHeight}.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get resize strategy as string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getResizeStrategyAsString()
|
||||
{
|
||||
switch ($this->resizeStrategy) {
|
||||
case self::KEEP_RATIO:
|
||||
return "KEEP_RATIO";
|
||||
break;
|
||||
|
||||
case self::CROP_TO_FIT:
|
||||
return "CROP_TO_FIT";
|
||||
break;
|
||||
|
||||
case self::FILL_TO_FIT:
|
||||
return "FILL_TO_FIT";
|
||||
break;
|
||||
|
||||
case self::STRETCH:
|
||||
return "STRETCH";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set resize strategy as KEEP_RATIO, CROP_TO_FIT or FILL_TO_FIT.
|
||||
*
|
||||
* @param integer $strategy
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setResizeStrategy($strategy)
|
||||
{
|
||||
$this->resizeStrategy = $strategy;
|
||||
$this->log("# Resize strategy is " . $this->getResizeStrategyAsString());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allow or disallow upscale smaller images.
|
||||
*
|
||||
* @param boolean $upscale
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function allowUpscale($upscale)
|
||||
{
|
||||
$this->upscale = $upscale;
|
||||
$this->log("# Allow upscale is $this->upscale.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if a value is upscaled or not by compare $current to $orig,
|
||||
* if $current is larger than $orig then check if upscaled is allowed.
|
||||
*
|
||||
* @param float &$current value to check and change.
|
||||
* @param float $orig value to check against.
|
||||
*
|
||||
* @return boolean true if upscaled changed values, else false.
|
||||
*/
|
||||
public function respectUpscale(&$current, $orig)
|
||||
{
|
||||
if (!$this->upscale && $current > $orig) {
|
||||
$this->log("# Disallowed upscale to $current ($orig)");
|
||||
$current = $orig;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set base for requested width and height.
|
||||
*
|
||||
* @param numeric|null $width as requested target width
|
||||
* @param numeric|null $height as requested target height
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseWidthHeight($width = null, $height = null)
|
||||
{
|
||||
$this->log("# Set base for width and height.");
|
||||
|
||||
$this->targetWidth = $width;
|
||||
$this->targetHeight = $height;
|
||||
|
||||
// Width specified as %
|
||||
if ($this->targetWidth[strlen($this->targetWidth)-1] == '%') {
|
||||
$this->targetWidth = $this->srcWidth * substr($this->targetWidth, 0, -1) / 100;
|
||||
$this->log(" Setting new width based on $width to {$this->targetWidth}.");
|
||||
}
|
||||
|
||||
// Height specified as %
|
||||
if ($this->targetHeight[strlen($this->targetHeight)-1] == '%') {
|
||||
$this->targetHeight = $this->srcHeight * substr($this->targetHeight, 0, -1) / 100;
|
||||
$this->log(" Setting new height based on $height to {$this->targetHeight}.");
|
||||
}
|
||||
|
||||
if (!(is_null($this->targetWidth) || is_numeric($this->targetWidth))) {
|
||||
throw new Exception('Width not numeric');
|
||||
}
|
||||
|
||||
if (!(is_null($this->targetHeight) || is_numeric($this->targetHeight))) {
|
||||
throw new Exception('Height not numeric');
|
||||
}
|
||||
|
||||
$this->log(" Requested target dimension as: {$this->targetWidth}x{$this->targetHeight}.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set base for requested aspect ratio.
|
||||
*
|
||||
* @param float|null $aspectRatio as requested aspect ratio
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseAspecRatio($aspectRatio = null)
|
||||
{
|
||||
$this->log("# Set base for aspect ratio.");
|
||||
|
||||
$this->aspectRatio = $aspectRatio;
|
||||
|
||||
if (!(is_null($this->aspectRatio) || is_numeric($this->aspectRatio))) {
|
||||
throw new Exception("Aspect ratio out of range");
|
||||
}
|
||||
|
||||
$this->log(" Requested aspectRatio={$this->aspectRatio}.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set base for requested device pixel ratio.
|
||||
*
|
||||
* @param float $dpr as requested density pixel rate
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseDevicePixelRate($dpr = null)
|
||||
{
|
||||
$this->log("# Set base for device pixel rate.");
|
||||
|
||||
$this->dpr = $dpr;
|
||||
|
||||
if (!(is_null($dpr) || (is_numeric($this->dpr) && $this->dpr > 0))) {
|
||||
throw new Exception("Device pixel rate out of range");
|
||||
}
|
||||
|
||||
$this->log(" Requested dpr={$this->dpr}.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculate target width and height by considering the selected
|
||||
* aspect ratio.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function prepareByConsiderAspectRatio()
|
||||
{
|
||||
$this->log(" Prepare by aspect ratio {$this->aspectRatio}.");
|
||||
|
||||
if (is_null($this->aspectRatio)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Both null, use source as base for target
|
||||
if (is_null($this->targetWidth) && is_null($this->targetHeight)) {
|
||||
$this->targetWidth = ($this->aspectRatio >= 1)
|
||||
? $this->srcWidth
|
||||
: null;
|
||||
|
||||
$this->targetHeight = ($this->aspectRatio >= 1)
|
||||
? null
|
||||
: $this->srcHeight;
|
||||
|
||||
$this->log(" Using source as base {$this->targetWidth}x{$this->targetHeight}");
|
||||
}
|
||||
|
||||
// Both or either set, calculate the other
|
||||
if (isset($this->targetWidth) && isset($this->targetHeight)) {
|
||||
$this->targetWidth = ($this->aspectRatio >= 1)
|
||||
? $this->targetWidth
|
||||
: $this->targetHeight * $this->aspectRatio;
|
||||
|
||||
$this->targetHeight = ($this->aspectRatio >= 1)
|
||||
? $this->targetWidth / $this->aspectRatio
|
||||
: $this->targetHeight;
|
||||
|
||||
$this->log(" New target width height {$this->targetWidth}x{$this->targetHeight}");
|
||||
} elseif (isset($this->targetWidth)) {
|
||||
$this->targetHeight = $this->targetWidth / $this->aspectRatio;
|
||||
$this->log(" New target height x{$this->targetHeight}");
|
||||
} elseif (isset($this->targetHeight)) {
|
||||
$this->targetWidth = $this->targetHeight * $this->aspectRatio;
|
||||
$this->log(" New target width {$this->targetWidth}x");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculate target width and height by considering the selected
|
||||
* dpr.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function prepareByConsiderDpr()
|
||||
{
|
||||
$this->log(" Prepare by dpr={$this->dpr}.");
|
||||
|
||||
if (is_null($this->dpr)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// If both not set, use source as base
|
||||
if (is_null($this->targetWidth) && is_null($this->targetHeight)) {
|
||||
$this->targetWidth = $this->srcWidth;
|
||||
$this->targetHeight = $this->srcHeight;
|
||||
}
|
||||
|
||||
if (isset($this->targetWidth)) {
|
||||
$this->targetWidth = $this->targetWidth * $this->dpr;
|
||||
$this->log(" Update target width to {$this->targetWidth}.");
|
||||
}
|
||||
|
||||
if (isset($this->targetHeight)) {
|
||||
$this->targetHeight = $this->targetHeight * $this->dpr;
|
||||
$this->log(" Update target height to {$this->targetHeight}.");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculate target width and height and do sanity checks on constraints.
|
||||
* After this method the $targetWidth and $targetHeight will have
|
||||
* the expected dimensions on the target image.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function prepareTargetDimensions()
|
||||
{
|
||||
$this->log("# Prepare target dimension (before): {$this->targetWidth}x{$this->targetHeight}.");
|
||||
|
||||
$this->prepareByConsiderAspectRatio()
|
||||
->prepareByConsiderDpr();
|
||||
|
||||
$this->log(" Prepare target dimension (after): {$this->targetWidth}x{$this->targetHeight}.");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculate new width and height of image.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function calculateTargetWidthAndHeight()
|
||||
{
|
||||
$this->log("# Calculate new width and height.");
|
||||
$this->log(" Source size {$this->srcWidth}x{$this->srcHeight}.");
|
||||
$this->log(" Target dimension (before) {$this->targetWidth}x{$this->targetHeight}.");
|
||||
|
||||
// Set default values to crop area to be whole source image
|
||||
$sw = $this->srcWidth;
|
||||
$sh = $this->srcHeight;
|
||||
$ar = $sw / $sh;
|
||||
$tw = $this->targetWidth;
|
||||
$th = $this->targetHeight;
|
||||
$dx = 0;
|
||||
$dy = 0;
|
||||
$dw = null;
|
||||
$dh = null;
|
||||
$cx = 0;
|
||||
$cy = 0;
|
||||
$cw = $sw;
|
||||
$ch = $sh;
|
||||
$rs = $this->resizeStrategy;
|
||||
$both = isset($tw) && isset($th);
|
||||
$ratio = $both ? $tw / $th : null;
|
||||
|
||||
if (is_null($tw) && is_null($th)) {
|
||||
// No tw/th use sw/sh
|
||||
$tw = $sw;
|
||||
$th = $sh;
|
||||
$this->log(" New tw x th {$tw}x{$th}");
|
||||
} elseif (isset($tw) && is_null($th)) {
|
||||
// Keep aspect ratio, make th based on tw
|
||||
$this->respectUpscale($tw, $sw);
|
||||
$th = $tw / $ar;
|
||||
$this->log(" New th x{$th}");
|
||||
} elseif (is_null($tw) && isset($th)) {
|
||||
// Keep aspect ratio, make tw based on th
|
||||
$this->respectUpscale($th, $sh);
|
||||
$tw = $th * $ar;
|
||||
$this->log(" New tw {$tw}x");
|
||||
} elseif ($rs === CImageResizer::KEEP_RATIO && $both) {
|
||||
// Keep aspect ratio, make fit in box not larger than tw/th
|
||||
$this->log(" Keep ratio, ratio target=$ratio, source=$ar");
|
||||
|
||||
if ($ratio > $ar) {
|
||||
$this->respectUpscale($th, $sh);
|
||||
$tw = $th * $ar;
|
||||
$this->log(" New tw {$tw}x");
|
||||
} elseif ($ratio < $ar) {
|
||||
$this->respectUpscale($tw, $sw);
|
||||
$th = $tw / $ar;
|
||||
$this->log(" New th x{$th}");
|
||||
} else {
|
||||
$this->respectUpscale($tw, $sw);
|
||||
$this->respectUpscale($th, $sh);
|
||||
}
|
||||
} elseif ($rs === CImageResizer::STRETCH && $both) {
|
||||
// Stretch to fit, leave as is
|
||||
$this->log(" Stretch");
|
||||
|
||||
// respectUpscale
|
||||
$dw = $tw;
|
||||
$dh = $th;
|
||||
$this->respectUpscale($dw, $sw);
|
||||
$this->respectUpscale($dh, $sh);
|
||||
$dx = ($tw - $dw) / 2;
|
||||
$dy = ($th - $dh) / 2;
|
||||
|
||||
$this->log(" Destination area dx=$dx, dy=$dy, dw=$dw, dh=$dh");
|
||||
} elseif ($rs === CImageResizer::CROP_TO_FIT && $both) {
|
||||
// Crop to fit image in box
|
||||
$this->log(" Crop to fit, ratio target=$ratio, source=$ar");
|
||||
|
||||
// Respect upscale
|
||||
$dw = $tw;
|
||||
$dh = $th;
|
||||
$this->respectUpscale($dw, $sw);
|
||||
$this->respectUpscale($dh, $sh);
|
||||
$dx = ($tw - $dw) / 2;
|
||||
$dy = ($th - $dh) / 2;
|
||||
|
||||
// Manage landscape/portrait
|
||||
if ($ratio > $ar) {
|
||||
$ch = $sw / $ratio;
|
||||
$cy = ($sh - $ch) / 2;
|
||||
$this->log(" Crop by cy=$cy ch=$ch");
|
||||
} elseif ($ratio < $ar) {
|
||||
$cw = $sh * $ratio;
|
||||
$cx = ($sw - $cw) / 2;
|
||||
$this->log(" Crop by cx=$cx cw=$cw");
|
||||
}
|
||||
|
||||
// Update crop when no upscale
|
||||
if (!$this->upscale && $dx) {
|
||||
$cy = $th < $sh ? ($sh - $th) / 2 : 0;
|
||||
$ch = $dh;
|
||||
}
|
||||
if (!$this->upscale && $dy) {
|
||||
$cx = $tw < $sw ? ($sw - $tw) / 2 : 0;
|
||||
$cw = $dw;
|
||||
}
|
||||
|
||||
$this->log(" Parts cx=$cx, cy=$cy, cw=$cw, ch=$ch");
|
||||
$this->log(" Destination area dx=$dx, dy=$dy, dw=$dw, dh=$dh");
|
||||
} elseif ($rs === CImageResizer::FILL_TO_FIT && $both) {
|
||||
// Fill to fit image in box
|
||||
$this->log(" Fill to fit, ratio target=$ratio, source=$ar");
|
||||
$dw = $tw;
|
||||
$dh = $th;
|
||||
|
||||
// Manage landscape/portrait
|
||||
if ($ratio > $ar) {
|
||||
$dw = $th * $ar;
|
||||
$dh = $th;
|
||||
} elseif ($ratio < $ar) {
|
||||
$dw = $tw;
|
||||
$dh = $tw / $ar;
|
||||
}
|
||||
|
||||
$this->respectUpscale($dw, $sw);
|
||||
$this->respectUpscale($dh, $sh);
|
||||
$dx = ($tw - $dw) / 2;
|
||||
$dy = ($th - $dh) / 2;
|
||||
|
||||
$this->log(" Destination area dx=$dx, dy=$dy, dw=$dw, dh=$dh");
|
||||
}
|
||||
|
||||
// All done, sum it up
|
||||
$dw = is_null($dw) ? $tw : $dw;
|
||||
$dh = is_null($dh) ? $th : $dh;
|
||||
|
||||
$this->targetWidth = round($tw);
|
||||
$this->targetHeight = round($th);
|
||||
$this->destinationX = round($dx);
|
||||
$this->destinationY = round($dy);
|
||||
$this->destinationWidth = round($dw);
|
||||
$this->destinationHeight = round($dh);
|
||||
$this->cropX = round($cx);
|
||||
$this->cropY = round($cy);
|
||||
$this->cropWidth = round($cw);
|
||||
$this->cropHeight = round($ch);
|
||||
|
||||
$str = <<<EOD
|
||||
Target dimension (after) {$this->targetWidth}x{$this->targetHeight}.
|
||||
Crop area {$this->cropX}x{$this->cropY} by {$this->cropWidth}x{$this->cropHeight}.
|
||||
Destination area {$this->destinationX}x{$this->destinationY} by {$this->destinationWidth}x{$this->destinationHeight}.
|
||||
EOD;
|
||||
$this->log($str);
|
||||
|
||||
/*
|
||||
|
||||
// Check if there is an area to crop off
|
||||
if (isset($this->area)) {
|
||||
$this->offset['top'] = round($this->area['top'] / 100 * $this->srcHeight);
|
||||
$this->offset['right'] = round($this->area['right'] / 100 * $this->srcWidth);
|
||||
$this->offset['bottom'] = round($this->area['bottom'] / 100 * $this->srcHeight);
|
||||
$this->offset['left'] = round($this->area['left'] / 100 * $this->srcWidth);
|
||||
$this->offset['width'] = $this->srcWidth - $this->offset['left'] - $this->offset['right'];
|
||||
$this->offset['height'] = $this->srcHeight - $this->offset['top'] - $this->offset['bottom'];
|
||||
$this->srcWidth = $this->offset['width'];
|
||||
$this->srcHeight = $this->offset['height'];
|
||||
$this->log("The offset for the area to use is top {$this->area['top']}%, right {$this->area['right']}%, bottom {$this->area['bottom']}%, left {$this->area['left']}%.");
|
||||
$this->log("The offset for the area to use is top {$this->offset['top']}px, right {$this->offset['right']}px, bottom {$this->offset['bottom']}px, left {$this->offset['left']}px, width {$this->offset['width']}px, height {$this->offset['height']}px.");
|
||||
}
|
||||
|
||||
|
||||
// Check if crop is set
|
||||
if ($this->crop) {
|
||||
$width = $this->crop['width'] = $this->crop['width'] <= 0 ? $this->srcWidth + $this->crop['width'] : $this->crop['width'];
|
||||
$height = $this->crop['height'] = $this->crop['height'] <= 0 ? $this->srcHeight + $this->crop['height'] : $this->crop['height'];
|
||||
|
||||
if ($this->crop['start_x'] == 'left') {
|
||||
$this->crop['start_x'] = 0;
|
||||
} elseif ($this->crop['start_x'] == 'right') {
|
||||
$this->crop['start_x'] = $this->srcWidth - $width;
|
||||
} elseif ($this->crop['start_x'] == 'center') {
|
||||
$this->crop['start_x'] = round($this->srcWidth / 2) - round($width / 2);
|
||||
}
|
||||
|
||||
if ($this->crop['start_y'] == 'top') {
|
||||
$this->crop['start_y'] = 0;
|
||||
} elseif ($this->crop['start_y'] == 'bottom') {
|
||||
$this->crop['start_y'] = $this->srcHeight - $height;
|
||||
} elseif ($this->crop['start_y'] == 'center') {
|
||||
$this->crop['start_y'] = round($this->srcHeight / 2) - round($height / 2);
|
||||
}
|
||||
|
||||
$this->log(" Crop area is width {$width}px, height {$height}px, start_x {$this->crop['start_x']}px, start_y {$this->crop['start_y']}px.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Crop, ensure to set new width and height
|
||||
if ($this->crop) {
|
||||
$this->log(" Crop.");
|
||||
$this->targetWidth = round(isset($this->targetWidth)
|
||||
? $this->targetWidth
|
||||
: $this->crop['width']);
|
||||
$this->targetHeight = round(isset($this->targetHeight)
|
||||
? $this->targetHeight
|
||||
: $this->crop['height']);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get source width.
|
||||
*
|
||||
* @return integer as source width
|
||||
*/
|
||||
public function getSourceWidth()
|
||||
{
|
||||
return $this->srcWidth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get source height.
|
||||
*
|
||||
* @return integer as source height
|
||||
*/
|
||||
public function getSourceHeight()
|
||||
{
|
||||
return $this->srcHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get target width.
|
||||
*
|
||||
* @return integer as target width
|
||||
*/
|
||||
public function getTargetWidth()
|
||||
{
|
||||
return $this->targetWidth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get target height.
|
||||
*
|
||||
* @return integer as target height
|
||||
*/
|
||||
public function getTargetHeight()
|
||||
{
|
||||
return $this->targetHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get destination x.
|
||||
*
|
||||
* @return integer as destination x
|
||||
*/
|
||||
public function getDestinationX()
|
||||
{
|
||||
return $this->destinationX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get destination y.
|
||||
*
|
||||
* @return integer as destination y
|
||||
*/
|
||||
public function getDestinationY()
|
||||
{
|
||||
return $this->destinationY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get destination width.
|
||||
*
|
||||
* @return integer as destination width
|
||||
*/
|
||||
public function getDestinationWidth()
|
||||
{
|
||||
return $this->destinationWidth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get destination height.
|
||||
*
|
||||
* @return integer as destination height
|
||||
*/
|
||||
public function getDestinationHeight()
|
||||
{
|
||||
return $this->destinationHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get crop position x.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCropX()
|
||||
{
|
||||
return $this->cropX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get crop position y.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCropY()
|
||||
{
|
||||
return $this->cropY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get crop width.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCropWidth()
|
||||
{
|
||||
return $this->cropWidth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get crop height.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCropHeight()
|
||||
{
|
||||
return $this->cropHeight;
|
||||
}
|
||||
}
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Act as whitelist (or blacklist).
|
||||
*
|
22
src/CImage/Exception.php
Normal file
22
src/CImage/Exception.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Anax class for wrapping sessions.
|
||||
*
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* Construct.
|
||||
*
|
||||
* @param string $message the Exception message to throw.
|
||||
* @param int $code the Exception code.
|
||||
* @param Exception previous the previous exception used for the exception chaining.
|
||||
*/
|
||||
public function __construct($message = "", $code = 0, $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.16 (2016-08-09)");
|
||||
define("CIMAGE_VERSION", "v0.7.19* (2016-08-11)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
@@ -67,22 +67,6 @@ function errorPage($msg, $type = 500)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input from query string or return default value if not set.
|
||||
*
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
|
74
test/CImageResizerByAspectRatioTest.php
Normal file
74
test/CImageResizerByAspectRatioTest.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerByAspectRatioTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return array(
|
||||
|
||||
// No value set
|
||||
array(null, 100, 100, null, null, null, null),
|
||||
|
||||
// Aspect ratio 1
|
||||
array(1, 100, 100, null, null, 100, 100),
|
||||
array(1, 100, 100, null, 100, 100, 100),
|
||||
array(1, 100, 100, 100, null, 100, 100),
|
||||
array(1, 100, 100, 100, 100, 100, 100),
|
||||
|
||||
// Aspect ratio 2
|
||||
array(2, 100, 100, null, null, 100, 50),
|
||||
array(2, 100, 100, null, 100, 200, 100),
|
||||
array(2, 100, 100, 100, null, 100, 50),
|
||||
array(2, 100, 100, 100, 100, 100, 50),
|
||||
|
||||
// Aspect ratio 0.5
|
||||
array(1/2, 100, 100, null, null, 50, 100),
|
||||
array(1/2, 100, 100, null, 100, 50, 100),
|
||||
array(1/2, 100, 100, 100, null, 100, 200),
|
||||
array(1/2, 100, 100, 100, 100, 50, 100),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1(
|
||||
$aspectRatio,
|
||||
$srcWidth,
|
||||
$srcHeight,
|
||||
$targetWidth,
|
||||
$targetHeight,
|
||||
$expectedWidth,
|
||||
$expectedHeight
|
||||
) {
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
//$img = new CImageResizer('logger');
|
||||
|
||||
$img->setSource($srcWidth, $srcHeight)
|
||||
->setBaseWidthHeight($targetWidth, $targetHeight)
|
||||
->setBaseAspecRatio($aspectRatio)
|
||||
->prepareTargetDimensions();
|
||||
// ->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($expectedWidth, $img->getTargetWidth(), "Width not correct.");
|
||||
$this->assertEquals($expectedHeight, $img->getTargetHeight(), "Height not correct.");
|
||||
}
|
||||
}
|
75
test/CImageResizerByDensityPixelRatioTest.php
Normal file
75
test/CImageResizerByDensityPixelRatioTest.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerByDevicePixelRatioTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return array(
|
||||
|
||||
// No value set
|
||||
array(null, 100, 100, null, null, null, null),
|
||||
|
||||
// dpr 1
|
||||
array(1, 100, 100, null, null, 100, 100),
|
||||
array(1, 100, 100, null, 100, null, 100),
|
||||
array(1, 100, 100, 100, null, 100, null),
|
||||
array(1, 100, 100, 100, 100, 100, 100),
|
||||
|
||||
// dpr 2
|
||||
array(2, 100, 100, null, null, 200, 200),
|
||||
array(2, 100, 100, null, 200, null, 400),
|
||||
array(2, 100, 100, 200, null, 400, null),
|
||||
array(2, 100, 100, 200, 200, 400, 400),
|
||||
|
||||
// dpr 1/2
|
||||
array(1/2, 100, 100, null, null, 50, 50),
|
||||
array(1/2, 100, 100, null, 200, null, 100),
|
||||
array(1/2, 100, 100, 200, null, 100, null),
|
||||
array(1/2, 100, 100, 200, 200, 100, 100),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1(
|
||||
$dpr,
|
||||
$srcWidth,
|
||||
$srcHeight,
|
||||
$targetWidth,
|
||||
$targetHeight,
|
||||
$expectedWidth,
|
||||
$expectedHeight
|
||||
) {
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
//$img = new CImageResizer('logger');
|
||||
|
||||
$img->setSource($srcWidth, $srcHeight)
|
||||
//->setResizeStrategy($img::KEEP_RATIO)
|
||||
->setBaseWidthHeight($targetWidth, $targetHeight)
|
||||
->setBaseDevicePixelRate($dpr)
|
||||
->prepareTargetDimensions();
|
||||
//->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($expectedWidth, $img->getTargetWidth(), "Width not correct.");
|
||||
$this->assertEquals($expectedHeight, $img->getTargetHeight(), "Height not correct.");
|
||||
}
|
||||
}
|
131
test/CImageResizerStrategyCropToFitTest.php
Normal file
131
test/CImageResizerStrategyCropToFitTest.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerStrategyCropToFitTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return [
|
||||
|
||||
// Square
|
||||
[100, 100, 200, 200, 0, 0, 100, 100],
|
||||
[100, 100, 200, 100, 0, 25, 100, 50],
|
||||
[100, 100, 100, 200, 25, 0, 50, 100],
|
||||
|
||||
// Landscape
|
||||
[200, 100, 400, 200, 0, 0, 200, 100],
|
||||
[200, 100, 50, 50, 50, 0, 100, 100],
|
||||
[200, 100, 400, 100, 0, 25, 200, 50],
|
||||
[200, 100, 100, 400, round(175/2), 0, 25, 100],
|
||||
|
||||
// Portrait
|
||||
[100, 200, 50, 100, 0, 0, 100, 200],
|
||||
[100, 200, 50, 50, 0, 50, 100, 100],
|
||||
[100, 200, 200, 50, 0, round(175/2), 100, 25],
|
||||
[100, 200, 50, 200, 25, 0, 50, 200],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1($sw, $sh, $tw, $th, $cx, $cy, $cw, $ch)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::CROP_TO_FIT)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($th, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($cx, $img->getCropX(), "CropX not correct.");
|
||||
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
|
||||
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
|
||||
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages2()
|
||||
{
|
||||
return [
|
||||
|
||||
// Square
|
||||
[100,100, 200,200, 0,0,100,100, 50,50,100,100],
|
||||
[100,100, 200,100, 0,0,100,100, 50,0,100,100],
|
||||
[100,100, 100,200, 0,0,100,100, 0,50,100,100],
|
||||
|
||||
// Landscape
|
||||
[200,100, 400,200, 0,0,200,100, 100,50,200,100],
|
||||
//[200,100, 50,50, 50,0,100,100, 0,0,200,100],
|
||||
/*
|
||||
[200, 100, 400, 100, 0, 25, 200, 50],
|
||||
[200, 100, 100, 400, round(175/2), 0, 25, 100],
|
||||
|
||||
// Portrait
|
||||
[100, 200, 50, 100, 0, 0, 100, 200],
|
||||
[100, 200, 50, 50, 0, 50, 100, 100],
|
||||
[100, 200, 200, 50, 0, round(175/2), 100, 25],
|
||||
[100, 200, 50, 200, 25, 0, 50, 200],
|
||||
/* */
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize2($sw, $sh, $tw, $th, $cx, $cy, $cw, $ch, $dx, $dy, $dw, $dh)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::CROP_TO_FIT)
|
||||
->allowUpscale(false)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($th, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($cx, $img->getCropX(), "CropX not correct.");
|
||||
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
|
||||
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
|
||||
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
|
||||
|
||||
$this->assertEquals($dx, $img->getDestinationX(), "DestinationX not correct.");
|
||||
$this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct.");
|
||||
$this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct.");
|
||||
$this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct.");
|
||||
}
|
||||
}
|
119
test/CImageResizerStrategyFillToFitTest.php
Normal file
119
test/CImageResizerStrategyFillToFitTest.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerStrategyFillToFitTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return array(
|
||||
|
||||
// Square
|
||||
array(100, 100, 200, 200, 0, 0, 200, 200),
|
||||
array(100, 100, 100, 50, 25, 0, 50, 50),
|
||||
array(100, 100, 50, 100, 0, 25, 50, 50),
|
||||
|
||||
// Landscape
|
||||
array(200, 100, 400, 200, 0, 0, 400, 200),
|
||||
array(200, 100, 100, 100, 0, 25, 100, 50),
|
||||
array(200, 100, 400, 100, 100, 0, 200, 100),
|
||||
array(200, 100, 100, 400, 0, 175, 100, 50),
|
||||
|
||||
// Portrait
|
||||
array(100, 200, 200, 400, 0, 0, 200, 400),
|
||||
array(100, 200, 100, 100, 25, 0, 50, 100),
|
||||
array(100, 200, 400, 100, 175, 0, 50, 100),
|
||||
array(100, 200, 100, 400, 0, 100, 100, 200),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1($sw, $sh, $tw, $th, $dx, $dy, $dw, $dh)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::FILL_TO_FIT)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($th, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($dx, $img->getDestinationX(), "DestinationX not correct.");
|
||||
$this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct.");
|
||||
$this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct.");
|
||||
$this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages2()
|
||||
{
|
||||
return [
|
||||
|
||||
// Square
|
||||
[100, 100, 200, 200, 50, 50, 100, 100],
|
||||
[100, 100, 400, 100, 150, 0, 100, 100],
|
||||
[100, 100, 100, 400, 0, 150, 100, 100],
|
||||
[100, 100, 400, 400, 150, 150, 100, 100],
|
||||
[491, 323, 600, 400, 55, 39, 491, 323],
|
||||
|
||||
// Landscape
|
||||
|
||||
// Portrait
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize2($sw, $sh, $tw, $th, $dx, $dy, $dw, $dh)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::FILL_TO_FIT)
|
||||
->allowUpscale(false)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($th, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($dx, $img->getDestinationX(), "DestinationX not correct.");
|
||||
$this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct.");
|
||||
$this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct.");
|
||||
$this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct.");
|
||||
}
|
||||
}
|
129
test/CImageResizerStrategyKeepAspectRatioTest.php
Normal file
129
test/CImageResizerStrategyKeepAspectRatioTest.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerStrategyKeepAspectRatioTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return array(
|
||||
|
||||
// Square
|
||||
array(100, 100, null, null, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, null, 200, 200, 200, 0, 0, 100, 100),
|
||||
array(100, 100, 200, null, 200, 200, 0, 0, 100, 100),
|
||||
array(100, 100, 200, 200, 200, 200, 0, 0, 100, 100),
|
||||
|
||||
// Landscape
|
||||
array(200, 100, null, null, 200, 100, 0, 0, 200, 100),
|
||||
array(200, 100, null, 200, 400, 200, 0, 0, 200, 100),
|
||||
array(200, 100, 400, null, 400, 200, 0, 0, 200, 100),
|
||||
array(200, 100, 400, 200, 400, 200, 0, 0, 200, 100),
|
||||
|
||||
// Portrait
|
||||
array(100, 200, null, null, 100, 200, 0, 0, 100, 200),
|
||||
array(100, 200, null, 100, 50, 100, 0, 0, 100, 200),
|
||||
array(100, 200, 50, null, 50, 100, 0, 0, 100, 200),
|
||||
array(100, 200, 50, 100, 50, 100, 0, 0, 100, 200),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1($sw, $sh, $tw, $th, $twa, $tha, $cx, $cy, $cw, $ch)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::KEEP_RATIO)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($twa, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($tha, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($cx, $img->getCropX(), "CropX not correct.");
|
||||
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
|
||||
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
|
||||
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages2()
|
||||
{
|
||||
return array(
|
||||
|
||||
// Square
|
||||
array(100, 100, 100, 100, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, null, 200, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, 200, null, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, 200, 100, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, 100, 200, 100, 100, 0, 0, 100, 100),
|
||||
array(100, 100, 200, 200, 100, 100, 0, 0, 100, 100),
|
||||
|
||||
// Landscape
|
||||
//array(200, 100, null, null, 200, 100, 0, 0, 200, 100),
|
||||
//array(200, 100, null, 200, 400, 200, 0, 0, 200, 100),
|
||||
//array(200, 100, 400, null, 400, 200, 0, 0, 200, 100),
|
||||
//array(200, 100, 400, 200, 400, 200, 0, 0, 200, 100),
|
||||
|
||||
// Portrait
|
||||
//array(100, 200, null, null, 100, 200, 0, 0, 100, 200),
|
||||
//array(100, 200, null, 100, 50, 100, 0, 0, 100, 200),
|
||||
//array(100, 200, 50, null, 50, 100, 0, 0, 100, 200),
|
||||
//array(100, 200, 50, 100, 50, 100, 0, 0, 100, 200),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize2($sw, $sh, $tw, $th, $twa, $tha, $cx, $cy, $cw, $ch)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::KEEP_RATIO)
|
||||
->allowUpscale(false)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($twa, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($tha, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($cx, $img->getCropX(), "CropX not correct.");
|
||||
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
|
||||
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
|
||||
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
|
||||
}
|
||||
}
|
57
test/CImageResizerStrategyStretchTest.php
Normal file
57
test/CImageResizerStrategyStretchTest.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
class CImageResizerStrategyStretchTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return array(
|
||||
|
||||
// Square
|
||||
array(100, 100, 200, 200),
|
||||
array(100, 100, 200, 100),
|
||||
array(100, 100, 100, 200),
|
||||
|
||||
// Landscape
|
||||
array(200, 100, 400, 200),
|
||||
array(200, 100, 100, 200),
|
||||
|
||||
// Portrait
|
||||
array(100, 200, 50, 100),
|
||||
array(100, 200, 100, 100),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize1($sw, $sh, $tw, $th)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy(CImageResizer::STRETCH)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($tw, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($th, $img->getTargetHeight(), "Target height not correct.");
|
||||
}
|
||||
}
|
207
test/CImageResizerTest.php
Normal file
207
test/CImageResizerTest.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
*/
|
||||
function logger($str)
|
||||
{
|
||||
echo "$str\n";
|
||||
}
|
||||
|
||||
function loggerDummy($str)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
class CImageResizerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerFaultImages()
|
||||
{
|
||||
return array(
|
||||
array('xx', 100, null, 1),
|
||||
array( 100, 'yy', null, 1),
|
||||
array( 100, 100, 'zz', 1),
|
||||
array( 100, 100, null, -1),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerFaultImages
|
||||
*
|
||||
* @expectedException Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResizeFaults($targetWidth, $targetHeight, $aspectRatio, $dpr)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
|
||||
$img->setBaseWidthHeight($targetWidth, $targetHeight)
|
||||
->setBaseAspecRatio($aspectRatio)
|
||||
->setBaseDevicePixelRate($dpr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLogger()
|
||||
{
|
||||
$img = new CImageResizer('Mos\CImage\loggerDummy');
|
||||
|
||||
$img->setBaseWidthHeight(100, 100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerResizeStrategy()
|
||||
{
|
||||
return array(
|
||||
array(CImageResizer::KEEP_RATIO, "KEEP_RATIO"),
|
||||
array(CImageResizer::CROP_TO_FIT, "CROP_TO_FIT"),
|
||||
array(CImageResizer::FILL_TO_FIT, "FILL_TO_FIT"),
|
||||
array(CImageResizer::STRETCH, "STRETCH"),
|
||||
array(-1, "UNKNOWN"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerResizeStrategy
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResizeStrategy($strategy, $str)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
|
||||
$img->setResizeStrategy($strategy);
|
||||
$res = $img->getResizeStrategyAsString();
|
||||
|
||||
$this->assertEquals($str, $res, "Strategy not matching.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerPercent()
|
||||
{
|
||||
return array(
|
||||
array(100, 100, "100%", "100%", 100, 100),
|
||||
array(100, 100, "50%", "50%", 50, 50),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerPercent
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPercent($sw, $sh, $tw, $th, $w, $h)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th);
|
||||
|
||||
$this->assertEquals($w, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($h, $img->getTargetHeight(), "Target height not correct.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetSource()
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'*/);
|
||||
|
||||
$w = 100;
|
||||
$h = 100;
|
||||
|
||||
$img->setSource($w, $h);
|
||||
|
||||
$this->assertEquals($w, $img->getSourceWidth(), "Source width not correct.");
|
||||
$this->assertEquals($h, $img->getSourceHeight(), "Source height not correct.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerImages()
|
||||
{
|
||||
return [
|
||||
|
||||
// car.png
|
||||
[CImageResizer::KEEP_RATIO, 491, 324, 500, 200, 303, 200, 0, 0, 491, 324],
|
||||
[CImageResizer::KEEP_RATIO, 491, 324, 500, 500, 500, 330, 0, 0, 491, 324],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @dataProvider providerImages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize($strat, $sw, $sh, $tw, $th, $twa, $tha, $cx, $cy, $cw, $ch)
|
||||
{
|
||||
$img = new CImageResizer(/*'logger'/**/);
|
||||
|
||||
$img->setSource($sw, $sh)
|
||||
->setBaseWidthHeight($tw, $th)
|
||||
->setResizeStrategy($strat)
|
||||
->calculateTargetWidthAndHeight();
|
||||
|
||||
$this->assertEquals($twa, $img->getTargetWidth(), "Target width not correct.");
|
||||
$this->assertEquals($tha, $img->getTargetHeight(), "Target height not correct.");
|
||||
|
||||
$this->assertEquals($cx, $img->getCropX(), "CropX not correct.");
|
||||
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
|
||||
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
|
||||
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
|
||||
}
|
||||
}
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
|
54
test/CImgTest.php
Normal file
54
test/CImgTest.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass for img.php
|
||||
*
|
||||
*/
|
||||
class CImgTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerQueryString()
|
||||
{
|
||||
return [
|
||||
|
||||
//
|
||||
[[
|
||||
"src" => "car.png",
|
||||
"json" => true,
|
||||
"rotate" => 90,
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test
|
||||
*
|
||||
* @-preserveGlobalState disabled
|
||||
* @runInSeparateProcess
|
||||
*
|
||||
* @dataProvider providerQueryString
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testResize($query)
|
||||
{
|
||||
//$_GET = $query;
|
||||
|
||||
#ob_start();
|
||||
//$res = require "webroot/img.php";
|
||||
#$res = ob_get_clean();
|
||||
|
||||
//echo "MOPED $res";
|
||||
}
|
||||
}
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* A testclass
|
||||
*
|
||||
|
13
test/Tests.txt
Normal file
13
test/Tests.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# Tests to be done
|
||||
|
||||
Use resize fill-to-fit, crop-to-fit, stretch without width and height should result in image having original width and height.
|
||||
|
||||
## Integration tests
|
||||
|
||||
Checkout a version using composer and execute all tests, prefarably on cimage.se.
|
||||
|
||||
|
||||
|
||||
## Reference images
|
||||
|
||||
Create a bunch of reference images to compare between versions. Save together with how it was created.
|
@@ -3,7 +3,12 @@
|
||||
* Get all configuration details to be able to execute the test suite.
|
||||
*
|
||||
*/
|
||||
require __DIR__ . "/../autoload.php";
|
||||
require __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
define('IMAGE_PATH', __DIR__ . '/../webroot/img/');
|
||||
define('CACHE_PATH', __DIR__ . '/../cache/');
|
||||
if (!defined("IMAGE_PATH")) {
|
||||
define("IMAGE_PATH", __DIR__ . "/../webroot/img/");
|
||||
}
|
||||
|
||||
if (!defined("CACHE_PATH")) {
|
||||
define("CACHE_PATH", __DIR__ . "/../cache/");
|
||||
}
|
||||
|
7
vendor/autoload.php
vendored
Normal file
7
vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit2b4448ad4be850d755525f1f201dede8::getLoader();
|
441
vendor/composer/ClassLoader.php
vendored
Normal file
441
vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
private $classMapAuthoritative = false;
|
||||
private $missingClasses = array();
|
||||
private $apcuPrefix;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
21
vendor/composer/LICENSE
vendored
Normal file
21
vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) 2016 Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
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.
|
||||
|
9
vendor/composer/autoload_classmap.php
vendored
Normal file
9
vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
11
vendor/composer/autoload_files.php
vendored
Normal file
11
vendor/composer/autoload_files.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'c033e147fa8801d0fd8ea2bc8fa37e2a' => $baseDir . '/src/defines.php',
|
||||
'3b345cc3469552d097f31e5a67742144' => $baseDir . '/src/functions.php',
|
||||
);
|
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
10
vendor/composer/autoload_psr4.php
vendored
Normal file
10
vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Mos\\' => array($baseDir . '/src'),
|
||||
);
|
70
vendor/composer/autoload_real.php
vendored
Normal file
70
vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit2b4448ad4be850d755525f1f201dede8
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit2b4448ad4be850d755525f1f201dede8', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit2b4448ad4be850d755525f1f201dede8', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit2b4448ad4be850d755525f1f201dede8::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit2b4448ad4be850d755525f1f201dede8::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire2b4448ad4be850d755525f1f201dede8($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire2b4448ad4be850d755525f1f201dede8($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
36
vendor/composer/autoload_static.php
vendored
Normal file
36
vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit2b4448ad4be850d755525f1f201dede8
|
||||
{
|
||||
public static $files = array (
|
||||
'c033e147fa8801d0fd8ea2bc8fa37e2a' => __DIR__ . '/../..' . '/src/defines.php',
|
||||
'3b345cc3469552d097f31e5a67742144' => __DIR__ . '/../..' . '/src/functions.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'M' =>
|
||||
array (
|
||||
'Mos\\' => 4,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Mos\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit2b4448ad4be850d755525f1f201dede8::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit2b4448ad4be850d755525f1f201dede8::$prefixDirsPsr4;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
1
vendor/composer/installed.json
vendored
Normal file
1
vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
@@ -2,7 +2,7 @@
|
||||
|
||||
echo 'Current PHP version: ' . phpversion() . '<br><br>';
|
||||
|
||||
echo 'Running on: ' . $_SERVER['SERVER_SOFTWARE'] . '<br><br>';
|
||||
echo 'Running on: ' . htmlentities($_SERVER['SERVER_SOFTWARE']) . '<br><br>';
|
||||
|
||||
$no = extension_loaded('exif') ? null : 'NOT';
|
||||
echo "Extension exif is $no loaded.<br>";
|
||||
|
@@ -4,7 +4,7 @@
|
||||
# The example is set up as following.
|
||||
#
|
||||
# img A directory where all images are stored
|
||||
# img/me.jpg Access a image as usually.
|
||||
# img/me.jpg Access a image as usual.
|
||||
# image/me.jpg Access a image though img.php using htaccess rewrite.
|
||||
# image/me.jpg?w=300 Using options to img.php.
|
||||
#
|
||||
|
@@ -8,6 +8,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom exception handler.
|
||||
*/
|
||||
set_exception_handler(function ($exception) {
|
||||
errorPage(
|
||||
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||
. $exception->getMessage()
|
||||
. "</p><pre>"
|
||||
. $exception->getTraceAsString()
|
||||
. "</pre>",
|
||||
500
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get configuration options from file, if the file exists, else use $config
|
||||
* if its defined or create an empty $config.
|
||||
@@ -73,36 +89,28 @@ if (!extension_loaded('gd')) {
|
||||
|
||||
// Specific settings for each mode
|
||||
if ($mode == 'strict') {
|
||||
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
$verbose = false;
|
||||
$status = false;
|
||||
$verboseFile = false;
|
||||
|
||||
} elseif ($mode == 'production') {
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
$verbose = false;
|
||||
$status = false;
|
||||
$verboseFile = false;
|
||||
|
||||
} elseif ($mode == 'development') {
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('log_errors', 0);
|
||||
$verboseFile = false;
|
||||
|
||||
} elseif ($mode == 'test') {
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('log_errors', 0);
|
||||
|
||||
} else {
|
||||
errorPage("Unknown mode: $mode", 500);
|
||||
}
|
||||
@@ -192,7 +200,6 @@ if (!$allowHotlinking) {
|
||||
} else {
|
||||
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.", 403);
|
||||
}
|
||||
|
||||
} else {
|
||||
errorPage("Hotlinking/leeching not allowed.", 403);
|
||||
}
|
||||
@@ -207,7 +214,7 @@ verbose("referer host = $refererHost");
|
||||
/**
|
||||
* Create the class for the image.
|
||||
*/
|
||||
$CImage = getConfig('CImage', 'CImage');
|
||||
$CImage = getConfig('CImage', '\Mos\CImage\CImage');
|
||||
$img = new $CImage();
|
||||
$img->setVerbose($verbose || $verboseFile);
|
||||
|
||||
@@ -216,7 +223,7 @@ $img->setVerbose($verbose || $verboseFile);
|
||||
/**
|
||||
* Get the cachepath from config.
|
||||
*/
|
||||
$CCache = getConfig('CCache', 'CCache');
|
||||
$CCache = getConfig('CCache', '\Mos\CImage\CCache');
|
||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||
$cache = new $CCache();
|
||||
$cache->setDir($cachePath);
|
||||
@@ -238,7 +245,7 @@ verbose("use cache = $useCache");
|
||||
$fastTrackCache = "fasttrack";
|
||||
$allowFastTrackCache = getConfig('fast_track_allow', false);
|
||||
|
||||
$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache');
|
||||
$CFastTrackCache = getConfig('CFastTrackCache', '\Mos\CImage\CFastTrackCache');
|
||||
$ftc = new $CFastTrackCache();
|
||||
$ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache))
|
||||
->enable($allowFastTrackCache)
|
||||
@@ -291,8 +298,8 @@ $shortcutConfig = getConfig('shortcut', array(
|
||||
verbose("shortcut = $shortcut");
|
||||
|
||||
if (isset($shortcut)
|
||||
&& isset($shortcutConfig[$shortcut])) {
|
||||
|
||||
&& isset($shortcutConfig[$shortcut])
|
||||
) {
|
||||
parse_str($shortcutConfig[$shortcut], $get);
|
||||
verbose("shortcut-constant = {$shortcutConfig[$shortcut]}");
|
||||
$_GET = array_merge($_GET, $get);
|
||||
@@ -330,17 +337,12 @@ preg_match($validFilename, $srcImage)
|
||||
or errorPage('Source filename contains invalid characters.', 404);
|
||||
|
||||
if ($dummyEnabled && $srcImage === $dummyFilename) {
|
||||
|
||||
// Prepare to create a dummy image and use it as the source image.
|
||||
$dummyImage = true;
|
||||
|
||||
} elseif ($allowRemote && $img->isRemoteSource($srcImage)) {
|
||||
|
||||
// If source is a remote file, ignore local file checks.
|
||||
$remoteSource = true;
|
||||
|
||||
} else {
|
||||
|
||||
// Check if file exists on disk or try using src-alt
|
||||
$pathToImage = realpath($imagePath . $srcImage);
|
||||
|
||||
@@ -365,7 +367,7 @@ if ($dummyEnabled && $srcImage === $dummyFilename) {
|
||||
matching file exists on the filesystem.',
|
||||
404
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($imagePathConstraint && !$dummyImage && !$remoteSource) {
|
||||
@@ -1120,7 +1122,7 @@ EOD;
|
||||
/**
|
||||
* Load, process and output the image
|
||||
*/
|
||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
$res = $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->setSaveFolder($cachePath)
|
||||
->useCache($useCache)
|
||||
->setSource($srcImage, $imagePath)
|
||||
@@ -1179,3 +1181,5 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->save()
|
||||
->linkToCacheFile($aliasTarget)
|
||||
->output();
|
||||
|
||||
return $res;
|
||||
|
171
webroot/img/drawing.svg
Normal file
171
webroot/img/drawing.svg
Normal file
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 744.09448819 1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="drawing.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="76.428572"
|
||||
inkscape:cy="-22.526694"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="919"
|
||||
inkscape:window-height="416"
|
||||
inkscape:window-x="167"
|
||||
inkscape:window-y="177"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="rect4146"
|
||||
width="100"
|
||||
height="100"
|
||||
x="-7.4924429e-08"
|
||||
y="952.36218"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 0,952.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="rect4136"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4140"
|
||||
d="m 166,948.8622 0,10 10,0 0,-10 -10,0 z"
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 185.5,949.3622 0,10 10,0 0,-10 -10,0 z"
|
||||
id="path4142"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4144"
|
||||
d="m 201.5,949.8622 0,10 10,0 0,-10 -10,0 z"
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4148"
|
||||
d="m 40,952.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 80,952.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="path4150"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4152"
|
||||
d="m 20,972.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#000080;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 60,972.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="path4154"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4156"
|
||||
d="m 0,992.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 40,992.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="path4158"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4160"
|
||||
d="m 80,992.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#00ffff;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 20,1012.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="path4162"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4164"
|
||||
d="m 60,1012.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#000080;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4166"
|
||||
d="m 0,1032.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
d="m 40,1032.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
id="path4168"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4170"
|
||||
d="m 80,1032.3622 0,20 20,0 0,-20 -20,0 z"
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
BIN
webroot/img/test_100x100.png
Normal file
BIN
webroot/img/test_100x100.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 445 B |
BIN
webroot/img/tower.jpg
Normal file
BIN
webroot/img/tower.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
@@ -23,7 +23,7 @@ if (!defined("CIMAGE_DEBUG")) {
|
||||
|
||||
|
||||
|
||||
return array(
|
||||
return [
|
||||
|
||||
/**
|
||||
* Set mode as 'strict', 'production' or 'development'.
|
||||
@@ -41,7 +41,7 @@ return array(
|
||||
* mode: 'production'
|
||||
*/
|
||||
//'mode' => 'production',
|
||||
//'mode' => 'development',
|
||||
'mode' => 'development',
|
||||
//'mode' => 'strict',
|
||||
|
||||
|
||||
@@ -52,12 +52,14 @@ return array(
|
||||
* Default values:
|
||||
* autoloader: null
|
||||
*/
|
||||
'autoloader' => __DIR__ . '/../autoload.php',
|
||||
//'autoloader' => __DIR__ . '/../autoload.php',
|
||||
'autoloader' => __DIR__ . '/../vendor/autoload.php',
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Paths, where are the images stored and where is the cache.
|
||||
* Path to aliases, useful when downloading external images and you
|
||||
* want to create a local copy of the file, a alias file.
|
||||
* End all paths with a slash.
|
||||
*
|
||||
* Default values:
|
||||
@@ -89,13 +91,13 @@ return array(
|
||||
* the codebase.
|
||||
*
|
||||
* Default values:
|
||||
* CImage: CImage
|
||||
* CCache: CCache
|
||||
* CFastTrackCache: CFastTrackCache
|
||||
* CImage: \Mos\CImage\CImage
|
||||
* CCache: \Mos\CImage\CCache
|
||||
* CFastTrackCache: \Mos\CImage\CFastTrackCache
|
||||
*/
|
||||
//'CImage' => 'CImage',
|
||||
//'CCache' => 'CCache',
|
||||
//'CFastTrackCache' => 'CFastTrackCache',
|
||||
//'CImage' => '\Mos\CImage\CImage',
|
||||
//'CCache' => '\Mos\CImage\CCache',
|
||||
//'CFastTrackCache' => '\Mos\CImage\CFastTrackCache',
|
||||
|
||||
|
||||
|
||||
@@ -141,13 +143,14 @@ return array(
|
||||
* 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$'
|
||||
//),
|
||||
/*
|
||||
'remote_allow' => true,
|
||||
'remote_pattern' => '#^https?://#',
|
||||
'remote_whitelist' => [
|
||||
'\.facebook\.com$',
|
||||
'^(?:images|photos-[a-z])\.ak\.instagram\.com$',
|
||||
'\.google\.com$'
|
||||
], */
|
||||
|
||||
|
||||
|
||||
@@ -182,18 +185,20 @@ return array(
|
||||
* when saving images.
|
||||
*
|
||||
* Default value:
|
||||
* jpg_quality: null, integer between 0-100
|
||||
* png_compression: null, integer between 0-9
|
||||
* jpg_quality: null, integer between 0-100,
|
||||
* default is 60
|
||||
* png_compression: null, integer between 0-9,
|
||||
* default is -1 (PHP GD decides)
|
||||
*/
|
||||
//'jpg_quality' => 75,
|
||||
//'png_compression' => 1,
|
||||
//'jpg_quality' => 60,
|
||||
//'png_compression' => -1,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert the image to srgb before processing. Saves the converted
|
||||
* 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.
|
||||
* be changed to default true to always do conversion for all images.
|
||||
* This option requires PHP extension imagick and will silently fail
|
||||
* if that is not installed.
|
||||
*
|
||||
@@ -341,8 +346,8 @@ return array(
|
||||
* jpeg_optimize_cmd: '/usr/local/bin/jpegtran -copy none -optimize'
|
||||
*/
|
||||
/*
|
||||
'postprocessing' => array(
|
||||
'png_lossy' => false,
|
||||
'postprocessing' => [
|
||||
'png_lossy' => null,
|
||||
'png_lossy_cmd' => '/usr/local/bin/pngquant --force --output',
|
||||
|
||||
'png_filter' => false,
|
||||
@@ -353,7 +358,7 @@ return array(
|
||||
|
||||
'jpeg_optimize' => false,
|
||||
'jpeg_optimize_cmd' => '/usr/local/bin/jpegtran -copy none -optimize',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -363,13 +368,13 @@ return array(
|
||||
* offset.
|
||||
*
|
||||
* Default values.
|
||||
* convolution_constant: array()
|
||||
* convolution_constant: []
|
||||
*/
|
||||
/*
|
||||
'convolution_constant' => array(
|
||||
'convolution_constant' => [
|
||||
//'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',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -386,13 +391,13 @@ return array(
|
||||
*
|
||||
* Default values.
|
||||
* allow_hotlinking: true
|
||||
* hotlinking_whitelist: array()
|
||||
* hotlinking_whitelist: []
|
||||
*/
|
||||
/*
|
||||
'allow_hotlinking' => false,
|
||||
'hotlinking_whitelist' => array(
|
||||
'hotlinking_whitelist' => [
|
||||
'^dbwebb\.se$',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -400,14 +405,14 @@ return array(
|
||||
* Create custom shortcuts for more advanced expressions.
|
||||
*
|
||||
* Default values.
|
||||
* shortcut: array(
|
||||
* shortcut: [
|
||||
* 'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
|
||||
* )
|
||||
* ]
|
||||
*/
|
||||
/*
|
||||
'shortcut' => array(
|
||||
'shortcut' => [
|
||||
'sepia' => "&f=grayscale&f0=brightness,-10&f1=contrast,-20&f2=colorize,120,60,0,0&sharpen",
|
||||
),*/
|
||||
],*/
|
||||
|
||||
|
||||
|
||||
@@ -430,10 +435,10 @@ return array(
|
||||
'size_constant' => function () {
|
||||
|
||||
// Set sizes to map constant to value, easier to use with width or height
|
||||
$sizes = array(
|
||||
'w1' => 613,
|
||||
'w2' => 630,
|
||||
);
|
||||
$sizes = [
|
||||
'w1' => 613,
|
||||
'w2' => 630,
|
||||
];
|
||||
|
||||
// Add grid column width, useful for use as predefined size for width (or height).
|
||||
$gridColumnWidth = 30;
|
||||
@@ -456,7 +461,7 @@ return array(
|
||||
* aspect_ratio_constant: As the function below.
|
||||
*/
|
||||
/*'aspect_ratio_constant' => function () {
|
||||
return array(
|
||||
return [
|
||||
'3:1' => 3/1,
|
||||
'3:2' => 3/2,
|
||||
'4:3' => 4/3,
|
||||
@@ -464,7 +469,7 @@ return array(
|
||||
'16:10' => 16/10,
|
||||
'16:9' => 16/9,
|
||||
'golden' => 1.618,
|
||||
);
|
||||
];
|
||||
},*/
|
||||
|
||||
|
||||
@@ -480,11 +485,11 @@ return array(
|
||||
* luminanceStrategy: Choose any strategy available in CAsciiArt.
|
||||
* customCharacterSet: Define your own character set.
|
||||
*/
|
||||
/*'ascii-options' => array(
|
||||
/*'ascii-options' => [
|
||||
"characterSet" => 'two',
|
||||
"scale" => 14,
|
||||
"luminanceStrategy" => 3,
|
||||
"customCharacterSet" => null,
|
||||
);
|
||||
},*/
|
||||
);
|
||||
],*/
|
||||
];
|
||||
|
@@ -38,7 +38,7 @@ $config = array(
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.15 (2016-08-09)");
|
||||
define("CIMAGE_VERSION", "v0.7.18 (2016-08-09)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
@@ -217,6 +217,27 @@ function verbose($msg = null)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
@@ -1260,6 +1281,13 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Do lossy output using external postprocessing tools.
|
||||
*/
|
||||
private $lossy = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verbose mode to print out a trace and display the created image
|
||||
*/
|
||||
@@ -1295,7 +1323,15 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for filter optimize, for example optipng or null.
|
||||
* Path to command for lossy optimize, for example pngquant.
|
||||
*/
|
||||
private $pngLossy;
|
||||
private $pngLossyCmd;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for filter optimize, for example optipng.
|
||||
*/
|
||||
private $pngFilter;
|
||||
private $pngFilterCmd;
|
||||
@@ -1303,7 +1339,7 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for deflate optimize, for example pngout or null.
|
||||
* Path to command for deflate optimize, for example pngout.
|
||||
*/
|
||||
private $pngDeflate;
|
||||
private $pngDeflateCmd;
|
||||
@@ -1932,6 +1968,9 @@ class CImage
|
||||
// Output format
|
||||
'outputFormat' => null,
|
||||
'dpr' => 1,
|
||||
|
||||
// Postprocessing using external tools
|
||||
'lossy' => null,
|
||||
);
|
||||
|
||||
// Convert crop settings from string to array
|
||||
@@ -2452,6 +2491,7 @@ class CImage
|
||||
&& !$this->autoRotate
|
||||
&& !$this->bgColor
|
||||
&& ($this->upscale === self::UPSCALE_DEFAULT)
|
||||
&& !$this->lossy
|
||||
) {
|
||||
$this->log("Using original image.");
|
||||
$this->output($this->pathToImage);
|
||||
@@ -2485,6 +2525,7 @@ class CImage
|
||||
$compress = $this->compress ? "_co{$this->compress}" : null;
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -2551,7 +2592,7 @@ class CImage
|
||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette
|
||||
. $optimize . $compress
|
||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
|
||||
. $convolve . $copyStrat . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -3450,6 +3491,14 @@ class CImage
|
||||
$this->jpegOptimizeCmd = null;
|
||||
}
|
||||
|
||||
if (array_key_exists("png_lossy", $options)
|
||||
&& $options['png_lossy'] !== false) {
|
||||
$this->pngLossy = $options['png_lossy'];
|
||||
$this->pngLossyCmd = $options['png_lossy_cmd'];
|
||||
} else {
|
||||
$this->pngLossyCmd = null;
|
||||
}
|
||||
|
||||
if (isset($options['png_filter']) && $options['png_filter']) {
|
||||
$this->pngFilterCmd = $options['png_filter_cmd'];
|
||||
} else {
|
||||
@@ -3551,6 +3600,24 @@ class CImage
|
||||
imagesavealpha($this->image, true);
|
||||
imagepng($this->image, $this->cacheFileName, $this->compress);
|
||||
|
||||
// Use external program to process lossy PNG, if defined
|
||||
$lossyEnabled = $this->pngLossy === true;
|
||||
$lossySoftEnabled = $this->pngLossy === null;
|
||||
$lossyActiveEnabled = $this->lossy === true;
|
||||
if ($lossyEnabled || ($lossySoftEnabled && $lossyActiveEnabled)) {
|
||||
if ($this->verbose) {
|
||||
clearstatcache();
|
||||
$this->log("Lossy enabled: $lossyEnabled");
|
||||
$this->log("Lossy soft enabled: $lossySoftEnabled");
|
||||
$this->Log("Filesize before lossy optimize: " . filesize($this->cacheFileName) . " bytes.");
|
||||
}
|
||||
$res = array();
|
||||
$cmd = $this->pngLossyCmd . " $this->cacheFileName $this->cacheFileName";
|
||||
exec($cmd, $res);
|
||||
$this->Log($cmd);
|
||||
$this->Log($res);
|
||||
}
|
||||
|
||||
// Use external program to filter PNG, if defined
|
||||
if ($this->pngFilterCmd) {
|
||||
if ($this->verbose) {
|
||||
@@ -5183,6 +5250,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',
|
||||
|
||||
@@ -5195,6 +5265,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.
|
||||
@@ -5313,7 +5392,7 @@ if ($status) {
|
||||
$res = $cache->getStatusOfSubdir("srgb");
|
||||
$text .= "Cache srgb $res\n";
|
||||
|
||||
$res = $cache->getStatusOfSubdir($fasttrackCache);
|
||||
$res = $cache->getStatusOfSubdir($fastTrackCache);
|
||||
$text .= "Cache fasttrack $res\n";
|
||||
|
||||
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
||||
@@ -5330,6 +5409,11 @@ if ($status) {
|
||||
$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);
|
||||
}
|
||||
@@ -5398,6 +5482,7 @@ if (is_callable($hookBeforeCImage)) {
|
||||
|
||||
// Other
|
||||
'postProcessing' => $postProcessing,
|
||||
'lossy' => $lossy,
|
||||
));
|
||||
verbose(print_r($allConfig, 1));
|
||||
extract($allConfig);
|
||||
@@ -5482,6 +5567,9 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
'dpr' => $dpr,
|
||||
|
||||
// Postprocessing using external tools
|
||||
'lossy' => $lossy,
|
||||
)
|
||||
)
|
||||
->loadImageDetails()
|
||||
|
@@ -38,7 +38,7 @@ $config = array(
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.7.15 (2016-08-09)");
|
||||
define("CIMAGE_VERSION", "v0.7.18 (2016-08-09)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
@@ -217,6 +217,27 @@ function verbose($msg = null)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a image from a remote server using HTTP GET and If-Modified-Since.
|
||||
*
|
||||
@@ -1260,6 +1281,13 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Do lossy output using external postprocessing tools.
|
||||
*/
|
||||
private $lossy = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verbose mode to print out a trace and display the created image
|
||||
*/
|
||||
@@ -1295,7 +1323,15 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for filter optimize, for example optipng or null.
|
||||
* Path to command for lossy optimize, for example pngquant.
|
||||
*/
|
||||
private $pngLossy;
|
||||
private $pngLossyCmd;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for filter optimize, for example optipng.
|
||||
*/
|
||||
private $pngFilter;
|
||||
private $pngFilterCmd;
|
||||
@@ -1303,7 +1339,7 @@ class CImage
|
||||
|
||||
|
||||
/**
|
||||
* Path to command for deflate optimize, for example pngout or null.
|
||||
* Path to command for deflate optimize, for example pngout.
|
||||
*/
|
||||
private $pngDeflate;
|
||||
private $pngDeflateCmd;
|
||||
@@ -1932,6 +1968,9 @@ class CImage
|
||||
// Output format
|
||||
'outputFormat' => null,
|
||||
'dpr' => 1,
|
||||
|
||||
// Postprocessing using external tools
|
||||
'lossy' => null,
|
||||
);
|
||||
|
||||
// Convert crop settings from string to array
|
||||
@@ -2452,6 +2491,7 @@ class CImage
|
||||
&& !$this->autoRotate
|
||||
&& !$this->bgColor
|
||||
&& ($this->upscale === self::UPSCALE_DEFAULT)
|
||||
&& !$this->lossy
|
||||
) {
|
||||
$this->log("Using original image.");
|
||||
$this->output($this->pathToImage);
|
||||
@@ -2485,6 +2525,7 @@ class CImage
|
||||
$compress = $this->compress ? "_co{$this->compress}" : null;
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -2551,7 +2592,7 @@ class CImage
|
||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette
|
||||
. $optimize . $compress
|
||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
|
||||
. $convolve . $copyStrat . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -3450,6 +3491,14 @@ class CImage
|
||||
$this->jpegOptimizeCmd = null;
|
||||
}
|
||||
|
||||
if (array_key_exists("png_lossy", $options)
|
||||
&& $options['png_lossy'] !== false) {
|
||||
$this->pngLossy = $options['png_lossy'];
|
||||
$this->pngLossyCmd = $options['png_lossy_cmd'];
|
||||
} else {
|
||||
$this->pngLossyCmd = null;
|
||||
}
|
||||
|
||||
if (isset($options['png_filter']) && $options['png_filter']) {
|
||||
$this->pngFilterCmd = $options['png_filter_cmd'];
|
||||
} else {
|
||||
@@ -3551,6 +3600,24 @@ class CImage
|
||||
imagesavealpha($this->image, true);
|
||||
imagepng($this->image, $this->cacheFileName, $this->compress);
|
||||
|
||||
// Use external program to process lossy PNG, if defined
|
||||
$lossyEnabled = $this->pngLossy === true;
|
||||
$lossySoftEnabled = $this->pngLossy === null;
|
||||
$lossyActiveEnabled = $this->lossy === true;
|
||||
if ($lossyEnabled || ($lossySoftEnabled && $lossyActiveEnabled)) {
|
||||
if ($this->verbose) {
|
||||
clearstatcache();
|
||||
$this->log("Lossy enabled: $lossyEnabled");
|
||||
$this->log("Lossy soft enabled: $lossySoftEnabled");
|
||||
$this->Log("Filesize before lossy optimize: " . filesize($this->cacheFileName) . " bytes.");
|
||||
}
|
||||
$res = array();
|
||||
$cmd = $this->pngLossyCmd . " $this->cacheFileName $this->cacheFileName";
|
||||
exec($cmd, $res);
|
||||
$this->Log($cmd);
|
||||
$this->Log($res);
|
||||
}
|
||||
|
||||
// Use external program to filter PNG, if defined
|
||||
if ($this->pngFilterCmd) {
|
||||
if ($this->verbose) {
|
||||
@@ -5183,6 +5250,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',
|
||||
|
||||
@@ -5195,6 +5265,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.
|
||||
@@ -5313,7 +5392,7 @@ if ($status) {
|
||||
$res = $cache->getStatusOfSubdir("srgb");
|
||||
$text .= "Cache srgb $res\n";
|
||||
|
||||
$res = $cache->getStatusOfSubdir($fasttrackCache);
|
||||
$res = $cache->getStatusOfSubdir($fastTrackCache);
|
||||
$text .= "Cache fasttrack $res\n";
|
||||
|
||||
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
||||
@@ -5330,6 +5409,11 @@ if ($status) {
|
||||
$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);
|
||||
}
|
||||
@@ -5398,6 +5482,7 @@ if (is_callable($hookBeforeCImage)) {
|
||||
|
||||
// Other
|
||||
'postProcessing' => $postProcessing,
|
||||
'lossy' => $lossy,
|
||||
));
|
||||
verbose(print_r($allConfig, 1));
|
||||
extract($allConfig);
|
||||
@@ -5482,6 +5567,9 @@ $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
'dpr' => $dpr,
|
||||
|
||||
// Postprocessing using external tools
|
||||
'lossy' => $lossy,
|
||||
)
|
||||
)
|
||||
->loadImageDetails()
|
||||
|
File diff suppressed because one or more lines are too long
@@ -18,43 +18,38 @@ $description = "Do not upscale image when original image (slice) is smaller than
|
||||
$images = array(
|
||||
'car.png',
|
||||
'apple.jpg',
|
||||
'tower.jpg',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = "&bgc=660000"; //null; //"&nc"; //null; //&nc';
|
||||
$nc = "&bgc=660000&nc"; //null; //"&nc"; //null; //&nc';
|
||||
$testcase = array(
|
||||
$nc . '&w=600',
|
||||
$nc . '&w=600&no-upscale',
|
||||
$nc . '&h=400',
|
||||
$nc . '&h=400&no-upscale',
|
||||
$nc . '&w=600&h=400',
|
||||
$nc . '&w=600&h=400&no-upscale',
|
||||
$nc . '&w=700&h=400&stretch',
|
||||
$nc . '&w=700&h=400&no-upscale&stretch',
|
||||
$nc . '&h=420',
|
||||
$nc . '&h=420&no-upscale',
|
||||
$nc . '&w=600&h=420',
|
||||
$nc . '&w=600&h=420&no-upscale',
|
||||
$nc . '&w=700&h=420&stretch',
|
||||
$nc . '&w=700&h=420&no-upscale&stretch',
|
||||
$nc . '&w=700&h=200&stretch',
|
||||
$nc . '&w=700&h=200&no-upscale&stretch',
|
||||
$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=250&h=420&stretch',
|
||||
$nc . '&w=250&h=420&no-upscale&stretch',
|
||||
$nc . '&w=700&h=420&crop-to-fit',
|
||||
$nc . '&w=700&h=420&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=250&h=420&crop-to-fit',
|
||||
$nc . '&w=250&h=420&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',
|
||||
$nc . '&h=400&ar=1.6',
|
||||
$nc . '&h=400&ar=1.6&no-upscale',
|
||||
*/
|
||||
$nc . '&w=250&h=420&fill-to-fit',
|
||||
$nc . '&w=250&h=420&no-upscale&fill-to-fit',
|
||||
$nc . '&w=700&h=420&fill-to-fit',
|
||||
$nc . '&w=700&h=420&no-upscale&fill-to-fit',
|
||||
);
|
||||
|
||||
|
43
webroot/test/resize-landscape.php
Normal file
43
webroot/test/resize-landscape.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing resize landscape image";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Resize landscape image";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'car.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = empty($_SERVER['QUERY_STRING']) ? "" : "&" . $_SERVER['QUERY_STRING'];
|
||||
|
||||
$testcase = array(
|
||||
$nc . '&w=500',
|
||||
$nc . '&h=200',
|
||||
$nc . '&w=500&h=500',
|
||||
$nc . '&w=500&h=200',
|
||||
$nc . '&w=500&h=200&crop-to-fit',
|
||||
$nc . '&w=200&h=500&crop-to-fit',
|
||||
$nc . '&w=500&h=200&fill-to-fit',
|
||||
$nc . '&w=200&h=500&fill-to-fit',
|
||||
$nc . '&w=500&h=200&stretch',
|
||||
$nc . '&w=200&h=500&stretch',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
43
webroot/test/resize-portrait.php
Normal file
43
webroot/test/resize-portrait.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// Include config for all testcases
|
||||
include __DIR__ . "/config.php";
|
||||
|
||||
|
||||
|
||||
// The title of the test case
|
||||
$title = "Testing resize portrait image";
|
||||
|
||||
|
||||
|
||||
// Provide a short description of the testcase.
|
||||
$description = "Resize portrait image";
|
||||
|
||||
|
||||
|
||||
// Use these images in the test
|
||||
$images = array(
|
||||
'kodim04.png',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// For each image, apply these testcases
|
||||
$nc = empty($_SERVER['QUERY_STRING']) ? "" : "&" . $_SERVER['QUERY_STRING'];
|
||||
|
||||
$testcase = array(
|
||||
$nc . '&w=500',
|
||||
$nc . '&h=200',
|
||||
$nc . '&w=500&h=500',
|
||||
$nc . '&w=500&h=200',
|
||||
$nc . '&w=500&h=200&crop-to-fit',
|
||||
$nc . '&w=200&h=500&crop-to-fit',
|
||||
$nc . '&w=500&h=200&fill-to-fit',
|
||||
$nc . '&w=200&h=500&fill-to-fit',
|
||||
$nc . '&w=500&h=200&stretch',
|
||||
$nc . '&w=200&h=500&stretch',
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Apply testcases and present results
|
||||
include __DIR__ . "/template.php";
|
Reference in New Issue
Block a user