Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
daf39105fb | ||
|
026e01b2cd | ||
|
0f0d954e61 | ||
|
58d83ba494 | ||
|
4f8fb82baf | ||
|
1bd8965535 | ||
|
081601ebbb | ||
|
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
@@ -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
@@ -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
@@ -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
@@ -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)
|
68
README.md
@@ -2,10 +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
|
||||
-------------------------------------
|
||||
@@ -47,7 +51,7 @@ There are several ways of installing. You either install the whole project which
|
||||
|
||||
|
||||
|
||||
### Install source from GitHub
|
||||
###Install source from GitHub
|
||||
|
||||
The [sourcode is available on GitHub](https://github.com/mosbth/cimage). Clone, fork or [download as zip](https://github.com/mosbth/cimage/archive/master.zip).
|
||||
|
||||
@@ -68,7 +72,7 @@ chmod 777 cache
|
||||
```
|
||||
|
||||
|
||||
### Install all-included bundle
|
||||
###Install all-included bundle
|
||||
|
||||
There are some all-included bundles of `img.php` that can be downloaded and used without dependency to the rest of the sourcecode.
|
||||
|
||||
@@ -88,7 +92,7 @@ Open up the file in your editor and edit the array `$config`. Ensure that the pa
|
||||
|
||||
|
||||
|
||||
### Install from Packagist
|
||||
###Install from Packagist
|
||||
|
||||
You can install the package [`mos/cimage` from Packagist](https://packagist.org/packages/mos/cimage) using composer.
|
||||
|
||||
@@ -141,13 +145,13 @@ Get going quickly
|
||||
|
||||
|
||||
|
||||
### Check out the test page
|
||||
###Check out the test page
|
||||
|
||||
Try it out by pointing your browser to the test file `webroot/test/test.php`. It will show some example images and you can review how they are created.
|
||||
|
||||
|
||||
|
||||
### Process your first image
|
||||
###Process your first image
|
||||
|
||||
<img src="https://cimage.se/cimage/imgd.php?src=example/kodim04.png&w=w2&a=40,0,50,0" alt=''>
|
||||
|
||||
@@ -161,20 +165,20 @@ and try to resize it to a thumbnail by adding the options
|
||||
|
||||
|
||||
|
||||
### What does "processing the image" involves?
|
||||
###What does "processing the image" involves?
|
||||
|
||||
Add `&verbose` to the link to get a verbose output of what is happens during image processing. This is useful for developers and those who seek a deeper understanding on how it works behind the scene.
|
||||
|
||||
|
||||
|
||||
### Check your system
|
||||
###Check your system
|
||||
|
||||
Open up `webroot/check_system.php` if you are uncertain that your system has the right extensions loaded.
|
||||
|
||||
|
||||
|
||||
|
||||
### How does it work?
|
||||
###How does it work?
|
||||
|
||||
Review the settings in `webroot/img_config.php` and check out `webroot/img.php` on how it uses `CImage`.
|
||||
|
||||
@@ -195,7 +199,7 @@ Basic usage
|
||||
|
||||
|
||||
|
||||
### Select the source
|
||||
###Select the source
|
||||
|
||||
Open an image through `img.php` by using its `src` attribute.
|
||||
|
||||
@@ -211,7 +215,7 @@ All images are stored in a directory structure and you access them as:
|
||||
|
||||
|
||||
|
||||
### Resize using constraints on width and height
|
||||
###Resize using constraints on width and height
|
||||
|
||||
Create a thumbnail of the image by applying constraints on width and height, or one of them.
|
||||
|
||||
@@ -225,7 +229,7 @@ Think of the constraints as a imaginary box where the image should fit. With `wi
|
||||
|
||||
|
||||
|
||||
### Resize to fit a certain dimension
|
||||
###Resize to fit a certain dimension
|
||||
|
||||
Creating a thumbnail with a certain dimension of width and height, usually involves stretching or cropping the image to fit in the selected dimensions. Here is how you create a image that has the exact dimensions of 300x150 pixels, by either *stretching*, *cropping* or *fill to fit*.
|
||||
|
||||
@@ -245,7 +249,7 @@ Fill to fit is useful when you have some image that must fit in a certain dimens
|
||||
|
||||
|
||||
|
||||
### List of parameters
|
||||
###List of parameters
|
||||
|
||||
`img.php` supports a lot of parameters. Combine the parameters to get the desired behavior and resulting image. For example, take the original image, resize it using width, aspect-ratio and crop-to-fit, apply a sharpen effect, save the image as JPEG using quality 30.
|
||||
|
||||
@@ -257,7 +261,7 @@ Fill to fit is useful when you have some image that must fit in a certain dimens
|
||||
Here is a list of all parameters that you can use together with `img.php`, grouped by its basic intent of usage.
|
||||
|
||||
|
||||
#### Mandatory options and debugging
|
||||
####Mandatory options and debugging
|
||||
|
||||
Option `src` is the only mandatory option. The options in this section is useful for debugging or deciding what version of the target image is used.
|
||||
|
||||
@@ -272,7 +276,7 @@ Option `src` is the only mandatory option. The options in this section is useful
|
||||
|
||||
|
||||
|
||||
#### Options for deciding width and height of target image
|
||||
####Options for deciding width and height of target image
|
||||
|
||||
These options are all affecting the final dimensions, width and height, of the resulting image.
|
||||
|
||||
@@ -285,7 +289,7 @@ These options are all affecting the final dimensions, width and height, of the r
|
||||
|
||||
|
||||
|
||||
#### Options for resize strategy
|
||||
####Options for resize strategy
|
||||
|
||||
These options affect strategy to use when resizing an image into a target image that has both width and height set.
|
||||
|
||||
@@ -298,7 +302,7 @@ These options affect strategy to use when resizing an image into a target image
|
||||
|
||||
|
||||
|
||||
#### Options for cropping part of image
|
||||
####Options for cropping part of image
|
||||
|
||||
These options enable to decide what part of image to crop out.
|
||||
|
||||
@@ -309,7 +313,7 @@ These options enable to decide what part of image to crop out.
|
||||
|
||||
|
||||
|
||||
#### General processing options
|
||||
####General processing options
|
||||
|
||||
These options are general options affecting processing.
|
||||
|
||||
@@ -319,7 +323,7 @@ These options are general options affecting processing.
|
||||
|
||||
|
||||
|
||||
#### Processing of image before resizing
|
||||
####Processing of image before resizing
|
||||
|
||||
This option are executed *before* the image is resized.
|
||||
|
||||
@@ -331,7 +335,7 @@ This option are executed *before* the image is resized.
|
||||
|
||||
|
||||
|
||||
#### Processing of image after resizing
|
||||
####Processing of image after resizing
|
||||
|
||||
These options are executed *after* the image is resized.
|
||||
|
||||
@@ -349,7 +353,7 @@ These options are executed *after* the image is resized.
|
||||
|
||||
|
||||
|
||||
#### Saving image, affecting quality and file size
|
||||
####Saving image, affecting quality and file size
|
||||
|
||||
Options for saving the target image.
|
||||
|
||||
@@ -405,7 +409,7 @@ Consult the file `webroot/img-config.php` for a complete list together with the
|
||||
|
||||
|
||||
|
||||
### Create and name the config file
|
||||
###Create and name the config file
|
||||
|
||||
The file `img.php` looks for the config-file `img_config.php`, and uses it if its found. The three files where everything is included -- `imgd.php`, `imgp.php` and `imgs.php` -- includes an empty `$config`-array which can be overridden by saving a config-file in the same directory. If the script is `imgp.php` then name the config-file `imgp_config.php` and it will find it and use those settings.
|
||||
|
||||
@@ -470,19 +474,19 @@ Here are some thoughts when applying `img.php` on a live system.
|
||||
|
||||
|
||||
|
||||
### Select the proper mode
|
||||
###Select the proper mode
|
||||
|
||||
Select the proper mode for `img.php`. Set it to "strict" or "production" to prevent outsiders to get information about your system. Use only "development" for internal use since its quite verbose in its nature of error reporting.
|
||||
|
||||
|
||||
|
||||
### Put the installation directory outside web root
|
||||
###Put the installation directory outside web root
|
||||
|
||||
Edit the config file to put the installation directory -- and the cache directory -- outside of the web root. Best practice would be to store the installation directory and cache, outside of the web root. The only thing needed in the web root is `img.php` and `img_config.php` (if used) which can be placed, for example, in `/img/img.php` or just as `/img.php`.
|
||||
|
||||
|
||||
|
||||
### Friendly urls through `.htaccess`
|
||||
###Friendly urls through `.htaccess`
|
||||
|
||||
Use `.htaccess`and rewrite rules (Apache) to get friendly image urls. Put `img.php` in the `/img` directory. Put the file `.htaccess` in the web root.
|
||||
|
||||
@@ -520,7 +524,7 @@ The result is good readable urls to your images. Its easy for the search engine
|
||||
|
||||
|
||||
|
||||
### Monitor cache size
|
||||
###Monitor cache size
|
||||
|
||||
There is a utility `cache.bash` included for monitoring the size of the cache-directory. It generates an output like this.
|
||||
|
||||
@@ -558,13 +562,13 @@ Use it as a base if you feel the need to monitor the size och the cache-director
|
||||
|
||||
|
||||
|
||||
### Read-only cache
|
||||
###Read-only cache
|
||||
|
||||
The cache directory need to be writable for `img.php` to create new files. But its possible to first create all cache-files and then set the directory to be read-only. This will give you a way of shutting of `img.php` from creating new cache files. `img.php` will then continue to work for all images having a cached version but will fail if someone tries to create a new, not previously cached, version of the image.
|
||||
|
||||
|
||||
|
||||
### Post-processing with external tools
|
||||
###Post-processing with external tools
|
||||
|
||||
You can use external tools to post-process the images to optimize the file size. This option is available for JPEG and for PNG images. Post-processing is disabled by default, edit `img_config.php` to enable it.
|
||||
|
||||
@@ -574,7 +578,7 @@ These tools for post processing is not a part of `CImage` and `img.php`, you nee
|
||||
|
||||
|
||||
|
||||
### Allowing remote download of images
|
||||
###Allowing remote download of images
|
||||
|
||||
You can allow `img.php` to download remote images. That can be enabled in the config-file. However, before doing so, consider the implications on allowing anyone to download a file, hopefully an image, to your server and then the possibility to access it through the webserver.
|
||||
|
||||
|
104
REVISION.md
@@ -1,100 +1,26 @@
|
||||
Revision history
|
||||
=====================================
|
||||
|
||||
<!--
|
||||
[](https://travis-ci.org/mosbth/cimage)
|
||||
[](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master)
|
||||
--->
|
||||
|
||||
v0.8.6 (2023-10-27)
|
||||
|
||||
v0.8.* (2015-12-05) (branch resize)
|
||||
-------------------------------------
|
||||
|
||||
* Fix deprecation notice on "Creation of dynamic property" for PHP 8.2.
|
||||
* 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.8.5 (2022-11-17)
|
||||
v0.7.9* (2015-12-07)
|
||||
-------------------------------------
|
||||
|
||||
* Enable configuration fix for solving Windows 2 WSL2 issue with is_readable/is_writable #189.
|
||||
* Update CHttpGet.php for php 8.1 deprecated notice #188.
|
||||
* Remove build status from README (since it is not up to date).
|
||||
* Fix strict mode only reporting 404 when failure, #127.
|
||||
|
||||
|
||||
|
||||
v0.8.4 (2022-05-30)
|
||||
v0.7.19* (2016-08-31)
|
||||
-------------------------------------
|
||||
|
||||
* Support PHP 8.1 and remove (more) deprecated messages when run in in development mode.
|
||||
|
||||
|
||||
|
||||
v0.8.3 (2022-05-24)
|
||||
-------------------------------------
|
||||
|
||||
* Support PHP 8.1 and remove deprecated messages when run in in development mode.
|
||||
* Generate prebuilt all include files for various settings
|
||||
* Fix deprecated for PHP 8.1
|
||||
* Fix deprecated for PHP 8.1
|
||||
* Add php version as output in verbose mode
|
||||
* Add PHP 81 as test environment
|
||||
|
||||
|
||||
|
||||
v0.8.2 (2021-10-27)
|
||||
-------------------------------------
|
||||
|
||||
* Remove bad configuration.
|
||||
|
||||
|
||||
|
||||
v0.8.1 (2020-06-08)
|
||||
-------------------------------------
|
||||
|
||||
* Updated version number in define.php.
|
||||
|
||||
|
||||
|
||||
v0.8.0 (2020-06-08)
|
||||
-------------------------------------
|
||||
|
||||
* Enable to set JPEG image as interlaced, implement feature #177.
|
||||
* Add function getValue() to read from querystring.
|
||||
* Set PHP 7.0 as precondition (to prepare to update the codebase).
|
||||
|
||||
|
||||
|
||||
v0.7.23 (2020-05-06)
|
||||
-------------------------------------
|
||||
|
||||
* Fix error in composer.json
|
||||
|
||||
|
||||
|
||||
v0.7.22 (2020-05-06)
|
||||
-------------------------------------
|
||||
|
||||
* Update composer.json and move ext-gd from required to suggested to ease installation where cli does not have all extensions installed.
|
||||
|
||||
|
||||
|
||||
v0.7.21 (2020-01-15)
|
||||
-------------------------------------
|
||||
|
||||
* Support PHP 7.4, some minor fixes with notices.
|
||||
|
||||
|
||||
v0.7.20 (2017-11-06)
|
||||
-------------------------------------
|
||||
|
||||
* Remove webroot/img/{round8.PNG,wider.JPEG,wider.JPG} to avoid unzip warning message when installing with composer.
|
||||
* Adding docker-compose.yml #169.
|
||||
|
||||
|
||||
v0.7.19 (2017-03-31)
|
||||
-------------------------------------
|
||||
|
||||
* Move exception handler from functions.php to img.php #166.
|
||||
* Correct XSS injection in `check_system.php`.
|
||||
* Composer suggests ext-imagick and ext-curl.
|
||||
|
||||
@@ -180,7 +106,7 @@ v0.7.8 (2015-12-06)
|
||||
|
||||
* HTTP error messages now 403, 404 and 500 as in #128 and #127.
|
||||
* More examples on dealing with cache through bash `bin/cache.bash`, #129.
|
||||
* Added conversion to sRGB using option `?srgb`. #120.
|
||||
* Added conversion to sRGB using option `?srgb`. #120.
|
||||
* Added Gitter badge to README, #126.
|
||||
* Fix proper download url in README, #125.
|
||||
* Change path in `webroot/htaccess` to make it work in current environment.
|
||||
@@ -191,11 +117,11 @@ v0.7.7 (2015-10-21)
|
||||
|
||||
* One can now add a HTTP header for Cache-Control in the config file, #109.
|
||||
* Added hook in img,php before CImage is called, #123.
|
||||
* Added configuration for default jpeg quality and png compression in the config file, #107.
|
||||
* Added configuration for default jpeg quality and png compression in the config file, #107.
|
||||
* Strip comments and whitespace in imgs.php, #115.
|
||||
* Bundle imgs.php did not have the correct mode.
|
||||
* Adding option &status to get an overview of the installed on configured utilities, #116.
|
||||
* Bug, all files saved as png-files, when not saving as specific file.
|
||||
* Bug, all files saved as png-files, when not saving as specific file.
|
||||
* Removed saving filename extension for alias images.
|
||||
* Added option to decide if resample or resize when copying images internally. `&no-resample` makes resize, instead of resample as is default.
|
||||
* Verbose now correctly states if transparent color is detected.
|
||||
@@ -250,14 +176,14 @@ v0.7.1 (2015-07-25)
|
||||
* Using `CWhitelist` for checking hotlinking to images, fix #88.
|
||||
* Added mode for `test` which enables logging verbose mode to file, fix #97.
|
||||
* Improved codestyle and added `phpcs.xml` to start using phpcs to check code style, fix #95.
|
||||
* Adding `composer.json` for publishing on packagist.
|
||||
* Adding `composer.json` for publishing on packagist.
|
||||
* Add permalink to setup for comparing images with `webroot/compare/compare.php`, fix #92.
|
||||
* Allow space in filename by using `urlencode()` and allow space as valid filenam character. fix #91.
|
||||
* Support redirections for remote images, fix #87, fix #90.
|
||||
* Support redirections for remote images, fix #87, fix #90.
|
||||
* Improving usage of Travis and Scrutinizer.
|
||||
* Naming cache-file using md5 for remote images, fix #86.
|
||||
* Loading images without depending on filename extension, fix #85.
|
||||
* Adding unittest with phpunit #84, fix #13
|
||||
* Adding unittest with phpunit #84, fix #13
|
||||
* Adding support for whitelist of remote hostnames, #84
|
||||
* Adding phpdoc, fix #48.
|
||||
* Adding travis, fix #15.
|
||||
|
@@ -1,6 +0,0 @@
|
||||
Security policy
|
||||
======================
|
||||
|
||||
To report security vulnerabilities in the project, send en email to mikael.t.h.roos@gmail.com.
|
||||
|
||||
For other security related issues, please open an issue on the project.
|
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,44 +1,39 @@
|
||||
{
|
||||
"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": ">=7.0"
|
||||
"php": ">=5.4",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "*",
|
||||
"ext-exif": "*",
|
||||
"ext-gd": "*",
|
||||
"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
@@ -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": []
|
||||
}
|
@@ -1,97 +0,0 @@
|
||||
version: "3"
|
||||
services:
|
||||
cli:
|
||||
image: anax/dev
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
apache:
|
||||
image: anax/dev:apache
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
ports: [ "11000:80" ]
|
||||
|
||||
remserver:
|
||||
image: anax/dev:apache
|
||||
ports:
|
||||
- "8090:80"
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php82:
|
||||
image: anax/dev:php82
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php82-apache:
|
||||
image: anax/dev:php82-apache
|
||||
ports: [ "11082:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php81:
|
||||
image: anax/dev:php81
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php81-apache:
|
||||
image: anax/dev:php81-apache
|
||||
ports: [ "11081:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php80:
|
||||
image: anax/dev:php80
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php80-apache:
|
||||
image: anax/dev:php80-apache
|
||||
ports: [ "11080:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php74:
|
||||
image: anax/dev:php74
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php74-apache:
|
||||
image: anax/dev:php74-apache
|
||||
ports: [ "11074:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php73:
|
||||
image: anax/dev:php73
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php73-apache:
|
||||
image: anax/dev:php73-apache
|
||||
ports: [ "11073:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php72:
|
||||
image: anax/dev:php72
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php72-apache:
|
||||
image: anax/dev:php72-apache
|
||||
ports: [ "11072:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php71:
|
||||
image: anax/dev:php71
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php71-apache:
|
||||
image: anax/dev:php71-apache
|
||||
ports: [ "11071:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php70:
|
||||
image: anax/dev:php70
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php70:
|
||||
image: anax/dev:php70-apache
|
||||
ports: [ "11070:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php56:
|
||||
image: anax/dev:php56
|
||||
volumes: [ ".:/home/anax/repo" ]
|
||||
|
||||
php56:
|
||||
image: anax/dev:php56-apache
|
||||
ports: [ "11056:80" ]
|
||||
volumes: [ ".:/home/anax/repo" ]
|
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
@@ -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
@@ -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
After Width: | Height: | Size: 334 B |
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
After Width: | Height: | Size: 392 B |
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
@@ -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
@@ -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.
|
||||
*
|
||||
@@ -51,15 +54,6 @@ class CCache
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($create && defined('WINDOWS2WSL')) {
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
||||
if (mkdir($path)) {
|
||||
return realpath($path);
|
||||
}
|
||||
}
|
||||
|
||||
if ($create && is_writable($this->path)) {
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
@@ -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.
|
||||
*
|
||||
@@ -215,7 +218,7 @@ class CHttpGet
|
||||
{
|
||||
$type = isset($this->response['header']['Content-Type'])
|
||||
? $this->response['header']['Content-Type']
|
||||
: '';
|
||||
: null;
|
||||
|
||||
return preg_match('#[a-z]+/[a-z]+#', $type)
|
||||
? $type
|
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Mos\CImage;
|
||||
|
||||
/**
|
||||
* Resize and crop images on the fly, store generated images in a cache.
|
||||
*
|
||||
@@ -6,7 +9,6 @@
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class CImage
|
||||
{
|
||||
|
||||
@@ -224,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;
|
||||
|
||||
|
||||
|
||||
@@ -355,6 +357,7 @@ class CImage
|
||||
/**
|
||||
* Used with option area to set which parts of the image to use.
|
||||
*/
|
||||
private $area;
|
||||
private $offset;
|
||||
|
||||
|
||||
@@ -424,22 +427,20 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Use interlaced progressive mode for JPEG images.
|
||||
*/
|
||||
private $interlace = false;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Image copy strategy, defaults to RESAMPLE.
|
||||
*/
|
||||
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.
|
||||
@@ -471,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.
|
||||
*
|
||||
@@ -680,9 +683,9 @@ class CImage
|
||||
*
|
||||
* @return string $extension as a normalized file extension.
|
||||
*/
|
||||
private function normalizeFileExtension($extension = "")
|
||||
private function normalizeFileExtension($extension = null)
|
||||
{
|
||||
$extension = strtolower($extension ? $extension : $this->extension ?? "");
|
||||
$extension = strtolower($extension ? $extension : $this->extension);
|
||||
|
||||
if ($extension == 'jpeg') {
|
||||
$extension = 'jpg';
|
||||
@@ -846,7 +849,6 @@ class CImage
|
||||
'blur' => null,
|
||||
'convolve' => null,
|
||||
'rotateAfter' => null,
|
||||
'interlace' => null,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => null,
|
||||
@@ -965,11 +967,8 @@ class CImage
|
||||
{
|
||||
$file = $file ? $file : $this->pathToImage;
|
||||
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
if (!defined('WINDOWS2WSL')) {
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
}
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
|
||||
$info = list($this->width, $this->height, $this->fileType) = getimagesize($file);
|
||||
if (empty($info)) {
|
||||
@@ -993,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());
|
||||
@@ -1024,76 +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
|
||||
&& $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
|
||||
&& $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;
|
||||
}
|
||||
@@ -1107,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}.");
|
||||
@@ -1195,7 +1163,7 @@ class CImage
|
||||
$this->newWidth = $width;
|
||||
$this->newHeight = $height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get image dimensions for pre-resize image.
|
||||
if ($this->cropToFit || $this->fillToFit) {
|
||||
@@ -1234,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;
|
||||
}
|
||||
|
||||
@@ -1258,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;
|
||||
@@ -1405,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;
|
||||
@@ -1414,7 +1380,6 @@ class CImage
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
$interlace = $this->interlace ? "_i" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -1474,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 . $lossy . $interlace . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -1524,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.
|
||||
@@ -1625,7 +1589,6 @@ class CImage
|
||||
}
|
||||
|
||||
switch ($pngType) {
|
||||
|
||||
case self::PNG_GREYSCALE:
|
||||
$text = "PNG is type 0, Greyscale$transparent";
|
||||
break;
|
||||
@@ -1731,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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1746,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 {
|
||||
@@ -1764,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']);
|
||||
@@ -1780,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']);
|
||||
@@ -1797,7 +1781,6 @@ class CImage
|
||||
}
|
||||
|
||||
if ($this->cropToFit) {
|
||||
|
||||
// Resize by crop to fit
|
||||
$this->log("Resizing using strategy - Crop to fit");
|
||||
|
||||
@@ -1837,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");
|
||||
|
||||
@@ -1870,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);
|
||||
@@ -1887,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");
|
||||
|
||||
@@ -1954,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;
|
||||
@@ -2304,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'];
|
||||
@@ -2317,7 +2301,6 @@ class CImage
|
||||
}
|
||||
|
||||
return $color;
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -2345,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.");
|
||||
@@ -2444,23 +2424,14 @@ class CImage
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined("WINDOWS2WSL")) {
|
||||
is_writable($this->saveFolder)
|
||||
is_writable($this->saveFolder)
|
||||
or $this->raiseError('Target directory is not writable.');
|
||||
}
|
||||
|
||||
$type = $this->getTargetImageExtension();
|
||||
$this->Log("Saving image as " . $type);
|
||||
switch($type) {
|
||||
|
||||
switch ($type) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
// Set as interlaced progressive JPEG
|
||||
if ($this->interlace) {
|
||||
$this->Log("Set JPEG image to be interlaced.");
|
||||
$res = imageinterlace($this->image, true);
|
||||
}
|
||||
|
||||
$this->Log("Saving image as JPEG to cache using quality = {$this->quality}.");
|
||||
imagejpeg($this->image, $this->cacheFileName, $this->quality);
|
||||
|
||||
@@ -2578,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;
|
||||
}
|
||||
@@ -2599,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);
|
||||
|
||||
@@ -2610,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;
|
||||
}
|
||||
@@ -2730,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();
|
||||
@@ -2741,9 +2711,7 @@ class CImage
|
||||
if (CIMAGE_DEBUG) {
|
||||
trace(__CLASS__ . " 304");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$this->loadImageDetails($file);
|
||||
$mime = $this->getMimeType();
|
||||
$size = filesize($file);
|
||||
@@ -2799,18 +2767,18 @@ class CImage
|
||||
$lastModified = filemtime($this->pathToImage);
|
||||
$details['srcGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$details['cache'] = basename($this->cacheFileName ?? "");
|
||||
$lastModified = filemtime($this->cacheFileName ?? "");
|
||||
$details['cache'] = basename($this->cacheFileName);
|
||||
$lastModified = filemtime($this->cacheFileName);
|
||||
$details['cacheGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$this->load($file);
|
||||
|
||||
$details['filename'] = basename($file ?? "");
|
||||
$details['filename'] = basename($file);
|
||||
$details['mimeType'] = $this->getMimeType($this->fileType);
|
||||
$details['width'] = $this->width;
|
||||
$details['height'] = $this->height;
|
||||
$details['aspectRatio'] = round($this->width / $this->height, 3);
|
||||
$details['size'] = filesize($file ?? "");
|
||||
$details['size'] = filesize($file);
|
||||
$details['colors'] = $this->colorsTotal($this->image);
|
||||
$details['includedFiles'] = count(get_included_files());
|
||||
$details['memoryPeek'] = round(memory_get_peak_usage()/1024/1024, 3) . " MB" ;
|
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
@@ -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.8.6 (2023-10-27)");
|
||||
define("CIMAGE_VERSION", "v0.7.19* (2016-08-11)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
@@ -107,25 +107,6 @@ function getDefined($key, $defined, $undefined)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value of input from query string or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $undefined value to return when $key has no, or empty value in $_GET.
|
||||
*
|
||||
* @return mixed value as or $undefined.
|
||||
*/
|
||||
function getValue($key, $undefined)
|
||||
{
|
||||
$val = get($key);
|
||||
if (is_null($val) || $val === "") {
|
||||
return $undefined;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
@@ -151,7 +132,7 @@ function getConfig($key, $default)
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null, $arg = "")
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
@@ -164,15 +145,7 @@ function verbose($msg = null, $arg = "")
|
||||
return $log;
|
||||
}
|
||||
|
||||
if (is_null($arg)) {
|
||||
$arg = "null";
|
||||
} elseif ($arg === false) {
|
||||
$arg = "false";
|
||||
} elseif ($arg === true) {
|
||||
$arg = "true";
|
||||
}
|
||||
|
||||
$log[] = $msg . $arg;
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@
|
||||
[]
|
@@ -3,12 +3,6 @@
|
||||
<head>
|
||||
<style>
|
||||
|
||||
<?php
|
||||
function e($str) {
|
||||
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
?>
|
||||
|
||||
body {
|
||||
}
|
||||
|
||||
@@ -134,15 +128,15 @@ if (isset($_GET['input1'])) {
|
||||
// Use incoming from querystring as defaults
|
||||
?>
|
||||
CImage.compare({
|
||||
"input1": "<?=e($_GET['input1'])?>",
|
||||
"input2": "<?=e($_GET['input2'])?>",
|
||||
"input3": "<?=e($_GET['input3'])?>",
|
||||
"input4": "<?=e($_GET['input4'])?>",
|
||||
"input5": "<?=e($_GET['input5'])?>",
|
||||
"input6": "<?=e($_GET['input6'])?>",
|
||||
"json": <?=e($_GET['json'])?>,
|
||||
"stack": <?=e($_GET['stack'])?>,
|
||||
"bg": <?=e($_GET['bg'])?>
|
||||
"input1": "<?=$_GET['input1']?>",
|
||||
"input2": "<?=$_GET['input2']?>",
|
||||
"input3": "<?=$_GET['input3']?>",
|
||||
"input4": "<?=$_GET['input4']?>",
|
||||
"input5": "<?=$_GET['input5']?>",
|
||||
"input6": "<?=$_GET['input6']?>",
|
||||
"json": <?=$_GET['json']?>,
|
||||
"stack": <?=$_GET['stack']?>,
|
||||
"bg": <?=$_GET['bg']?>
|
||||
});
|
||||
<?php
|
||||
} elseif (isset($script)) {
|
||||
|
@@ -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.
|
||||
#
|
||||
|
@@ -89,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);
|
||||
}
|
||||
@@ -186,7 +178,7 @@ $hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
|
||||
$refererHost = parse_url($referer ?? "", PHP_URL_HOST);
|
||||
$refererHost = parse_url($referer, PHP_URL_HOST);
|
||||
|
||||
if (!$allowHotlinking) {
|
||||
if ($passwordMatch) {
|
||||
@@ -208,7 +200,6 @@ if (!$allowHotlinking) {
|
||||
} else {
|
||||
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.", 403);
|
||||
}
|
||||
|
||||
} else {
|
||||
errorPage("Hotlinking/leeching not allowed.", 403);
|
||||
}
|
||||
@@ -223,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);
|
||||
|
||||
@@ -232,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);
|
||||
@@ -254,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)
|
||||
@@ -285,7 +276,7 @@ $allowRemote = getConfig('remote_allow', false);
|
||||
|
||||
if ($allowRemote && $passwordMatch !== false) {
|
||||
$cacheRemote = $cache->getPathToSubdir("remote");
|
||||
|
||||
|
||||
$pattern = getConfig('remote_pattern', null);
|
||||
$img->setRemoteDownload($allowRemote, $cacheRemote, $pattern);
|
||||
|
||||
@@ -307,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);
|
||||
@@ -319,11 +310,11 @@ if (isset($shortcut)
|
||||
/**
|
||||
* src - the source image file.
|
||||
*/
|
||||
$srcImage = urldecode(get('src', ""))
|
||||
$srcImage = urldecode(get('src'))
|
||||
or errorPage('Must set src-attribute.', 404);
|
||||
|
||||
// Get settings for src-alt as backup image
|
||||
$srcAltImage = urldecode(get('src-alt', ""));
|
||||
$srcAltImage = urldecode(get('src-alt', null));
|
||||
$srcAltConfig = getConfig('src_alt', null);
|
||||
if (empty($srcAltImage)) {
|
||||
$srcAltImage = $srcAltConfig;
|
||||
@@ -346,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);
|
||||
|
||||
@@ -440,7 +426,7 @@ if (isset($sizes[$newWidth])) {
|
||||
}
|
||||
|
||||
// Support width as % of original width
|
||||
if ($newWidth && $newWidth[strlen($newWidth)-1] == '%') {
|
||||
if ($newWidth[strlen($newWidth)-1] == '%') {
|
||||
is_numeric(substr($newWidth, 0, -1))
|
||||
or errorPage('Width % not numeric.', 404);
|
||||
} else {
|
||||
@@ -465,7 +451,7 @@ if (isset($sizes[$newHeight])) {
|
||||
}
|
||||
|
||||
// height
|
||||
if ($newHeight && $newHeight[strlen($newHeight)-1] == '%') {
|
||||
if ($newHeight[strlen($newHeight)-1] == '%') {
|
||||
is_numeric(substr($newHeight, 0, -1))
|
||||
or errorPage('Height % out of range.', 404);
|
||||
} else {
|
||||
@@ -496,7 +482,7 @@ $aspectRatioConstant = getConfig('aspect_ratio_constant', function () {
|
||||
|
||||
// Check to replace predefined aspect ratio
|
||||
$aspectRatios = call_user_func($aspectRatioConstant);
|
||||
$negateAspectRatio = ($aspectRatio && $aspectRatio[0] == '!') ? true : false;
|
||||
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
|
||||
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
|
||||
|
||||
if (isset($aspectRatios[$aspectRatio])) {
|
||||
@@ -920,18 +906,6 @@ if ($cacheControl) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* interlace - Enable configuration for interlaced progressive JPEG images.
|
||||
*/
|
||||
$interlaceConfig = getConfig('interlace', null);
|
||||
$interlaceValue = getValue('interlace', null);
|
||||
$interlaceDefined = getDefined('interlace', true, null);
|
||||
$interlace = $interlaceValue ?? $interlaceDefined ?? $interlaceConfig;
|
||||
verbose("interlace (configfile) = ", $interlaceConfig);
|
||||
verbose("interlace = ", $interlace);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a dummy image and use it as source image.
|
||||
*/
|
||||
@@ -1093,7 +1067,6 @@ if (is_callable($hookBeforeCImage)) {
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
@@ -1149,8 +1122,7 @@ EOD;
|
||||
/**
|
||||
* Load, process and output the image
|
||||
*/
|
||||
$img->log("PHP version: " . phpversion())
|
||||
->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
$res = $img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->setSaveFolder($cachePath)
|
||||
->useCache($useCache)
|
||||
->setSource($srcImage, $imagePath)
|
||||
@@ -1183,7 +1155,6 @@ $img->log("PHP version: " . phpversion())
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
@@ -1210,3 +1181,5 @@ $img->log("PHP version: " . phpversion())
|
||||
->save()
|
||||
->linkToCacheFile($aliasTarget)
|
||||
->output();
|
||||
|
||||
return $res;
|
||||
|
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/round8.PNG
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
webroot/img/test_100x100.png
Normal file
After Width: | Height: | Size: 445 B |
BIN
webroot/img/tower.jpg
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
webroot/img/wider.JPEG
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
webroot/img/wider.JPG
Normal file
After Width: | Height: | Size: 70 KiB |
@@ -21,18 +21,9 @@ if (!defined("CIMAGE_DEBUG")) {
|
||||
define("CIMAGE_DEBUG_FILE", "/tmp/cimage");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this if you work with a webserver in Windows and try to access files
|
||||
* within WSL2.
|
||||
* The issue seems to be with functions like `is_writable()` and
|
||||
* `is_readable()`.
|
||||
* When WINDOWS2WSL is defined (to any value) it ignores these functions.
|
||||
*/
|
||||
#define('WINDOWS2WSL', 1);
|
||||
|
||||
|
||||
|
||||
return array(
|
||||
return [
|
||||
|
||||
/**
|
||||
* Set mode as 'strict', 'production' or 'development'.
|
||||
@@ -61,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:
|
||||
@@ -76,7 +69,7 @@ return array(
|
||||
*/
|
||||
'image_path' => __DIR__ . '/img/',
|
||||
'cache_path' => __DIR__ . '/../cache/',
|
||||
'alias_path' => __DIR__ . '/img/alias/',
|
||||
//'alias_path' => __DIR__ . '/img/alias/',
|
||||
|
||||
|
||||
|
||||
@@ -98,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',
|
||||
|
||||
|
||||
|
||||
@@ -125,7 +118,7 @@ return array(
|
||||
* password_type: 'text' // use plain password, not encoded,
|
||||
*/
|
||||
//'password_always' => false, // always require password,
|
||||
//'password' => "moped", // "secret-password",
|
||||
//'password' => false, // "secret-password",
|
||||
//'password_type' => 'text', // supports 'text', 'md5', 'hash',
|
||||
|
||||
|
||||
@@ -150,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$'
|
||||
], */
|
||||
|
||||
|
||||
|
||||
@@ -191,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.
|
||||
*
|
||||
@@ -350,7 +346,7 @@ return array(
|
||||
* jpeg_optimize_cmd: '/usr/local/bin/jpegtran -copy none -optimize'
|
||||
*/
|
||||
/*
|
||||
'postprocessing' => array(
|
||||
'postprocessing' => [
|
||||
'png_lossy' => null,
|
||||
'png_lossy_cmd' => '/usr/local/bin/pngquant --force --output',
|
||||
|
||||
@@ -362,7 +358,7 @@ return array(
|
||||
|
||||
'jpeg_optimize' => false,
|
||||
'jpeg_optimize_cmd' => '/usr/local/bin/jpegtran -copy none -optimize',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -372,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',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -395,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$',
|
||||
),
|
||||
],
|
||||
*/
|
||||
|
||||
|
||||
@@ -409,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",
|
||||
),*/
|
||||
],*/
|
||||
|
||||
|
||||
|
||||
@@ -439,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;
|
||||
@@ -465,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,
|
||||
@@ -473,7 +469,7 @@ return array(
|
||||
'16:10' => 16/10,
|
||||
'16:9' => 16/9,
|
||||
'golden' => 1.618,
|
||||
);
|
||||
];
|
||||
},*/
|
||||
|
||||
|
||||
@@ -489,23 +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,
|
||||
), */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Default options for creating interlaced progressive JPEG images. Set
|
||||
* to true to always render jpeg images as interlaced. This setting can
|
||||
* be overridden by using `?interlace`, `?interlace=true` or
|
||||
* `?interlace=false`.
|
||||
*
|
||||
* Default values are:
|
||||
* interlace: false
|
||||
*/
|
||||
/*'interlace' => false,*/
|
||||
);
|
||||
);
|
||||
],*/
|
||||
];
|
||||
|
162
webroot/imgd.php
@@ -38,7 +38,7 @@ $config = array(
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.8.6 (2023-10-27)");
|
||||
define("CIMAGE_VERSION", "v0.7.18 (2016-08-09)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
@@ -118,6 +118,22 @@ 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.
|
||||
*
|
||||
@@ -158,25 +174,6 @@ function getDefined($key, $defined, $undefined)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value of input from query string or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $undefined value to return when $key has no, or empty value in $_GET.
|
||||
*
|
||||
* @return mixed value as or $undefined.
|
||||
*/
|
||||
function getValue($key, $undefined)
|
||||
{
|
||||
$val = get($key);
|
||||
if (is_null($val) || $val === "") {
|
||||
return $undefined;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
@@ -202,7 +199,7 @@ function getConfig($key, $default)
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null, $arg = "")
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
@@ -215,15 +212,7 @@ function verbose($msg = null, $arg = "")
|
||||
return $log;
|
||||
}
|
||||
|
||||
if (is_null($arg)) {
|
||||
$arg = "null";
|
||||
} elseif ($arg === false) {
|
||||
$arg = "false";
|
||||
} elseif ($arg === true) {
|
||||
$arg = "true";
|
||||
}
|
||||
|
||||
$log[] = $msg . $arg;
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -465,7 +454,7 @@ class CHttpGet
|
||||
{
|
||||
$type = isset($this->response['header']['Content-Type'])
|
||||
? $this->response['header']['Content-Type']
|
||||
: '';
|
||||
: null;
|
||||
|
||||
return preg_match('#[a-z]+/[a-z]+#', $type)
|
||||
? $type
|
||||
@@ -1143,7 +1132,6 @@ class CAsciiArt
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class CImage
|
||||
{
|
||||
|
||||
@@ -1561,13 +1549,6 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Use interlaced progressive mode for JPEG images.
|
||||
*/
|
||||
private $interlace = false;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Image copy strategy, defaults to RESAMPLE.
|
||||
*/
|
||||
@@ -1817,9 +1798,9 @@ class CImage
|
||||
*
|
||||
* @return string $extension as a normalized file extension.
|
||||
*/
|
||||
private function normalizeFileExtension($extension = "")
|
||||
private function normalizeFileExtension($extension = null)
|
||||
{
|
||||
$extension = strtolower($extension ? $extension : $this->extension ?? "");
|
||||
$extension = strtolower($extension ? $extension : $this->extension);
|
||||
|
||||
if ($extension == 'jpeg') {
|
||||
$extension = 'jpg';
|
||||
@@ -1983,7 +1964,6 @@ class CImage
|
||||
'blur' => null,
|
||||
'convolve' => null,
|
||||
'rotateAfter' => null,
|
||||
'interlace' => null,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => null,
|
||||
@@ -2102,11 +2082,8 @@ class CImage
|
||||
{
|
||||
$file = $file ? $file : $this->pathToImage;
|
||||
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
if (!defined('WINDOWS2WSL')) {
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
}
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
|
||||
$info = list($this->width, $this->height, $this->fileType) = getimagesize($file);
|
||||
if (empty($info)) {
|
||||
@@ -2172,15 +2149,13 @@ class CImage
|
||||
$this->log("Init dimension (before) newWidth x newHeight is {$this->newWidth} x {$this->newHeight}.");
|
||||
|
||||
// width as %
|
||||
if ($this->newWidth
|
||||
&& $this->newWidth[strlen($this->newWidth)-1] == '%') {
|
||||
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
|
||||
&& $this->newHeight[strlen($this->newHeight)-1] == '%') {
|
||||
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}");
|
||||
}
|
||||
@@ -2332,7 +2307,7 @@ class CImage
|
||||
$this->newWidth = $width;
|
||||
$this->newHeight = $height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get image dimensions for pre-resize image.
|
||||
if ($this->cropToFit || $this->fillToFit) {
|
||||
@@ -2551,7 +2526,6 @@ class CImage
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
$interlace = $this->interlace ? "_i" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -2618,7 +2592,7 @@ class CImage
|
||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette
|
||||
. $optimize . $compress
|
||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
|
||||
. $convolve . $copyStrat . $lossy . $interlace . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -2938,7 +2912,7 @@ class CImage
|
||||
// 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.");
|
||||
|
||||
@@ -3517,7 +3491,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'];
|
||||
@@ -3581,10 +3555,8 @@ class CImage
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined("WINDOWS2WSL")) {
|
||||
is_writable($this->saveFolder)
|
||||
is_writable($this->saveFolder)
|
||||
or $this->raiseError('Target directory is not writable.');
|
||||
}
|
||||
|
||||
$type = $this->getTargetImageExtension();
|
||||
$this->Log("Saving image as " . $type);
|
||||
@@ -3592,12 +3564,6 @@ class CImage
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
// Set as interlaced progressive JPEG
|
||||
if ($this->interlace) {
|
||||
$this->Log("Set JPEG image to be interlaced.");
|
||||
$res = imageinterlace($this->image, true);
|
||||
}
|
||||
|
||||
$this->Log("Saving image as JPEG to cache using quality = {$this->quality}.");
|
||||
imagejpeg($this->image, $this->cacheFileName, $this->quality);
|
||||
|
||||
@@ -3936,18 +3902,18 @@ class CImage
|
||||
$lastModified = filemtime($this->pathToImage);
|
||||
$details['srcGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$details['cache'] = basename($this->cacheFileName ?? "");
|
||||
$lastModified = filemtime($this->cacheFileName ?? "");
|
||||
$details['cache'] = basename($this->cacheFileName);
|
||||
$lastModified = filemtime($this->cacheFileName);
|
||||
$details['cacheGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$this->load($file);
|
||||
|
||||
$details['filename'] = basename($file ?? "");
|
||||
$details['filename'] = basename($file);
|
||||
$details['mimeType'] = $this->getMimeType($this->fileType);
|
||||
$details['width'] = $this->width;
|
||||
$details['height'] = $this->height;
|
||||
$details['aspectRatio'] = round($this->width / $this->height, 3);
|
||||
$details['size'] = filesize($file ?? "");
|
||||
$details['size'] = filesize($file);
|
||||
$details['colors'] = $this->colorsTotal($this->image);
|
||||
$details['includedFiles'] = count(get_included_files());
|
||||
$details['memoryPeek'] = round(memory_get_peak_usage()/1024/1024, 3) . " MB" ;
|
||||
@@ -4146,15 +4112,6 @@ class CCache
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($create && defined('WINDOWS2WSL')) {
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
||||
if (mkdir($path)) {
|
||||
return realpath($path);
|
||||
}
|
||||
}
|
||||
|
||||
if ($create && is_writable($this->path)) {
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
||||
@@ -4461,22 +4418,6 @@ class CFastTrackCache
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -4639,7 +4580,7 @@ $hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
|
||||
$refererHost = parse_url($referer ?? "", PHP_URL_HOST);
|
||||
$refererHost = parse_url($referer, PHP_URL_HOST);
|
||||
|
||||
if (!$allowHotlinking) {
|
||||
if ($passwordMatch) {
|
||||
@@ -4738,7 +4679,7 @@ $allowRemote = getConfig('remote_allow', false);
|
||||
|
||||
if ($allowRemote && $passwordMatch !== false) {
|
||||
$cacheRemote = $cache->getPathToSubdir("remote");
|
||||
|
||||
|
||||
$pattern = getConfig('remote_pattern', null);
|
||||
$img->setRemoteDownload($allowRemote, $cacheRemote, $pattern);
|
||||
|
||||
@@ -4772,11 +4713,11 @@ if (isset($shortcut)
|
||||
/**
|
||||
* src - the source image file.
|
||||
*/
|
||||
$srcImage = urldecode(get('src', ""))
|
||||
$srcImage = urldecode(get('src'))
|
||||
or errorPage('Must set src-attribute.', 404);
|
||||
|
||||
// Get settings for src-alt as backup image
|
||||
$srcAltImage = urldecode(get('src-alt', ""));
|
||||
$srcAltImage = urldecode(get('src-alt', null));
|
||||
$srcAltConfig = getConfig('src_alt', null);
|
||||
if (empty($srcAltImage)) {
|
||||
$srcAltImage = $srcAltConfig;
|
||||
@@ -4834,7 +4775,7 @@ if ($dummyEnabled && $srcImage === $dummyFilename) {
|
||||
matching file exists on the filesystem.',
|
||||
404
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($imagePathConstraint && !$dummyImage && !$remoteSource) {
|
||||
@@ -4893,7 +4834,7 @@ if (isset($sizes[$newWidth])) {
|
||||
}
|
||||
|
||||
// Support width as % of original width
|
||||
if ($newWidth && $newWidth[strlen($newWidth)-1] == '%') {
|
||||
if ($newWidth[strlen($newWidth)-1] == '%') {
|
||||
is_numeric(substr($newWidth, 0, -1))
|
||||
or errorPage('Width % not numeric.', 404);
|
||||
} else {
|
||||
@@ -4918,7 +4859,7 @@ if (isset($sizes[$newHeight])) {
|
||||
}
|
||||
|
||||
// height
|
||||
if ($newHeight && $newHeight[strlen($newHeight)-1] == '%') {
|
||||
if ($newHeight[strlen($newHeight)-1] == '%') {
|
||||
is_numeric(substr($newHeight, 0, -1))
|
||||
or errorPage('Height % out of range.', 404);
|
||||
} else {
|
||||
@@ -4949,7 +4890,7 @@ $aspectRatioConstant = getConfig('aspect_ratio_constant', function () {
|
||||
|
||||
// Check to replace predefined aspect ratio
|
||||
$aspectRatios = call_user_func($aspectRatioConstant);
|
||||
$negateAspectRatio = ($aspectRatio && $aspectRatio[0] == '!') ? true : false;
|
||||
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
|
||||
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
|
||||
|
||||
if (isset($aspectRatios[$aspectRatio])) {
|
||||
@@ -5373,18 +5314,6 @@ if ($cacheControl) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* interlace - Enable configuration for interlaced progressive JPEG images.
|
||||
*/
|
||||
$interlaceConfig = getConfig('interlace', null);
|
||||
$interlaceValue = getValue('interlace', null);
|
||||
$interlaceDefined = getDefined('interlace', true, null);
|
||||
$interlace = $interlaceValue ?? $interlaceDefined ?? $interlaceConfig;
|
||||
verbose("interlace (configfile) = ", $interlaceConfig);
|
||||
verbose("interlace = ", $interlace);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a dummy image and use it as source image.
|
||||
*/
|
||||
@@ -5546,7 +5475,6 @@ if (is_callable($hookBeforeCImage)) {
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
@@ -5602,8 +5530,7 @@ EOD;
|
||||
/**
|
||||
* Load, process and output the image
|
||||
*/
|
||||
$img->log("PHP version: " . phpversion())
|
||||
->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->setSaveFolder($cachePath)
|
||||
->useCache($useCache)
|
||||
->setSource($srcImage, $imagePath)
|
||||
@@ -5636,7 +5563,6 @@ $img->log("PHP version: " . phpversion())
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
|
162
webroot/imgp.php
@@ -38,7 +38,7 @@ $config = array(
|
||||
|
||||
|
||||
// Version of cimage and img.php
|
||||
define("CIMAGE_VERSION", "v0.8.6 (2023-10-27)");
|
||||
define("CIMAGE_VERSION", "v0.7.18 (2016-08-09)");
|
||||
|
||||
// For CRemoteImage
|
||||
define("CIMAGE_USER_AGENT", "CImage/" . CIMAGE_VERSION);
|
||||
@@ -118,6 +118,22 @@ 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.
|
||||
*
|
||||
@@ -158,25 +174,6 @@ function getDefined($key, $defined, $undefined)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value of input from query string or else $undefined.
|
||||
*
|
||||
* @param mixed $key as string or array of string values to look for in $_GET.
|
||||
* @param mixed $undefined value to return when $key has no, or empty value in $_GET.
|
||||
*
|
||||
* @return mixed value as or $undefined.
|
||||
*/
|
||||
function getValue($key, $undefined)
|
||||
{
|
||||
$val = get($key);
|
||||
if (is_null($val) || $val === "") {
|
||||
return $undefined;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get value from config array or default if key is not set in config array.
|
||||
*
|
||||
@@ -202,7 +199,7 @@ function getConfig($key, $default)
|
||||
*
|
||||
* @return void or array.
|
||||
*/
|
||||
function verbose($msg = null, $arg = "")
|
||||
function verbose($msg = null)
|
||||
{
|
||||
global $verbose, $verboseFile;
|
||||
static $log = array();
|
||||
@@ -215,15 +212,7 @@ function verbose($msg = null, $arg = "")
|
||||
return $log;
|
||||
}
|
||||
|
||||
if (is_null($arg)) {
|
||||
$arg = "null";
|
||||
} elseif ($arg === false) {
|
||||
$arg = "false";
|
||||
} elseif ($arg === true) {
|
||||
$arg = "true";
|
||||
}
|
||||
|
||||
$log[] = $msg . $arg;
|
||||
$log[] = $msg;
|
||||
}
|
||||
|
||||
|
||||
@@ -465,7 +454,7 @@ class CHttpGet
|
||||
{
|
||||
$type = isset($this->response['header']['Content-Type'])
|
||||
? $this->response['header']['Content-Type']
|
||||
: '';
|
||||
: null;
|
||||
|
||||
return preg_match('#[a-z]+/[a-z]+#', $type)
|
||||
? $type
|
||||
@@ -1143,7 +1132,6 @@ class CAsciiArt
|
||||
* @example http://dbwebb.se/opensource/cimage
|
||||
* @link https://github.com/mosbth/cimage
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class CImage
|
||||
{
|
||||
|
||||
@@ -1561,13 +1549,6 @@ class CImage
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Use interlaced progressive mode for JPEG images.
|
||||
*/
|
||||
private $interlace = false;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Image copy strategy, defaults to RESAMPLE.
|
||||
*/
|
||||
@@ -1817,9 +1798,9 @@ class CImage
|
||||
*
|
||||
* @return string $extension as a normalized file extension.
|
||||
*/
|
||||
private function normalizeFileExtension($extension = "")
|
||||
private function normalizeFileExtension($extension = null)
|
||||
{
|
||||
$extension = strtolower($extension ? $extension : $this->extension ?? "");
|
||||
$extension = strtolower($extension ? $extension : $this->extension);
|
||||
|
||||
if ($extension == 'jpeg') {
|
||||
$extension = 'jpg';
|
||||
@@ -1983,7 +1964,6 @@ class CImage
|
||||
'blur' => null,
|
||||
'convolve' => null,
|
||||
'rotateAfter' => null,
|
||||
'interlace' => null,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => null,
|
||||
@@ -2102,11 +2082,8 @@ class CImage
|
||||
{
|
||||
$file = $file ? $file : $this->pathToImage;
|
||||
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
if (!defined('WINDOWS2WSL')) {
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
}
|
||||
is_readable($file)
|
||||
or $this->raiseError('Image file does not exist.');
|
||||
|
||||
$info = list($this->width, $this->height, $this->fileType) = getimagesize($file);
|
||||
if (empty($info)) {
|
||||
@@ -2172,15 +2149,13 @@ class CImage
|
||||
$this->log("Init dimension (before) newWidth x newHeight is {$this->newWidth} x {$this->newHeight}.");
|
||||
|
||||
// width as %
|
||||
if ($this->newWidth
|
||||
&& $this->newWidth[strlen($this->newWidth)-1] == '%') {
|
||||
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
|
||||
&& $this->newHeight[strlen($this->newHeight)-1] == '%') {
|
||||
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}");
|
||||
}
|
||||
@@ -2332,7 +2307,7 @@ class CImage
|
||||
$this->newWidth = $width;
|
||||
$this->newHeight = $height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get image dimensions for pre-resize image.
|
||||
if ($this->cropToFit || $this->fillToFit) {
|
||||
@@ -2551,7 +2526,6 @@ class CImage
|
||||
$rotateBefore = $this->rotateBefore ? "_rb{$this->rotateBefore}" : null;
|
||||
$rotateAfter = $this->rotateAfter ? "_ra{$this->rotateAfter}" : null;
|
||||
$lossy = $this->lossy ? "_l" : null;
|
||||
$interlace = $this->interlace ? "_i" : null;
|
||||
|
||||
$saveAs = $this->normalizeFileExtension();
|
||||
$saveAs = $saveAs ? "_$saveAs" : null;
|
||||
@@ -2618,7 +2592,7 @@ class CImage
|
||||
. $quality . $filters . $sharpen . $emboss . $blur . $palette
|
||||
. $optimize . $compress
|
||||
. $scale . $rotateBefore . $rotateAfter . $autoRotate . $bgColor
|
||||
. $convolve . $copyStrat . $lossy . $interlace . $saveAs;
|
||||
. $convolve . $copyStrat . $lossy . $saveAs;
|
||||
|
||||
return $this->setTarget($file, $base);
|
||||
}
|
||||
@@ -2938,7 +2912,7 @@ class CImage
|
||||
// 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.");
|
||||
|
||||
@@ -3517,7 +3491,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'];
|
||||
@@ -3581,10 +3555,8 @@ class CImage
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined("WINDOWS2WSL")) {
|
||||
is_writable($this->saveFolder)
|
||||
is_writable($this->saveFolder)
|
||||
or $this->raiseError('Target directory is not writable.');
|
||||
}
|
||||
|
||||
$type = $this->getTargetImageExtension();
|
||||
$this->Log("Saving image as " . $type);
|
||||
@@ -3592,12 +3564,6 @@ class CImage
|
||||
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
// Set as interlaced progressive JPEG
|
||||
if ($this->interlace) {
|
||||
$this->Log("Set JPEG image to be interlaced.");
|
||||
$res = imageinterlace($this->image, true);
|
||||
}
|
||||
|
||||
$this->Log("Saving image as JPEG to cache using quality = {$this->quality}.");
|
||||
imagejpeg($this->image, $this->cacheFileName, $this->quality);
|
||||
|
||||
@@ -3936,18 +3902,18 @@ class CImage
|
||||
$lastModified = filemtime($this->pathToImage);
|
||||
$details['srcGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$details['cache'] = basename($this->cacheFileName ?? "");
|
||||
$lastModified = filemtime($this->cacheFileName ?? "");
|
||||
$details['cache'] = basename($this->cacheFileName);
|
||||
$lastModified = filemtime($this->cacheFileName);
|
||||
$details['cacheGmdate'] = gmdate("D, d M Y H:i:s", $lastModified);
|
||||
|
||||
$this->load($file);
|
||||
|
||||
$details['filename'] = basename($file ?? "");
|
||||
$details['filename'] = basename($file);
|
||||
$details['mimeType'] = $this->getMimeType($this->fileType);
|
||||
$details['width'] = $this->width;
|
||||
$details['height'] = $this->height;
|
||||
$details['aspectRatio'] = round($this->width / $this->height, 3);
|
||||
$details['size'] = filesize($file ?? "");
|
||||
$details['size'] = filesize($file);
|
||||
$details['colors'] = $this->colorsTotal($this->image);
|
||||
$details['includedFiles'] = count(get_included_files());
|
||||
$details['memoryPeek'] = round(memory_get_peak_usage()/1024/1024, 3) . " MB" ;
|
||||
@@ -4146,15 +4112,6 @@ class CCache
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($create && defined('WINDOWS2WSL')) {
|
||||
// Special case to solve Windows 2 WSL integration
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
||||
if (mkdir($path)) {
|
||||
return realpath($path);
|
||||
}
|
||||
}
|
||||
|
||||
if ($create && is_writable($this->path)) {
|
||||
$path = $this->path . "/" . $subdir;
|
||||
|
||||
@@ -4461,22 +4418,6 @@ class CFastTrackCache
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -4639,7 +4580,7 @@ $hotlinkingWhitelist = getConfig('hotlinking_whitelist', array());
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
|
||||
$refererHost = parse_url($referer ?? "", PHP_URL_HOST);
|
||||
$refererHost = parse_url($referer, PHP_URL_HOST);
|
||||
|
||||
if (!$allowHotlinking) {
|
||||
if ($passwordMatch) {
|
||||
@@ -4738,7 +4679,7 @@ $allowRemote = getConfig('remote_allow', false);
|
||||
|
||||
if ($allowRemote && $passwordMatch !== false) {
|
||||
$cacheRemote = $cache->getPathToSubdir("remote");
|
||||
|
||||
|
||||
$pattern = getConfig('remote_pattern', null);
|
||||
$img->setRemoteDownload($allowRemote, $cacheRemote, $pattern);
|
||||
|
||||
@@ -4772,11 +4713,11 @@ if (isset($shortcut)
|
||||
/**
|
||||
* src - the source image file.
|
||||
*/
|
||||
$srcImage = urldecode(get('src', ""))
|
||||
$srcImage = urldecode(get('src'))
|
||||
or errorPage('Must set src-attribute.', 404);
|
||||
|
||||
// Get settings for src-alt as backup image
|
||||
$srcAltImage = urldecode(get('src-alt', ""));
|
||||
$srcAltImage = urldecode(get('src-alt', null));
|
||||
$srcAltConfig = getConfig('src_alt', null);
|
||||
if (empty($srcAltImage)) {
|
||||
$srcAltImage = $srcAltConfig;
|
||||
@@ -4834,7 +4775,7 @@ if ($dummyEnabled && $srcImage === $dummyFilename) {
|
||||
matching file exists on the filesystem.',
|
||||
404
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($imagePathConstraint && !$dummyImage && !$remoteSource) {
|
||||
@@ -4893,7 +4834,7 @@ if (isset($sizes[$newWidth])) {
|
||||
}
|
||||
|
||||
// Support width as % of original width
|
||||
if ($newWidth && $newWidth[strlen($newWidth)-1] == '%') {
|
||||
if ($newWidth[strlen($newWidth)-1] == '%') {
|
||||
is_numeric(substr($newWidth, 0, -1))
|
||||
or errorPage('Width % not numeric.', 404);
|
||||
} else {
|
||||
@@ -4918,7 +4859,7 @@ if (isset($sizes[$newHeight])) {
|
||||
}
|
||||
|
||||
// height
|
||||
if ($newHeight && $newHeight[strlen($newHeight)-1] == '%') {
|
||||
if ($newHeight[strlen($newHeight)-1] == '%') {
|
||||
is_numeric(substr($newHeight, 0, -1))
|
||||
or errorPage('Height % out of range.', 404);
|
||||
} else {
|
||||
@@ -4949,7 +4890,7 @@ $aspectRatioConstant = getConfig('aspect_ratio_constant', function () {
|
||||
|
||||
// Check to replace predefined aspect ratio
|
||||
$aspectRatios = call_user_func($aspectRatioConstant);
|
||||
$negateAspectRatio = ($aspectRatio && $aspectRatio[0] == '!') ? true : false;
|
||||
$negateAspectRatio = ($aspectRatio[0] == '!') ? true : false;
|
||||
$aspectRatio = $negateAspectRatio ? substr($aspectRatio, 1) : $aspectRatio;
|
||||
|
||||
if (isset($aspectRatios[$aspectRatio])) {
|
||||
@@ -5373,18 +5314,6 @@ if ($cacheControl) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* interlace - Enable configuration for interlaced progressive JPEG images.
|
||||
*/
|
||||
$interlaceConfig = getConfig('interlace', null);
|
||||
$interlaceValue = getValue('interlace', null);
|
||||
$interlaceDefined = getDefined('interlace', true, null);
|
||||
$interlace = $interlaceValue ?? $interlaceDefined ?? $interlaceConfig;
|
||||
verbose("interlace (configfile) = ", $interlaceConfig);
|
||||
verbose("interlace = ", $interlace);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a dummy image and use it as source image.
|
||||
*/
|
||||
@@ -5546,7 +5475,6 @@ if (is_callable($hookBeforeCImage)) {
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
@@ -5602,8 +5530,7 @@ EOD;
|
||||
/**
|
||||
* Load, process and output the image
|
||||
*/
|
||||
$img->log("PHP version: " . phpversion())
|
||||
->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||
->setSaveFolder($cachePath)
|
||||
->useCache($useCache)
|
||||
->setSource($srcImage, $imagePath)
|
||||
@@ -5636,7 +5563,6 @@ $img->log("PHP version: " . phpversion())
|
||||
'blur' => $blur,
|
||||
'convolve' => $convolve,
|
||||
'rotateAfter' => $rotateAfter,
|
||||
'interlace' => $interlace,
|
||||
|
||||
// Output format
|
||||
'outputFormat' => $outputFormat,
|
||||
|
@@ -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
@@ -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
@@ -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";
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
$links = [
|
||||
"img.php?src=car.png&v",
|
||||
"img.php?src=car.png&w=700&v",
|
||||
];
|
||||
|
||||
?><!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Links to use for testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Links useful for testing</h1>
|
||||
<p>A collection of linkt to use to test various aspects of the cimage process.</p>
|
||||
<ul>
|
||||
<?php foreach ($links as $link) : ?>
|
||||
<li><a href="<?= $link ?>"><?= $link ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|