From 6a93f843be6a73fa1a48564c559d33c5f9285fa8 Mon Sep 17 00:00:00 2001 From: Mikael Roos Date: Sat, 5 Dec 2015 14:50:49 +0100 Subject: [PATCH] major rearrange to prepare to move to PHP 5.4 --- .gitignore | 5 +- phpcs.xml => .phpcs.xml | 3 +- phpdoc.xml => .phpdoc.xml | 0 phpunit.xml => .phpunit.xml | 4 +- .scrutinizer.yml | 30 +- .travis.yml | 69 +- CImageResizer.php | 822 ------------------ LICENSE.txt | 4 +- Makefile | 162 ++++ README.md | 6 +- REVISION.md | 13 +- autoload.php | 14 +- composer.json | 14 +- CAsciiArt.php => src/CImage/CAsciiArt.php | 2 +- CHttpGet.php => src/CImage/CHttpGet.php | 0 CImage.php => src/CImage/CImage.php | 36 +- src/CImage/CImageResizer.php | 822 ++++++++++++++++++ .../CImage/CRemoteImage.php | 0 CWhitelist.php => src/CImage/CWhitelist.php | 0 ...mageResizerStrategyKeepAspectRatioTest.php | 28 +- test/CImageResizerStrategyStretchTest.php | 2 +- test/CImageResizerTest.php | 4 +- test/CImageSRGBTest.php | 6 +- webroot/img.php | 6 +- 24 files changed, 1137 insertions(+), 915 deletions(-) rename phpcs.xml => .phpcs.xml (91%) rename phpdoc.xml => .phpdoc.xml (100%) rename phpunit.xml => .phpunit.xml (73%) delete mode 100644 CImageResizer.php create mode 100644 Makefile rename CAsciiArt.php => src/CImage/CAsciiArt.php (99%) rename CHttpGet.php => src/CImage/CHttpGet.php (100%) rename CImage.php => src/CImage/CImage.php (99%) create mode 100644 src/CImage/CImageResizer.php rename CRemoteImage.php => src/CImage/CRemoteImage.php (100%) rename CWhitelist.php => src/CImage/CWhitelist.php (100%) diff --git a/.gitignore b/.gitignore index e6bc346..5c27965 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # Cache files cache/* -# Test -coverage/ -coverage.clover +# Test and build +build/ diff --git a/phpcs.xml b/.phpcs.xml similarity index 91% rename from phpcs.xml rename to .phpcs.xml index c65fee7..84e974d 100644 --- a/phpcs.xml +++ b/.phpcs.xml @@ -7,7 +7,8 @@ autoload.php docs/* - coverage/* + build/* + test/config.php webroot/imgs.php webroot/imgp.php webroot/imgd.php diff --git a/phpdoc.xml b/.phpdoc.xml similarity index 100% rename from phpdoc.xml rename to .phpdoc.xml diff --git a/phpunit.xml b/.phpunit.xml similarity index 73% rename from phpunit.xml rename to .phpunit.xml index aadeeec..7b91989 100644 --- a/phpunit.xml +++ b/.phpunit.xml @@ -9,8 +9,8 @@ - - + + diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 7b7ca89..ff52365 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -10,32 +10,34 @@ 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: tests: override: diff --git a/.travis.yml b/.travis.yml index 9f15485..779abea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: php + php: - 5.4 - 5.5 @@ -7,11 +8,77 @@ php: - nightly - "7.0" + + +sudo: false + + + +git: + submodules: false + + + +addons: + apt: + packages: + #- php-codesniffer + #- phpmd + #- shellcheck + + + +before_script: + + # Store all files in your own bin + - mkdir bin + - export PATH=$PATH:$PWD/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/bin/phpcs + + # Install phpmd + #- wget -c http://static.phpmd.org/php/latest/phpmd.phar + #- install --mode 0755 phpmd.phar $PWD/bin/phpmd + + # Create a build directory for output + - mkdir build + + + script: - - phpunit + # 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 + #- make phpcs + + notifications: irc: "irc.freenode.org#dbwebb" + webhooks: urls: - https://webhooks.gitter.im/e/cce29c69604daa8a60ab diff --git a/CImageResizer.php b/CImageResizer.php deleted file mode 100644 index d8e0fdc..0000000 --- a/CImageResizer.php +++ /dev/null @@ -1,822 +0,0 @@ -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; - - 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; - } - - - - /** - * 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 - $aspectRatio = $this->srcWidth / $this->srcHeight; - $this->cropX = 0; - $this->cropY = 0; - $this->cropWidth = $this->srcWidth; - $this->cropHeight = $this->srcHeight; - - // Get relations of original & target image - $width = $this->srcWidth; - $height = $this->srcHeight; -*/ - - // 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; - $cx = 0; - $cy = 0; - $cw = $this->srcWidth; - $ch = $this->srcHeight; - - 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 - $th = $tw / $ar; - $this->log(" New th x{$th}"); - - } elseif (is_null($tw) && isset($th)) { - - // Keep aspect ratio, make tw based on th - $tw = $th * $ar; - $this->log(" New tw {$tw}x"); - - } elseif (isset($tw) && isset($th)) { - - // Keep aspect ratio, make fit in imaginary box - if ($ar < 1) { - $tw = $th * $ar; - $this->log(" New tw {$tw}x"); - } else { - $th = $tw / $ar; - $this->log(" New th x{$th}"); - } - } - -/* - if (isset($tw) && isset($th)) { - - // Both new width and height are set. - // Use targetWidth and targetHeight as max width/height, image - // should not be larger. - $ratioWidth = $width / $this->targetWidth; - $ratioHeight = $height / $this->targetHeight; - $ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight; - $this->targetWidth = round($width / $ratio); - $this->targetHeight = round($height / $ratio); - $this->log(" New width and height was set."); - - } elseif (isset($this->targetWidth)) { - - // Use new width as max-width - $factor = (float)$this->targetWidth / (float)$width; - $this->targetHeight = round($factor * $height); - $this->log(" New height x$this->targetHeight."); - - } elseif (isset($this->targetHeight)) { - - // Use new height as max-hight - $factor = (float)$this->targetHeight / (float)$height; - $this->targetWidth = round($factor * $width); - $this->log(" New width {$this->targetWidth}x."); - - } - -*/ - - // No new height or width is set, use existing measures. - -/* - $this->targetWidth = isset($this->targetWidth) - ? $this->targetWidth - : $this->srcWidth; - $this->targetHeight = isset($this->targetHeight) - ? $this->targetHeight - : $this->srcHeight; -*/ - - $this->targetWidth = round($tw); - $this->targetHeight = round($th); - $this->cropX = round($cx); - $this->cropY = round($cy); - $this->cropWidth = round($cw); - $this->cropHeight = round($ch); - - $this->log(" Target dimension (after) {$this->targetWidth}x{$this->targetHeight}."); - $this->log(" Crop {$this->cropX}x{$this->cropY} by {$this->cropWidth}x{$this->cropHeight}."); - - - -/* - $ratioWidth = $this->srcWidth / $this->targetWidth; - $ratioHeight = $this->srcHeight / $this->targetHeight; - - - - if ($this->resizeStrategy === self::CROP_TO_FIT) { - - // Use targetWidth and targetHeight as defined - // width/height, image should fit the area. - $this->log(" Crop to fit."); - $ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight; - $this->cropWidth = round($width / $ratio); - $this->cropHeight = round($height / $ratio); - $this->log(" Crop width, height, ratio: $this->cropWidth x $this->cropHeight ($ratio)."); - - } elseif ($this->resizeStrategy === self::FILL_TO_FIT) { - - // Use targetWidth and targetHeight as defined - // width/height, image should fit the area. - $this->log(" Fill to fit."); - $ratio = ($ratioWidth < $ratioHeight) ? $ratioHeight : $ratioWidth; - $this->fillWidth = round($width / $ratio); - $this->fillHeight = round($height / $ratio); - $this->log(" Fill width, height, ratio: $this->fillWidth x $this->fillHeight ($ratio)."); - } -*/ - - - // 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."); - } - -/* - // Calculate new width and height if keeping aspect-ratio. - if ($this->resizeStrategy === self::KEEP_RATIO) { - - $this->log(" Keep aspect ratio."); - - // Crop-to-fit and both new width and height are set. - if (($this->resizeStrategy === self::CROP_TO_FIT - || $this->resizeStrategy === self::FILL_TO_FIT) - && isset($this->targetWidth) - && isset($this->targetHeight) - ) { - - // Use targetWidth and targetHeight as width/height, image should - // fit in box. - $this->log(" Use targetWidth and targetHeight as width/height, image should fit in box."); - - } elseif (isset($this->targetWidth) && isset($this->targetHeight)) { - - // Both new width and height are set. - // Use targetWidth and targetHeight as max width/height, image - // should not be larger. - $ratioWidth = $width / $this->targetWidth; - $ratioHeight = $height / $this->targetHeight; - $ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight; - $this->targetWidth = round($width / $ratio); - $this->targetHeight = round($height / $ratio); - $this->log(" New width and height was set."); - - } elseif (isset($this->targetWidth)) { - - // Use new width as max-width - $factor = (float)$this->targetWidth / (float)$width; - $this->targetHeight = round($factor * $height); - $this->log(" New height x$this->targetHeight."); - - } elseif (isset($this->targetHeight)) { - - // Use new height as max-hight - $factor = (float)$this->targetHeight / (float)$height; - $this->targetWidth = round($factor * $width); - $this->log(" New width {$this->targetWidth}x."); - - } - } - - -/* - // Get image dimensions for pre-resize image. - if ($this->resizeStrategy === self::CROP_TO_FIT - || $this->resizeStrategy === self::FILL_TO_FIT - ) { - - // Get relations of original & target image - $ratioWidth = $width / $this->targetWidth; - $ratioHeight = $height / $this->targetHeight; - - if ($this->resizeStrategy === self::CROP_TO_FIT) { - - // Use targetWidth and targetHeight as defined - // width/height, image should fit the area. - $this->log(" Crop to fit."); - $ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight; - $this->cropWidth = round($width / $ratio); - $this->cropHeight = round($height / $ratio); - $this->log(" Crop width, height, ratio: $this->cropWidth x $this->cropHeight ($ratio)."); - - } elseif ($this->resizeStrategy === self::FILL_TO_FIT) { - - // Use targetWidth and targetHeight as defined - // width/height, image should fit the area. - $this->log(" Fill to fit."); - $ratio = ($ratioWidth < $ratioHeight) ? $ratioHeight : $ratioWidth; - $this->fillWidth = round($width / $ratio); - $this->fillHeight = round($height / $ratio); - $this->log(" Fill width, height, ratio: $this->fillWidth x $this->fillHeight ($ratio)."); - } - } -*/ - - - // 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']); - } - - // Fill to fit, ensure to set new width and height - /*if ($this->fillToFit) { - $this->log("FillToFit."); - $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 target width. - * - * @return integer as target width - */ - public function getTargetwidth() - { - return $this->targetWidth ? round($this->targetWidth) : null; - } - - - - /** - * Get target height. - * - * @return integer as target height - */ - public function getTargetheight() - { - return $this->targetHeight ? round($this->targetHeight) : null; - } - - - - /** - * Get crop position x. - * - * @return integer - */ - public function getCropX() - { - return $this->cropX; - /* - $cropX = 0; - - if ($this->cropWidth) { - $cropX = round(($this->cropWidth/2) - ($this->targetWidth/2)); - }; - - return $cropX;*/ - } - - - - /** - * Get crop position y. - * - * @return integer - */ - public function getCropY() - { - return $this->cropY; - /* - $cropY = 0; - - if ($this->cropHeight) { - $cropY = round(($this->cropHeight/2) - ($this->targetHeight/2)); - } - - return $cropY;*/ - } - - - - /** - * Get crop width. - * - * @return integer - */ - public function getCropWidth() - { - return $this->cropWidth; - /* - $cropWidth = $this->srcWidth; - - if ($this->cropWidth) { - $cropWidth = round($this->cropWidth); - } - - return $cropWidth;*/ - } - - - - /** - * Get crop height. - * - * @return integer - */ - public function getCropHeight() - { - return $this->cropHeight; - /* - $cropHeight = $this->srcHeight; - - if ($this->cropHeight) { - $cropHeight = round($this->cropHeight); - } - - return $cropHeight;*/ - } -} diff --git a/LICENSE.txt b/LICENSE.txt index 1549d2c..ec90989 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2012 - 2014 Mikael Roos, me@mikaelroos.se +Copyright (c) 2012 - 2015 Mikael Roos, me@mikaelroos.se Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fe4e726 --- /dev/null +++ b/Makefile @@ -0,0 +1,162 @@ +#!/usr/bin/make -f +# +# + + +# +# Update codebase +# +.PHONY: build + +build: + [ -d build ] || mkdir build + rm -rf build/* + + + +# +# Various test to pass build +# +.PHONY: test + +test: build phpunit phpcs + + + +# +# phpcs +# +.PHONY: phpcs + +phpcs: + phpcs --standard=.phpcs.xml | tee build/phpcs + + + +# +# phpcbf +# +.PHONY: phpcbf + +phpcbf: + phpcbf --standard=.phpcs.xml + + +# +# phpunit +# +.PHONY: phpunit + +phpunit: + phpunit --configuration .phpunit.xml + + + +# +# phpdoc +# +.PHONY: phpdoc + +phpdoc: + phpdoc --config=.phpdoc.xml + + +# ------------------------- OBSOLETE TO BE REMOVED? + +# +# Build and development environment using make +# +COMPOSER_PACKAGES = \ + "phpunit/phpunit=4.*" \ + "sebastian/phpcpd=2.*" \ + "phploc/phploc=2.*" \ + "phpdocumentor/phpdocumentor=2.*" \ + "squizlabs/php_codesniffer=2.*" \ + "phpmd/phpmd=@stable" \ + +NPM_PACKAGES = \ + htmlhint \ + csslint \ + less \ + +APM_PACKAGES = \ + linter \ + linter-htmlhint \ + linter-csslint \ + linter-less \ + linter-jscs \ + linter-jshint \ + linter-pep8 \ + linter-pylint \ + linter-php \ + linter-phpcs \ + linter-phpmd \ + linter-shellcheck \ + linter-xmllint \ + block-travel \ + + + +# +# less +# +.PHONY: less + +less: + lessc --clean-css app/css/style.less htdocs/css/style.css + + + + +# +# All developer tools +# +.PHONY: tools-config tools-install tools-update + +tools-config: npm-config + +tools-install: composer-require npm-install apm-install + +tools-update: composer-update npm-update apm-update + + + +# +# composer +# +.PHONY: composer-require composer-update + +composer-require: + composer --sort-packages --update-no-dev global require $(COMPOSER_PACKAGES) + +composer-update: + composer --no-dev global update + + + +# +# npm +# +.PHONY: npm-config npm-installl npm-update + +npm-config: + npm config set prefix '~/.npm-packages' + +npm-install: + npm -g install $(NPM_PACKAGES) + +npm-update: + npm -g update + + + +# +# apm +# +.PHONY: apm-installl apm-update + +apm-install: + apm install $(APM_PACKAGES) + +apm-update: + apm update --confirm=false diff --git a/README.md b/README.md index 8193cf2..573e720 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,10 @@ Image conversion on the fly using PHP ===================================== [![Join the chat at https://gitter.im/mosbth/cimage](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mosbth/cimage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/mosbth/cimage.svg?branch=master)](https://travis-ci.org/mosbth/cimage) -[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master) +[![Build Status](https://travis-ci.org/mosbth/cimage.svg?branch=resize)](https://travis-ci.org/mosbth/cimage) +[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=resize)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/resize) + + About ------------------------------------- diff --git a/REVISION.md b/REVISION.md index 02e761f..33a1663 100644 --- a/REVISION.md +++ b/REVISION.md @@ -1,11 +1,18 @@ Revision history ===================================== -[![Build Status](https://travis-ci.org/mosbth/cimage.svg?branch=master)](https://travis-ci.org/mosbth/cimage) -[![Build Status](https://scrutinizer-ci.com/g/mosbth/cimage/badges/build.png?b=master)](https://scrutinizer-ci.com/g/mosbth/cimage/build-status/master) -v0.7.7* (2015-10-25) +v0.8.* (2015-12-05) (branch resize) +------------------------------------- + +* Improving build phase using travis and scrutinizer. +* Code validating with phpunit and phpcs. +* Moved classes to src/, adding namespace and support PSR-4. +* Require PHP 5.4. + + +v0.7.7* (2015-10-25) (branch master) ------------------------------------- * Added conversion to sRGB using option `?srgb`. #120. diff --git a/autoload.php b/autoload.php index b65d4e1..c5f6bf8 100644 --- a/autoload.php +++ b/autoload.php @@ -3,20 +3,8 @@ * Autoloader for CImage and related class files. * */ -//include __DIR__ . "/../CHttpGet.php"; -//include __DIR__ . "/../CRemoteImage.php"; -//include __DIR__ . "/../CImage.php"; - -/** - * Autoloader for classes. - * - * @param string $class the fully-qualified class name. - * - * @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); } diff --git a/composer.json b/composer.json index de994fb..04cdf16 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { "name": "mos/cimage", "type": "library", - "description": "Process, scale, resize, crop and filter images.", - "keywords": ["image", "imageprocessing", "gd"], + "description": "Serverside image processing with PHP GD. Process, scale, resize, crop and filter images.", + "keywords": ["image", "imageprocessing", "gd", "crop", "resize"], "homepage": "http://dbwebb.se/opensource/cimage", "license": "MIT", "authors": [ @@ -18,15 +18,9 @@ "docs": "http://dbwebb.se/opensource/cimage" }, "require": { - "php": ">=5.3" + "php": ">=5.4" }, "autoload": { - "classmap": [ - "CImage.php", - "CHttpGet.php", - "CRemoteImage.php", - "CWhitelist.php", - "CAsciiArt.php" - ] + "classmap": [ "src/CImage/" ] } } diff --git a/CAsciiArt.php b/src/CImage/CAsciiArt.php similarity index 99% rename from CAsciiArt.php rename to src/CImage/CAsciiArt.php index 836d9fb..6a9a758 100644 --- a/CAsciiArt.php +++ b/src/CImage/CAsciiArt.php @@ -175,7 +175,7 @@ class CAsciiArt */ public function getLuminance($red, $green, $blue) { - switch($this->luminanceStrategy) { + switch ($this->luminanceStrategy) { case 1: $luminance = ($red * 0.2126 + $green * 0.7152 + $blue * 0.0722) / 255; break; diff --git a/CHttpGet.php b/src/CImage/CHttpGet.php similarity index 100% rename from CHttpGet.php rename to src/CImage/CHttpGet.php diff --git a/CImage.php b/src/CImage/CImage.php similarity index 99% rename from CImage.php rename to src/CImage/CImage.php index 09c812d..2b62703 100644 --- a/CImage.php +++ b/src/CImage/CImage.php @@ -208,8 +208,8 @@ class CImage /** * Path to command to optimize jpeg images, for example jpegtran or null. */ - private $jpegOptimize; - private $jpegOptimizeCmd; + private $jpegOptimize; + private $jpegOptimizeCmd; @@ -339,8 +339,8 @@ class CImage /** * Used with option area to set which parts of the image to use. */ - private $area; - private $offset; + private $area; + private $offset; @@ -401,14 +401,14 @@ class CImage */ const RESIZE = 1; const RESAMPLE = 2; - private $copyStrategy = NULL; + private $copyStrategy = null; /* * Class for image resizer. */ - private $imageResizer = null; + private $imageResizer = null; /** * Properties, the class is mutable and the method setOptions() @@ -637,7 +637,7 @@ class CImage if ($extension == 'jpeg') { $extension = 'jpg'; - } + } return $extension; } @@ -1343,7 +1343,7 @@ class CImage $subdir .= '_'; } - $file = $prefix . $subdir . $filename . $width . $height + $file = $prefix . $subdir . $filename . $width . $height . $offset . $crop . $cropToFit . $fillToFit . $crop_x . $crop_y . $upscale . $quality . $filters . $sharpen . $emboss . $blur . $palette @@ -1484,7 +1484,7 @@ class CImage $index = imagecolortransparent($this->image); $transparent = null; if ($index != -1) { - $transparent = " (transparent)"; + $transparent = " (transparent)"; } switch ($pngType) { @@ -1594,11 +1594,11 @@ class CImage * * @return $this */ - public function setCopyResizeStrategy($strategy) - { - $this->copyStrategy = $strategy; - return $this; - } + public function setCopyResizeStrategy($strategy) + { + $this->copyStrategy = $strategy; + return $this; + } @@ -1609,7 +1609,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 { @@ -2298,7 +2298,7 @@ class CImage $type = $this->getTargetImageExtension(); $this->Log("Saving image as " . $type); - switch($type) { + switch ($type) { case 'jpeg': case 'jpg': @@ -2424,7 +2424,7 @@ class CImage $colorspace = $image->getImageColorspace(); $this->log(" Current colorspace: " . $colorspace); - $profiles = $image->getImageProfiles('*', false); + $profiles = $image->getImageProfiles('*', false); $hasICCProfile = (array_search('icc', $profiles) !== false); $this->log(" Has ICC color profile: " . ($hasICCProfile ? "YES" : "NO")); @@ -2535,7 +2535,7 @@ class CImage header('Last-Modified: ' . $gmdate . " GMT"); } - foreach($this->HTTPHeader as $key => $val) { + foreach ($this->HTTPHeader as $key => $val) { header("$key: $val"); } diff --git a/src/CImage/CImageResizer.php b/src/CImage/CImageResizer.php new file mode 100644 index 0000000..c51169c --- /dev/null +++ b/src/CImage/CImageResizer.php @@ -0,0 +1,822 @@ +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; + + 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; + } + + + + /** + * 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 + $aspectRatio = $this->srcWidth / $this->srcHeight; + $this->cropX = 0; + $this->cropY = 0; + $this->cropWidth = $this->srcWidth; + $this->cropHeight = $this->srcHeight; + + // Get relations of original & target image + $width = $this->srcWidth; + $height = $this->srcHeight; +*/ + + // 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; + $cx = 0; + $cy = 0; + $cw = $this->srcWidth; + $ch = $this->srcHeight; + + 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 + $th = $tw / $ar; + $this->log(" New th x{$th}"); + + } elseif (is_null($tw) && isset($th)) { + + // Keep aspect ratio, make tw based on th + $tw = $th * $ar; + $this->log(" New tw {$tw}x"); + + } elseif (isset($tw) && isset($th)) { + + // Keep aspect ratio, make fit in imaginary box + if ($ar < 1) { + $tw = $th * $ar; + $this->log(" New tw {$tw}x"); + } else { + $th = $tw / $ar; + $this->log(" New th x{$th}"); + } + } + +/* + if (isset($tw) && isset($th)) { + + // Both new width and height are set. + // Use targetWidth and targetHeight as max width/height, image + // should not be larger. + $ratioWidth = $width / $this->targetWidth; + $ratioHeight = $height / $this->targetHeight; + $ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight; + $this->targetWidth = round($width / $ratio); + $this->targetHeight = round($height / $ratio); + $this->log(" New width and height was set."); + + } elseif (isset($this->targetWidth)) { + + // Use new width as max-width + $factor = (float)$this->targetWidth / (float)$width; + $this->targetHeight = round($factor * $height); + $this->log(" New height x$this->targetHeight."); + + } elseif (isset($this->targetHeight)) { + + // Use new height as max-hight + $factor = (float)$this->targetHeight / (float)$height; + $this->targetWidth = round($factor * $width); + $this->log(" New width {$this->targetWidth}x."); + + } + +*/ + + // No new height or width is set, use existing measures. + +/* + $this->targetWidth = isset($this->targetWidth) + ? $this->targetWidth + : $this->srcWidth; + $this->targetHeight = isset($this->targetHeight) + ? $this->targetHeight + : $this->srcHeight; +*/ + + $this->targetWidth = round($tw); + $this->targetHeight = round($th); + $this->cropX = round($cx); + $this->cropY = round($cy); + $this->cropWidth = round($cw); + $this->cropHeight = round($ch); + + $this->log(" Target dimension (after) {$this->targetWidth}x{$this->targetHeight}."); + $this->log(" Crop {$this->cropX}x{$this->cropY} by {$this->cropWidth}x{$this->cropHeight}."); + + + +/* + $ratioWidth = $this->srcWidth / $this->targetWidth; + $ratioHeight = $this->srcHeight / $this->targetHeight; + + + + if ($this->resizeStrategy === self::CROP_TO_FIT) { + + // Use targetWidth and targetHeight as defined + // width/height, image should fit the area. + $this->log(" Crop to fit."); + $ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight; + $this->cropWidth = round($width / $ratio); + $this->cropHeight = round($height / $ratio); + $this->log(" Crop width, height, ratio: $this->cropWidth x $this->cropHeight ($ratio)."); + + } elseif ($this->resizeStrategy === self::FILL_TO_FIT) { + + // Use targetWidth and targetHeight as defined + // width/height, image should fit the area. + $this->log(" Fill to fit."); + $ratio = ($ratioWidth < $ratioHeight) ? $ratioHeight : $ratioWidth; + $this->fillWidth = round($width / $ratio); + $this->fillHeight = round($height / $ratio); + $this->log(" Fill width, height, ratio: $this->fillWidth x $this->fillHeight ($ratio)."); + } +*/ + + + // 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."); + } + +/* + // Calculate new width and height if keeping aspect-ratio. + if ($this->resizeStrategy === self::KEEP_RATIO) { + + $this->log(" Keep aspect ratio."); + + // Crop-to-fit and both new width and height are set. + if (($this->resizeStrategy === self::CROP_TO_FIT + || $this->resizeStrategy === self::FILL_TO_FIT) + && isset($this->targetWidth) + && isset($this->targetHeight) + ) { + + // Use targetWidth and targetHeight as width/height, image should + // fit in box. + $this->log(" Use targetWidth and targetHeight as width/height, image should fit in box."); + + } elseif (isset($this->targetWidth) && isset($this->targetHeight)) { + + // Both new width and height are set. + // Use targetWidth and targetHeight as max width/height, image + // should not be larger. + $ratioWidth = $width / $this->targetWidth; + $ratioHeight = $height / $this->targetHeight; + $ratio = ($ratioWidth > $ratioHeight) ? $ratioWidth : $ratioHeight; + $this->targetWidth = round($width / $ratio); + $this->targetHeight = round($height / $ratio); + $this->log(" New width and height was set."); + + } elseif (isset($this->targetWidth)) { + + // Use new width as max-width + $factor = (float)$this->targetWidth / (float)$width; + $this->targetHeight = round($factor * $height); + $this->log(" New height x$this->targetHeight."); + + } elseif (isset($this->targetHeight)) { + + // Use new height as max-hight + $factor = (float)$this->targetHeight / (float)$height; + $this->targetWidth = round($factor * $width); + $this->log(" New width {$this->targetWidth}x."); + + } + } + + +/* + // Get image dimensions for pre-resize image. + if ($this->resizeStrategy === self::CROP_TO_FIT + || $this->resizeStrategy === self::FILL_TO_FIT + ) { + + // Get relations of original & target image + $ratioWidth = $width / $this->targetWidth; + $ratioHeight = $height / $this->targetHeight; + + if ($this->resizeStrategy === self::CROP_TO_FIT) { + + // Use targetWidth and targetHeight as defined + // width/height, image should fit the area. + $this->log(" Crop to fit."); + $ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight; + $this->cropWidth = round($width / $ratio); + $this->cropHeight = round($height / $ratio); + $this->log(" Crop width, height, ratio: $this->cropWidth x $this->cropHeight ($ratio)."); + + } elseif ($this->resizeStrategy === self::FILL_TO_FIT) { + + // Use targetWidth and targetHeight as defined + // width/height, image should fit the area. + $this->log(" Fill to fit."); + $ratio = ($ratioWidth < $ratioHeight) ? $ratioHeight : $ratioWidth; + $this->fillWidth = round($width / $ratio); + $this->fillHeight = round($height / $ratio); + $this->log(" Fill width, height, ratio: $this->fillWidth x $this->fillHeight ($ratio)."); + } + } +*/ + + + // 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']); + } + + // Fill to fit, ensure to set new width and height + /*if ($this->fillToFit) { + $this->log("FillToFit."); + $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 target width. + * + * @return integer as target width + */ + public function getTargetwidth() + { + return $this->targetWidth ? round($this->targetWidth) : null; + } + + + + /** + * Get target height. + * + * @return integer as target height + */ + public function getTargetheight() + { + return $this->targetHeight ? round($this->targetHeight) : null; + } + + + + /** + * Get crop position x. + * + * @return integer + */ + public function getCropX() + { + return $this->cropX; + /* + $cropX = 0; + + if ($this->cropWidth) { + $cropX = round(($this->cropWidth/2) - ($this->targetWidth/2)); + }; + + return $cropX;*/ + } + + + + /** + * Get crop position y. + * + * @return integer + */ + public function getCropY() + { + return $this->cropY; + /* + $cropY = 0; + + if ($this->cropHeight) { + $cropY = round(($this->cropHeight/2) - ($this->targetHeight/2)); + } + + return $cropY;*/ + } + + + + /** + * Get crop width. + * + * @return integer + */ + public function getCropWidth() + { + return $this->cropWidth; + /* + $cropWidth = $this->srcWidth; + + if ($this->cropWidth) { + $cropWidth = round($this->cropWidth); + } + + return $cropWidth;*/ + } + + + + /** + * Get crop height. + * + * @return integer + */ + public function getCropHeight() + { + return $this->cropHeight; + /* + $cropHeight = $this->srcHeight; + + if ($this->cropHeight) { + $cropHeight = round($this->cropHeight); + } + + return $cropHeight;*/ + } +} diff --git a/CRemoteImage.php b/src/CImage/CRemoteImage.php similarity index 100% rename from CRemoteImage.php rename to src/CImage/CRemoteImage.php diff --git a/CWhitelist.php b/src/CImage/CWhitelist.php similarity index 100% rename from CWhitelist.php rename to src/CImage/CWhitelist.php diff --git a/test/CImageResizerStrategyKeepAspectRatioTest.php b/test/CImageResizerStrategyKeepAspectRatioTest.php index 7cb8c7a..5e3d4bb 100644 --- a/test/CImageResizerStrategyKeepAspectRatioTest.php +++ b/test/CImageResizerStrategyKeepAspectRatioTest.php @@ -44,21 +44,21 @@ class CImageResizerStrategyKeepAspectRatioTest extends \PHPUnit_Framework_TestCa * * @return void */ - public function testResize1($sw, $sh, $tw, $th, $twa, $tha, $cx, $cy, $cw, $ch) - { - $img = new CImageResizer(/*'logger'/**/); + 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(); + $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($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."); - } + $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."); + } } diff --git a/test/CImageResizerStrategyStretchTest.php b/test/CImageResizerStrategyStretchTest.php index 7dc7c43..df90739 100644 --- a/test/CImageResizerStrategyStretchTest.php +++ b/test/CImageResizerStrategyStretchTest.php @@ -46,7 +46,7 @@ class CImageResizerStrategyStretchTest extends \PHPUnit_Framework_TestCase */ public function testResize1($sw, $sh, $tw, $th, $twa, $tha, $cx, $cy, $cw, $ch) { - $img = new CImageResizer(/*'logger'/**/); + $img = new CImageResizer(/*'logger'/**/); $img->setSource($sw, $sh) ->setBaseWidthHeight($tw, $th) diff --git a/test/CImageResizerTest.php b/test/CImageResizerTest.php index 3da2e0f..6a10442 100644 --- a/test/CImageResizerTest.php +++ b/test/CImageResizerTest.php @@ -21,7 +21,7 @@ class CImageResizerTest extends \PHPUnit_Framework_TestCase // $strategy // $srcWidth, $srcHeight, $targetWidth, $targetHeight, - // $aspectRatio, $dpr, + // $aspectRatio, $dpr, // $expectedWidth, $expectedHeight, // $expectedWidth2, $expectedHeight2 @@ -162,7 +162,7 @@ class CImageResizerTest extends \PHPUnit_Framework_TestCase */ public function testResizeStrategy($strategy, $str) { - $img = new CImageResizer(/*'logger'*/); + $img = new CImageResizer(/*'logger'*/); $img->setResizeStrategy($strategy); $res = $img->getResizeStrategyAsString(); diff --git a/test/CImageSRGBTest.php b/test/CImageSRGBTest.php index 49b816b..906220f 100644 --- a/test/CImageSRGBTest.php +++ b/test/CImageSRGBTest.php @@ -38,7 +38,7 @@ class CImageSRGBTest extends \PHPUnit_Framework_TestCase $img = new CImage(); $filename = $img->convert2sRGBColorSpace( - 'car.png', + 'car.png', IMAGE_PATH, $this->cache, $this->srgbColorProfile @@ -63,8 +63,8 @@ class CImageSRGBTest extends \PHPUnit_Framework_TestCase $img = new CImage(); $filename = $img->convert2sRGBColorSpace( - 'car.jpg', - IMAGE_PATH, + 'car.jpg', + IMAGE_PATH, $this->cache, $this->srgbColorProfile ); diff --git a/webroot/img.php b/webroot/img.php index 001898e..fba6191 100644 --- a/webroot/img.php +++ b/webroot/img.php @@ -244,7 +244,7 @@ $pwd = get(array('password', 'pwd'), null); // Check if passwords match, if configured to use passwords $passwordMatch = null; if ($pwd) { - switch($pwdType) { + switch ($pwdType) { case 'md5': $passwordMatch = ($pwdConfig === md5($pwd)); break; @@ -996,8 +996,8 @@ if ($srgb || $srgbDefault) { } $filename = $img->convert2sRGBColorSpace( - $srcImage, - $imagePath, + $srcImage, + $imagePath, $srgbDir, $srgbColorProfile, $useCache