Prva verzija - gui interfejs
This commit is contained in:
253
vendor/imagine/imagine/CHANGELOG.md
vendored
Normal file
253
vendor/imagine/imagine/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
# CHANGELOG
|
||||
|
||||
### 1.2.3 (2019-12-04)
|
||||
* Handle jfif extension in GD driver (#727, @sylvain-msl-talkspirit)
|
||||
* Improve detection of unsupported Exit Metadata Reader (#729, @mlocati, @ausi)
|
||||
|
||||
### 1.2.2 (2019-07-09)
|
||||
* The GD driver can now load WebP files (#711, #718, @lashus, @ausi)
|
||||
* Avoid calling `imageantialias` if it's not available (#713, @ahukkanen)
|
||||
|
||||
### 1.2.1 (2019-06-03)
|
||||
* Silence call to `\Imagick::setImageOpacity()` in order to prevent deprecation error with Imagick 3.4.4 and ImageMagick 6 (#715, @samdark, @mlocati)
|
||||
|
||||
### 1.2.0 (2018-12-07)
|
||||
* `ExifMetadataReader` now returns all the available metadata, not only EXIF and IFD0 (#701, @mlocati)
|
||||
|
||||
### 1.1.0 (2018-10-25)
|
||||
* New `ImageInterface::THUMBNAIL_FLAG_NOCLONE` flag for `thumbnail()` to let it modify the original image instance in order to save memory (@mlocati)
|
||||
|
||||
### 1.0.2 (2018-10-24)
|
||||
* Check that the Imagick PHP extension is not compiled using ImageMagick version 7.0.7-32 because it does not work correctly (@mlocati)
|
||||
|
||||
### 1.0.1 (2018-09-27)
|
||||
* `Box` now rounds the width/height it receives (previously it discarded the decimal points) (@mlocati)
|
||||
|
||||
### 1.0.0 (2018-09-25)
|
||||
* New `FontInterface` method: `wrapText` - split a text into multiple lines, so that it fits a specific width (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `FontInterface` implementation, it now must implement `wrapText`
|
||||
* Drawer methods can now accept a thickness of zero (@mlocati)
|
||||
* Fix drawing unfilled chords with GD driver (@mlocati)
|
||||
* Fix thickness drawing of unfilled chords with Imagick and Gmagick drivers (@mlocati)
|
||||
* Fix handling of radius in `circle` method implementations (@mlocati)
|
||||
* The `dissolve` method of `ColorInterface` normalizes the final value of alpha (@mlocati)
|
||||
**BREAKING CHANGE** `dissolve` doesn't throw a `Imagine\Exception\InvalidArgumentException` anymore
|
||||
|
||||
### 1.0.0-alpha2 (2018-09-08)
|
||||
* The `coalesce` method of `LayerInterface` instances now returns the LayerInterface itself (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `LayerInterface` implementation, it now must return `$this`
|
||||
* The `__toString` method has been added to `ColorInterface` since all its implementations have it (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `ColorInterface` implementation, it now must implement `__toString`
|
||||
* New Imagick save option: `optimize` if set, the size of animated GIF files is optimized (@mlocati)
|
||||
**NOTE** Imagick requires that the image frames have the same size
|
||||
* The `paste` method now accepts images not fully included in the destination image (@mlocati)
|
||||
**BREAKING CHANGE** the paste method doesn't throw an OutOfBoundsException anymore
|
||||
* Fix handling of PNG compression in Imagick `save` method (@mlocati)
|
||||
* New drawer methods: `rectangle` and `circle` (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own implementation of `DrawerInterface` you should add these two new methods
|
||||
* The `getChannelsMaxValue` method has been added to `PaletteInterface` (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `PaletteInterface` implementation, it now must implement this new method
|
||||
|
||||
### 1.0.0-alpha1 (2018-08-28)
|
||||
* Imagine is now tested under Windows too (@mlocati)
|
||||
* Add support to webp image format (@chregu, @antoligy, @alexander-schranz)
|
||||
* Add `Imagine\File\LoaderInterface` that allows loading remote images with any imaging driver (@mlocati).
|
||||
You can use your own `LoaderInterface` implementation so that you can for instance use curl or any other library.
|
||||
* Fix some phpdoc issues (@mlocati)
|
||||
* `flipHorizontally` and `flipVertically` methods of GD images is now much faster on PHP 5.5+ (@mlocati)
|
||||
* Fix loading of PNG indexed images with GD (@mlocati)
|
||||
* Loading indexed images with GD is now much faster on PHP 5.5+ (@mlocati)
|
||||
* Add support to grayscale images with Gmagick (@mlocati)
|
||||
* Add support to alpha channels of Gmagick images (@mlocati)
|
||||
* Fix `getColorAt` method of Gmagick images (@mlocati)
|
||||
* Add `getTransformations` to the `Autorotate` filter, so that you can get the list of transformations that should be applied to an image accordingly to the EXIF metadata (@mlocati)
|
||||
* The metadata reader now doesn't throw exceptions or warnings (@lentex, @mlocati)
|
||||
* Fix documentation (@ZhangChaoWN, @Mark-H, @mlocati)
|
||||
* Fix pixel range issue with Gmagick image (@b-viguier)
|
||||
* Fix `text` drawer method on Windows when using relative font file paths (@mlocati)
|
||||
* Fix `box` font method on Windows when using relative font file paths (@mlocati)
|
||||
* Fix crash on Windows when loading an image with Imagick (@mlocati)
|
||||
* Fix generation of API documentation (@mlocati)
|
||||
* Add `jpeg_sampling_factors` option when saving JPEG images (Gmagick/Imagick only) (@ausi)
|
||||
* Add BMP as supported image format (@mlocati)
|
||||
* Add support to new image type constants of Imagick (@ausi)
|
||||
* Check that Imagick correctly supports profiles (@ausi)
|
||||
* Add `setMetadataReader`/`getMetadataReader` to `ImagineInterface` (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `ImagineInterface` implementation, it now must implement those two methods
|
||||
* Fix creating Gmagick images with alpha colors when palette doesn't support alpha (@FractalizeR)
|
||||
* Fix warning about deprecated clone method in copy method of Imagick images (@mlocati)
|
||||
* Fix copy methods of Images (the original image and its new copy are now fully detached) (@mlocati)
|
||||
* It's now possible to use `clone $image` as an alternative to `$image->copy()` (@mlocati)
|
||||
* Add support to custom classes for `BoxInterface`, `MetadataReaderInterface`, `FontInterface`, `LoaderInterface`, `LayersInterface`, `ImageInterface` (@mlocati)
|
||||
**BREAKING CHANGE** if you have your own `ImagineInterface` implementation, it now must implement the methods of `ClassFactoryAwareInterface`
|
||||
* Add support for pasting with alpha for GD and Imagick (@AlloVince, @mlocati)
|
||||
* Downscaling a `Box` until it reaches a dimension less than 1 returns a box with dimension of 1 instead of throwing an exception (@mlocati)
|
||||
**BREAKING CHANGE** if you relied on `Box::scale` throwing an exception in this case
|
||||
* New filters: `BlackWhite`, `BorderDetection`, `Negation`, `Neighborhood` (@rejinka)
|
||||
* Minor optimization of filters based on `OnPixelBased` (@rejinka, @mlocati)
|
||||
* Add flag to `thumbnail` to allow upscaling images (@vlakoff)
|
||||
**BREAKING CHANGE** the `$mode` argument has been renamed to `$settings`, and it's now an integer (but old string values are accepted for backward compatibility). In this case the `ManipulatorInterface` constants `THUMBNAIL_INSET`, `THUMBNAIL_OUTBOUND` were changed from string values to integers.
|
||||
* New filter: `brightness` (@lenybernard, @mlocati)
|
||||
* New filter: `colvolve` available for all graphics libraries except gmagick with version prior to 2.0.1RC2 (@armatronic, @mlocati)
|
||||
* Fix bug in Imagine\Image\Palette\RGB::blend() (@dmolineus, @mlocati)
|
||||
* Autoload was moved from PSR-0 to PSR-4, and code files moved from `/lib/Imagine` to `/src` (@mlocati)
|
||||
|
||||
### 0.7.1 (2017-05-16)
|
||||
* Remove Symfony PHPUnit bridge as dependency (@craue)
|
||||
|
||||
### 0.7.0 (2017-05-02)
|
||||
* Fix memory usage on metadata reading (@Seldaek)
|
||||
* PHP 7.1 support
|
||||
* Latest Imagemagick compatibility (@jdewit)
|
||||
|
||||
### 0.6.3 (2015-09-19)
|
||||
* Fix wrong array_merge when calling Transformation::getFilters without filters
|
||||
* Add export-ignore git attribute (@Benoth)
|
||||
* Fix docblocks (@Sm0ke0ut and @norkunas)
|
||||
* Fix animated gif loop length options (@jygaulier)
|
||||
* Multiple tweaks for the repository and travis builds (@localheinz, @vrkansagara and @dunzun)
|
||||
* Fix metadata extraction from streams (@armatronic)
|
||||
* Fix autorotation (@tarleb)
|
||||
* Load exifmetadata reader whenever possible
|
||||
* Add metadata getter
|
||||
|
||||
### 0.6.2 (2014-11-11)
|
||||
* Stripping image containing an invalid ICC profile fails
|
||||
* MetadataBag now implements \Countable
|
||||
* Fix wrong array_merge in MetadataBag giving invalid results with HTTP resources (@javaguirre)
|
||||
* Fix Imagick merge strategy (@GrahamCampbell)
|
||||
* Fixed various alpha issues (@RadekDvorak)
|
||||
* Fix Image cloning on HHVM (@RdeWilde)
|
||||
* Fix exception on invalid file using GD driver (@vlakoff).
|
||||
* Fix ImageInterface::getSize on animated GIFs (@sokac)
|
||||
|
||||
### 0.6.1 (2014-06-16)
|
||||
* Fix invalid namespace usage (#336 @csanquer).
|
||||
|
||||
### 0.6.0 (2014-06-13)
|
||||
* BC break: Colors are now provided through the PaletteInterface. Any call
|
||||
to previous Imagine\Image\Color constructor must be removed and use the
|
||||
palette provided by Imagine\Image\ImageInterface::getPalette to create
|
||||
colors.
|
||||
* BC break : Animated GIF default delay is no longer 800ms but null. This
|
||||
avoids resettings a delay on animated image.
|
||||
* Add support for ICC profiles
|
||||
* Add support for CMYK and grayscale colorspace images.
|
||||
* Add filter argument to ImageInterface::thumbnail method.
|
||||
* Add priority to filters (@Richtermeister).
|
||||
* Add blur effect (@Nokrosis).
|
||||
* Rename "quality" option to "jpeg_quality" and apply it only to JPEG files (@vlakoff).
|
||||
* Add "png_compression_level" option (@vlakoff).
|
||||
* Rename "filters" option to "png_compression_filter" (@vlakoff).
|
||||
* Deprecate `quality` and `filters` ManipulatorInterface::save options, use
|
||||
`jpeg_quality`, `png_compression_level` and `png_compression_filter` instead.
|
||||
* Add support for alpha blending in GD drawer (@salem).
|
||||
* Add width parameter to Drawer::text (@salemgolemugoo).
|
||||
* Add NotSupportedException when a driver does not support an operation (@rouffj).
|
||||
* Add support for metadata.
|
||||
* Fix #158: GD alpha detection + Color::isOpaque are broken.
|
||||
* Fix color extraction for non-RGB palettes.
|
||||
|
||||
### 0.5.0 (2013-07-10)
|
||||
* Add `Layers::coalesce`.
|
||||
* Add filter option to `ImageInterface::resize`.
|
||||
* Add sharpen effect.
|
||||
* Add interlace support.
|
||||
* `LayersInterface` now extends `ArrayAccess`, gives support for animated gifs.
|
||||
* Remove Imagick and Gmagick flatten after composite.
|
||||
* Fix pixel opacity reading in `Gmagick::histogram`.
|
||||
* Deprecate pear channel installation.
|
||||
* Deprecate phar installation.
|
||||
|
||||
### 0.4.1 (2012-12-13)
|
||||
* Lazy-load GD layers.
|
||||
|
||||
### 0.4.0 (2012-12-10)
|
||||
* Add support for image Layers.
|
||||
* Add Colorize effect.
|
||||
* Add documentation for the Grayscale effect.
|
||||
* Port RelativeResize filter from JmikolaImagineBundle.
|
||||
|
||||
### 0.3.1 (2012-11-12)
|
||||
* Add Grayscale effect.
|
||||
* `Drawer::text` position fix.
|
||||
|
||||
### 0.3.0 (2012-07-28)
|
||||
* Add configurable border thickness to drawer interface and implementations.
|
||||
* Add `ImageInterface`::strip.
|
||||
* Add Canvas filter.
|
||||
* Add resolution option on image saving.
|
||||
* Add Grayscale filter.
|
||||
* Add sami API documentation.
|
||||
* Add compression quality to Gmagick.
|
||||
* Add effects API.
|
||||
* Add method to get pixel at point in Gmagick.
|
||||
* Ensure valid background color in rotations.
|
||||
* Fill lines with color to prevent semi-transparency issues.
|
||||
* Use `Imagick::resizeImage` instead of `Imagick::thumbnailImage` for resizing.
|
||||
* Fix PNG transparency on save ; do not flatten if not necessary.
|
||||
|
||||
### 0.2.8 (2011-11-29)
|
||||
* Add support for Travis CI.
|
||||
|
||||
### 0.2.7 (2011-11-17)
|
||||
* Use composer for autoloading.
|
||||
|
||||
### 0.2.6 (2011-11-09)
|
||||
* Documentation enhancements.
|
||||
|
||||
### 0.2.5 (2011-10-29)
|
||||
* Add PEAR support.
|
||||
* Documentation enhancements.
|
||||
|
||||
### 0.2.4 (2011-10-17)
|
||||
* Add imagine.phar, phar and rake tasks.
|
||||
* Add `ImagineInterface::read` to read from a stream resource.
|
||||
* Documentation enhancements.
|
||||
* Fix gifs transparency issues.
|
||||
|
||||
### 0.2.3 (2011-10-16)
|
||||
* Documentation enhancements.
|
||||
|
||||
### 0.2.2 (2011-10-16)
|
||||
* Documentation enhancements.
|
||||
|
||||
### 0.2.1 (2011-10-15)
|
||||
* Add `PointInterface::move`.
|
||||
* `BoxInterface::scale` can accept floats.
|
||||
* Set antialias mode for GD images.
|
||||
* Fix png compression.
|
||||
|
||||
### 0.2.0 (2011-10-06)
|
||||
* Add `Imagine\Fill\Gradient\Linear::getStart`/`getEnd`.
|
||||
* Add `Imagine\Image\Color::isOpaque`.
|
||||
* Add Gmagick transparency exceptions.
|
||||
* Add support for transparency for gif export.
|
||||
* Add widen/heighten methods for easy scaling to target width/height.
|
||||
* Add functionals tests to unit test thumbnails creation.
|
||||
* Add the ability to use hexadecimal notation for `Imagine\Image\Color` construction.
|
||||
* Implement fast linear gradient for Imagick.
|
||||
* Remove lengthy image histogram comparisons.
|
||||
* Extract `ManipulatorInterface` from `ImageInterface`.
|
||||
* Switch methods to final.
|
||||
* New method `ImageInterface::getColorAt`.
|
||||
* Introduce `ImagineAware` abstract filter class.
|
||||
|
||||
### 0.1.5 (2011-05-18)
|
||||
* Fix bug in GD rotate.
|
||||
|
||||
### 0.1.4 (2011-03-21)
|
||||
* Add environment check to gracefuly skip test.
|
||||
|
||||
### 0.1.3 (2011-03-21)
|
||||
* Improve api docs.
|
||||
* Extract `FontInterface`.
|
||||
|
||||
### 0.1.2 (2011-03-21)
|
||||
* Add check for GD.
|
||||
|
||||
### 0.1.1 (2011-03-21)
|
||||
* Add rounding and fixed thumbnail logic.
|
||||
|
||||
### 0.1.0 (2011-03-14)
|
||||
* First tagged version.
|
||||
25
vendor/imagine/imagine/LICENSE
vendored
Normal file
25
vendor/imagine/imagine/LICENSE
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2004-2012 Bulat Shakirzyanov
|
||||
|
||||
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.
|
||||
|
||||
This software embeds Adobe ICC Profiles, see license at
|
||||
http://www.adobe.com/support/downloads/iccprofiles/icc_eula_mac_dist.html .
|
||||
|
||||
This software also embeds ICC Profile from colormanagement.org. Please
|
||||
find information about their license at http://colormanagement.org/ .
|
||||
58
vendor/imagine/imagine/README.md
vendored
Normal file
58
vendor/imagine/imagine/README.md
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# Imagine
|
||||
[](https://travis-ci.org/avalanche123/Imagine) [](https://ci.appveyor.com/project/avalanche123/Imagine)
|
||||
|
||||
Tweet about it using the [#php_imagine](https://twitter.com/search?q=%23php_imagine) hashtag.
|
||||
|
||||
Image manipulation library for PHP 5.3 inspired by Python's PIL and other image
|
||||
libraries.
|
||||
|
||||
## Requirements
|
||||
|
||||
The Imagine library has the following requirements:
|
||||
|
||||
- PHP 5.3+
|
||||
|
||||
Depending on the chosen Image implementation, you may need one of the following PHP extensions:
|
||||
|
||||
- GD2
|
||||
- Imagick (with ImageMagick version 6.2.9 or later, except version 7.0.7-32)
|
||||
- Gmagick
|
||||
|
||||
### Installation using composer
|
||||
`php composer.phar require imagine/imagine`
|
||||
|
||||
## Basic Principles
|
||||
|
||||
The main purpose of Imagine is to provide all the necessary functionality to bring all native low level image processing libraries in PHP to the same simple and intuitive OO API.
|
||||
|
||||
Several things are necessary to accomplish that:
|
||||
|
||||
* Image manipulation tools, such as resize, crop, etc.
|
||||
* Drawing API - to create basic shapes and advanced charts, write text on the image
|
||||
* Masking functionality - ability to apply black&white or grayscale images as masks, leading to semi-transparency or absolute transparency of the image the mask is being applied to
|
||||
|
||||
The above tools should be the basic foundation for a more powerful set of tools that are called ``Filters`` in Imagine.
|
||||
|
||||
Some of the ideas for upcoming filters:
|
||||
|
||||
* Charting and graphing filters - pie and bar charts, linear graphs with annotations
|
||||
* Reflection - apple style
|
||||
* Rounded corners - web 2.0
|
||||
|
||||
## Documentation ##
|
||||
|
||||
- [Hosted by Read The Docs](http://imagine.readthedocs.org/)
|
||||
|
||||
## Presentations ##
|
||||
|
||||
- [Introduction to Imagine](http://www.slideshare.net/avalanche123/introduction-toimagine)
|
||||
- [How to Take Over the World with Lithium](http://speakerdeck.com/u/nateabele/p/how-to-take-over-the-world-with-lithium?slide=33)
|
||||
|
||||
## Articles ##
|
||||
|
||||
- [Image Processing with Imagine](http://www.phparch.com/2011/03/image-processing-with-imagine)
|
||||
|
||||
## Contributing ##
|
||||
|
||||
New pull requests should be based on the `develop` branch.
|
||||
The `master` branch is the stable branch: it usually matches the latest a release but in can be a bit ahead.
|
||||
62
vendor/imagine/imagine/composer.json
vendored
Normal file
62
vendor/imagine/imagine/composer.json
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "imagine/imagine",
|
||||
"description": "Image processing for PHP 5.3",
|
||||
"keywords": [
|
||||
"image manipulation",
|
||||
"image processing",
|
||||
"drawing",
|
||||
"graphics"
|
||||
],
|
||||
"homepage": "http://imagine.readthedocs.org/",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bulat Shakirzyanov",
|
||||
"email": "mallluhuct@gmail.com",
|
||||
"homepage": "http://avalanche123.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4",
|
||||
"friendsofphp/php-cs-fixer": "2.2.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "to use the GD implementation",
|
||||
"ext-imagick": "to use the Imagick implementation",
|
||||
"ext-gmagick": "to use the Gmagick implementation"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Imagine\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Imagine\\Test\\": "tests/tests/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "0.7-dev"
|
||||
}
|
||||
},
|
||||
"archive": {
|
||||
"exclude": [
|
||||
"/.*",
|
||||
"/tests",
|
||||
"/vendor",
|
||||
"/bin",
|
||||
"docs/_build",
|
||||
"Imagine-*.tgz",
|
||||
"imagine-*.phar",
|
||||
"composer.phar"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit --verbose",
|
||||
"codestyle": "php-cs-fixer fix --path-mode=intersection --config=.php_cs.dist"
|
||||
}
|
||||
}
|
||||
175
vendor/imagine/imagine/src/Draw/DrawerInterface.php
vendored
Normal file
175
vendor/imagine/imagine/src/Draw/DrawerInterface.php
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Draw;
|
||||
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Interface for the drawer.
|
||||
*/
|
||||
interface DrawerInterface
|
||||
{
|
||||
/**
|
||||
* Draws an arc on a starting at a given x, y coordinates under a given
|
||||
* start and end angles.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $center
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function arc(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Same as arc, but also connects end points with a straight line.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $center
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function chord(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Draws and circle with center at the given x, y coordinates, and given radius.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $center
|
||||
* @param int $radius
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function circle(PointInterface $center, $radius, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Draws and ellipse with center at the given x, y coordinates, and given width and height.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $center
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function ellipse(PointInterface $center, BoxInterface $size, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Draws a line from start(x, y) to end(x, y) coordinates.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
* @param \Imagine\Image\PointInterface $end
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $outline
|
||||
* @param int $thickness
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function line(PointInterface $start, PointInterface $end, ColorInterface $outline, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Same as arc, but connects end points and the center.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $center
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Places a one pixel point at specific coordinates and fills it with
|
||||
* specified color.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $position
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dot(PointInterface $position, ColorInterface $color);
|
||||
|
||||
/**
|
||||
* Draws a rectangle from left, top(x, y) to right, bottom(x, y) coordinates.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $leftTop
|
||||
* @param \Imagine\Image\PointInterface $rightBottom
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function rectangle(PointInterface $leftTop, PointInterface $rightBottom, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Draws a polygon using array of x, y coordinates. Must contain at least three coordinates.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface[] $coordinates
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param bool $fill
|
||||
* @param int $thickness
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function polygon(array $coordinates, ColorInterface $color, $fill = false, $thickness = 1);
|
||||
|
||||
/**
|
||||
* Annotates image with specified text at a given position starting on the top left of the final text box.
|
||||
*
|
||||
* The rotation is done CW
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Imagine\Image\AbstractFont $font
|
||||
* @param \Imagine\Image\PointInterface $position
|
||||
* @param int $angle
|
||||
* @param int $width
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function text($string, AbstractFont $font, PointInterface $position, $angle = 0, $width = null);
|
||||
}
|
||||
103
vendor/imagine/imagine/src/Effects/EffectsInterface.php
vendored
Normal file
103
vendor/imagine/imagine/src/Effects/EffectsInterface.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Effects;
|
||||
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* Interface for the effects.
|
||||
*/
|
||||
interface EffectsInterface
|
||||
{
|
||||
/**
|
||||
* Apply gamma correction.
|
||||
*
|
||||
* @param float $correction
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function gamma($correction);
|
||||
|
||||
/**
|
||||
* Invert the colors of the image.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function negative();
|
||||
|
||||
/**
|
||||
* Grayscale the image.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function grayscale();
|
||||
|
||||
/**
|
||||
* Colorize the image.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function colorize(ColorInterface $color);
|
||||
|
||||
/**
|
||||
* Sharpens the image.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sharpen();
|
||||
|
||||
/**
|
||||
* Blur the image.
|
||||
*
|
||||
* @param float|int $sigma
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function blur($sigma);
|
||||
|
||||
/**
|
||||
* Changes the brightness of the image.
|
||||
*
|
||||
* @param int $brightness The level of brightness (-100 (black) to 100 (white))
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function brightness($brightness);
|
||||
|
||||
/**
|
||||
* Convolves the image.
|
||||
*
|
||||
* @param \Imagine\Utils\Matrix $matrix The matrix from which derive the convolution kernel
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function convolve(Matrix $matrix);
|
||||
}
|
||||
19
vendor/imagine/imagine/src/Exception/Exception.php
vendored
Normal file
19
vendor/imagine/imagine/src/Exception/Exception.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Exception;
|
||||
|
||||
/**
|
||||
* Imagine-specific exception.
|
||||
*/
|
||||
interface Exception
|
||||
{
|
||||
}
|
||||
19
vendor/imagine/imagine/src/Exception/InvalidArgumentException.php
vendored
Normal file
19
vendor/imagine/imagine/src/Exception/InvalidArgumentException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Exception;
|
||||
|
||||
/**
|
||||
* Imagine-specific invalid argument exception.
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Exception
|
||||
{
|
||||
}
|
||||
19
vendor/imagine/imagine/src/Exception/NotSupportedException.php
vendored
Normal file
19
vendor/imagine/imagine/src/Exception/NotSupportedException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Exception;
|
||||
|
||||
/**
|
||||
* Should be used when a driver does not support an operation.
|
||||
*/
|
||||
class NotSupportedException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
19
vendor/imagine/imagine/src/Exception/OutOfBoundsException.php
vendored
Normal file
19
vendor/imagine/imagine/src/Exception/OutOfBoundsException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Exception;
|
||||
|
||||
/**
|
||||
* Imagine-specific out of bounds exception.
|
||||
*/
|
||||
class OutOfBoundsException extends \OutOfBoundsException implements Exception
|
||||
{
|
||||
}
|
||||
19
vendor/imagine/imagine/src/Exception/RuntimeException.php
vendored
Normal file
19
vendor/imagine/imagine/src/Exception/RuntimeException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Exception;
|
||||
|
||||
/**
|
||||
* Imagine-specific runtime exception.
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
189
vendor/imagine/imagine/src/Factory/ClassFactory.php
vendored
Normal file
189
vendor/imagine/imagine/src/Factory/ClassFactory.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace Imagine\Factory;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\File\Loader;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Metadata\DefaultMetadataReader;
|
||||
use Imagine\Image\Metadata\ExifMetadataReader;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
|
||||
/**
|
||||
* The default implementation of Imagine\Factory\ClassFactoryInterface.
|
||||
*/
|
||||
class ClassFactory implements ClassFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private static $gdInfo;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createMetadataReader()
|
||||
*/
|
||||
public function createMetadataReader()
|
||||
{
|
||||
return $this->finalize(ExifMetadataReader::isSupported() ? new ExifMetadataReader() : new DefaultMetadataReader());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createBox()
|
||||
*/
|
||||
public function createBox($width, $height)
|
||||
{
|
||||
return $this->finalize(new Box($width, $height));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createFileLoader()
|
||||
*/
|
||||
public function createFileLoader($path)
|
||||
{
|
||||
return $this->finalize(new Loader($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createDrawer()
|
||||
*/
|
||||
public function createDrawer($handle, $resource)
|
||||
{
|
||||
switch ($handle) {
|
||||
case self::HANDLE_GD:
|
||||
return $this->finalize(new \Imagine\Gd\Drawer($resource));
|
||||
case self::HANDLE_GMAGICK:
|
||||
return $this->finalize(new \Imagine\Gmagick\Drawer($resource));
|
||||
case self::HANDLE_IMAGICK:
|
||||
return $this->finalize(new \Imagine\Imagick\Drawer($resource));
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unrecognized handle %s in %s', $handle, __FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createLayers()
|
||||
*/
|
||||
public function createLayers($handle, ImageInterface $image, $initialKey = null)
|
||||
{
|
||||
switch ($handle) {
|
||||
case self::HANDLE_GD:
|
||||
return $this->finalize(new \Imagine\Gd\Layers($image, $image->palette(), $image->getGdResource(), (int) $initialKey));
|
||||
case self::HANDLE_GMAGICK:
|
||||
return $this->finalize(new \Imagine\Gmagick\Layers($image, $image->palette(), $image->getGmagick(), (int) $initialKey));
|
||||
case self::HANDLE_IMAGICK:
|
||||
return $this->finalize(new \Imagine\Imagick\Layers($image, $image->palette(), $image->getImagick(), (int) $initialKey));
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unrecognized handle %s in %s', $handle, __FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createEffects()
|
||||
*/
|
||||
public function createEffects($handle, $resource)
|
||||
{
|
||||
switch ($handle) {
|
||||
case self::HANDLE_GD:
|
||||
return $this->finalize(new \Imagine\Gd\Effects($resource));
|
||||
case self::HANDLE_GMAGICK:
|
||||
return $this->finalize(new \Imagine\Gmagick\Effects($resource));
|
||||
case self::HANDLE_IMAGICK:
|
||||
return $this->finalize(new \Imagine\Imagick\Effects($resource));
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unrecognized handle %s in %s', $handle, __FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createImage()
|
||||
*/
|
||||
public function createImage($handle, $resource, PaletteInterface $palette, MetadataBag $metadata)
|
||||
{
|
||||
switch ($handle) {
|
||||
case self::HANDLE_GD:
|
||||
return $this->finalize(new \Imagine\Gd\Image($resource, $palette, $metadata));
|
||||
case self::HANDLE_GMAGICK:
|
||||
return $this->finalize(new \Imagine\Gmagick\Image($resource, $palette, $metadata));
|
||||
case self::HANDLE_IMAGICK:
|
||||
return $this->finalize(new \Imagine\Imagick\Image($resource, $palette, $metadata));
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unrecognized handle %s in %s', $handle, __FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryInterface::createFont()
|
||||
*/
|
||||
public function createFont($handle, $file, $size, ColorInterface $color)
|
||||
{
|
||||
switch ($handle) {
|
||||
case self::HANDLE_GD:
|
||||
$gdInfo = static::getGDInfo();
|
||||
if (!$gdInfo['FreeType Support']) {
|
||||
throw new RuntimeException('GD is not compiled with FreeType support');
|
||||
}
|
||||
|
||||
return $this->finalize(new \Imagine\Gd\Font($file, $size, $color));
|
||||
case self::HANDLE_GMAGICK:
|
||||
$gmagick = new \Gmagick();
|
||||
$gmagick->newimage(1, 1, 'transparent');
|
||||
|
||||
return $this->finalize(new \Imagine\Gmagick\Font($gmagick, $file, $size, $color));
|
||||
case self::HANDLE_IMAGICK:
|
||||
return $this->finalize(new \Imagine\Imagick\Font(new \Imagick(), $file, $size, $color));
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unrecognized handle %s in %s', $handle, __FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the newly created object.
|
||||
*
|
||||
* @param object $object
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function finalize($object)
|
||||
{
|
||||
if ($object instanceof ClassFactoryAwareInterface) {
|
||||
$object->setClassFactory($this);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected static function getGDInfo()
|
||||
{
|
||||
if (self::$gdInfo === null) {
|
||||
if (!function_exists('gd_info')) {
|
||||
throw new RuntimeException('GD is not installed');
|
||||
}
|
||||
self::$gdInfo = gd_info();
|
||||
}
|
||||
|
||||
return self::$gdInfo;
|
||||
}
|
||||
}
|
||||
25
vendor/imagine/imagine/src/Factory/ClassFactoryAwareInterface.php
vendored
Normal file
25
vendor/imagine/imagine/src/Factory/ClassFactoryAwareInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Imagine\Factory;
|
||||
|
||||
/**
|
||||
* An interface that classes that accepts a class factory should implement.
|
||||
*/
|
||||
interface ClassFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* Set the class factory instance to be used.
|
||||
*
|
||||
* @param \Imagine\Factory\ClassFactoryInterface $classFactory
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setClassFactory(ClassFactoryInterface $classFactory);
|
||||
|
||||
/**
|
||||
* Get the class factory instance to be used.
|
||||
*
|
||||
* @return \Imagine\Factory\ClassFactoryInterface
|
||||
*/
|
||||
public function getClassFactory();
|
||||
}
|
||||
113
vendor/imagine/imagine/src/Factory/ClassFactoryInterface.php
vendored
Normal file
113
vendor/imagine/imagine/src/Factory/ClassFactoryInterface.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Imagine\Factory;
|
||||
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* The interface that class factories must implement.
|
||||
*/
|
||||
interface ClassFactoryInterface
|
||||
{
|
||||
/**
|
||||
* The handle to be used for the GD manipulation library.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HANDLE_GD = 'gd';
|
||||
|
||||
/**
|
||||
* The handle to be used for the Gmagick manipulation library.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HANDLE_GMAGICK = 'gmagick';
|
||||
|
||||
/**
|
||||
* The handle to be used for the Imagick manipulation library.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HANDLE_IMAGICK = 'imagick';
|
||||
|
||||
/**
|
||||
* Create a new instance of a metadata reader.
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataReaderInterface
|
||||
*/
|
||||
public function createMetadataReader();
|
||||
|
||||
/**
|
||||
* Create new BoxInterface instance.
|
||||
*
|
||||
* @param int $width The box width
|
||||
* @param int $height The box height
|
||||
*
|
||||
* @return \Imagine\Image\BoxInterface
|
||||
*/
|
||||
public function createBox($width, $height);
|
||||
|
||||
/**
|
||||
* Create new FontInterface instance.
|
||||
*
|
||||
* @param string $handle The handle that identifies the manipulation library (one of the HANDLE_... constants, or your own implementation).
|
||||
* @param string $file
|
||||
* @param int $size the font size in points (e.g. 10pt means 10)
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @return \Imagine\Image\FontInterface
|
||||
*/
|
||||
public function createFont($handle, $file, $size, ColorInterface $color);
|
||||
|
||||
/**
|
||||
* Create a new instance of a file loader.
|
||||
*
|
||||
* @param string|mixed $path
|
||||
*
|
||||
* @return \Imagine\File\LoaderInterface
|
||||
*/
|
||||
public function createFileLoader($path);
|
||||
|
||||
/**
|
||||
* Crate a new instance of a layers interface.
|
||||
*
|
||||
* @param string $handle The handle that identifies the manipulation library (one of the HANDLE_... constants, or your own implementation).
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
* @param mixed|null $initialKey the key of the initially selected layer
|
||||
*
|
||||
* @return \Imagine\Image\LayersInterface
|
||||
*/
|
||||
public function createLayers($handle, \Imagine\Image\ImageInterface $image, $initialKey = null);
|
||||
|
||||
/**
|
||||
* Create a new ImageInterface instance.
|
||||
*
|
||||
* @param string $handle The handle that identifies the manipulation library (one of the HANDLE_... constants, or your own implementation).
|
||||
* @param mixed $resource
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function createImage($handle, $resource, \Imagine\Image\Palette\PaletteInterface $palette, \Imagine\Image\Metadata\MetadataBag $metadata);
|
||||
|
||||
/**
|
||||
* Create a new DrawerInterface instance.
|
||||
*
|
||||
* @param string $handle The handle that identifies the manipulation library (one of the HANDLE_... constants, or your own implementation).
|
||||
* @param mixed $resource
|
||||
*
|
||||
* @return \Imagine\Draw\DrawerInterface
|
||||
*/
|
||||
public function createDrawer($handle, $resource);
|
||||
|
||||
/**
|
||||
* Create a new EffectsInterface instance.
|
||||
*
|
||||
* @param string $handle The handle that identifies the manipulation library (one of the HANDLE_... constants, or your own implementation).
|
||||
* @param mixed $resource
|
||||
*
|
||||
* @return \Imagine\Effects\EffectsInterface
|
||||
*/
|
||||
public function createEffects($handle, $resource);
|
||||
}
|
||||
300
vendor/imagine/imagine/src/File/Loader.php
vendored
Normal file
300
vendor/imagine/imagine/src/File/Loader.php
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\File;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Default implementation of Imagine\File\LoaderInterface.
|
||||
*/
|
||||
class Loader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* The mimimum supported version of curl.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MINIMUM_CURL_VERSION = '7.34.0';
|
||||
|
||||
/**
|
||||
* The file path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Does $path contain an URL?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isUrl;
|
||||
|
||||
/**
|
||||
* The loaded data.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Is curl available, with a decent version?
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $isCurlSupported;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param string|mixed $path the file path (or an object whose string representation is the file path)
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException throws an InvalidArgumentException is $path is an empty string, or is not an object that has a __toString method
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
if (is_object($path) && !method_exists($path, '__toString')) {
|
||||
throw new InvalidArgumentException(sprintf('$path is an object of file %s which does not implement the __toString method', get_class($path)));
|
||||
}
|
||||
|
||||
$this->path = (string) $path;
|
||||
if ($this->path === '') {
|
||||
throw new InvalidArgumentException('$path is empty');
|
||||
}
|
||||
$this->isUrl = filter_var($this->path, FILTER_VALIDATE_URL) !== false;
|
||||
if (!$this->isUrl) {
|
||||
$this->checkLocalFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\File\LoaderInterface::isLocalFile()
|
||||
*/
|
||||
public function isLocalFile()
|
||||
{
|
||||
return !$this->isUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\File\LoaderInterface::getPath()
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\File\LoaderInterface::hasReadData()
|
||||
*/
|
||||
public function hasReadData()
|
||||
{
|
||||
return $this->data !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @see \Imagine\File\LoaderInterface::getData()
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if (!$this->hasReadData()) {
|
||||
if ($this->isLocalFile()) {
|
||||
$this->data = $this->readLocalFile();
|
||||
} else {
|
||||
$this->data = $this->readRemoteFile();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\File\LoaderInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a local file.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function readLocalFile()
|
||||
{
|
||||
$this->checkLocalFile();
|
||||
$data = @file_get_contents($this->path);
|
||||
if ($data === false) {
|
||||
throw new InvalidArgumentException(sprintf('Failed to read from file %s.', $this->path));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the file exists and it's readable.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
protected function checkLocalFile()
|
||||
{
|
||||
if (!is_file($this->path)) {
|
||||
throw new InvalidArgumentException(sprintf('File %s does not exist.', $this->path));
|
||||
}
|
||||
if (!is_readable($this->path)) {
|
||||
throw new InvalidArgumentException(sprintf('File %s is not readable.', $this->path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a remote file.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function readRemoteFile()
|
||||
{
|
||||
if ($this->isCurlSupported()) {
|
||||
return $this->readRemoteFileWithCurl();
|
||||
}
|
||||
|
||||
return $this->readRemoteFileWithFileGetContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if curl is available and it's a decent version.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isCurlSupported()
|
||||
{
|
||||
if ($this->isCurlSupported === null) {
|
||||
$isCurlSupported = false;
|
||||
if (function_exists('curl_init') && function_exists('curl_version')) {
|
||||
$curlVersion = curl_version();
|
||||
if (is_array($curlVersion) && !empty($curlVersion['version'])) {
|
||||
if (version_compare($curlVersion['version'], static::MINIMUM_CURL_VERSION) >= 0) {
|
||||
$isCurlSupported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->isCurlSupported = $isCurlSupported;
|
||||
}
|
||||
|
||||
return $this->isCurlSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a remote file using the cURL extension.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function readRemoteFileWithCurl()
|
||||
{
|
||||
$curl = @curl_init($this->path);
|
||||
if ($curl === false) {
|
||||
throw new RuntimeException('curl_init() failed.');
|
||||
}
|
||||
if (!@curl_setopt($curl, CURLOPT_RETURNTRANSFER, true)) {
|
||||
throw new RuntimeException('curl_setopt(CURLOPT_RETURNTRANSFER) failed.');
|
||||
}
|
||||
$this->setCurlOptions($curl);
|
||||
|
||||
$response = @curl_exec($curl);
|
||||
if ($response === false) {
|
||||
$errorMessage = curl_error($curl);
|
||||
if ($errorMessage === '') {
|
||||
$errorMessage = 'curl_exec() failed.';
|
||||
}
|
||||
$errorCode = curl_errno($curl);
|
||||
curl_close($curl);
|
||||
throw new RuntimeException($errorMessage, $errorCode);
|
||||
}
|
||||
$responseInfo = curl_getinfo($curl);
|
||||
curl_close($curl);
|
||||
if ($responseInfo['http_code'] == 404) {
|
||||
throw new InvalidArgumentException(sprintf('File %s does not exist.', $this->path));
|
||||
}
|
||||
if ($responseInfo['http_code'] < 200 || $responseInfo['http_code'] >= 300) {
|
||||
throw new InvalidArgumentException(sprintf('Failed to download "%s": %s', $this->path, $responseInfo['http_code']));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set curl options.
|
||||
*
|
||||
*
|
||||
* @param resource $curl
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
protected function setCurlOptions($curl)
|
||||
{
|
||||
if (!@curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept-Encoding: identity'))) {
|
||||
throw new RuntimeException('curl_setopt(CURLOPT_HTTPHEADER) failed.');
|
||||
}
|
||||
if (!@curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true)) {
|
||||
throw new RuntimeException('curl_setopt(CURLOPT_FOLLOWLOCATION) failed.');
|
||||
}
|
||||
if (defined('CURL_SSLVERSION_TLSv1_1')) {
|
||||
if (!@curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1)) {
|
||||
throw new RuntimeException('curl_setopt(CURLOPT_SSLVERSION) failed.');
|
||||
}
|
||||
} else {
|
||||
// Manually checked that CURL_SSLVERSION_TLSv1_1 is 5 for any version of curl from 7.34.0 to 7.61.0
|
||||
// See for example https://github.com/curl/curl/blob/curl-7_34_0/include/curl/curl.h#L1668
|
||||
if (!@curl_setopt($curl, CURLOPT_SSLVERSION, 5)) {
|
||||
throw new RuntimeException('curl_setopt(CURLOPT_SSLVERSION) failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a remote file using the file_get_contents.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function readRemoteFileWithFileGetContents()
|
||||
{
|
||||
$http_response_header = null;
|
||||
$data = @file_get_contents($this->path);
|
||||
if ($data === false) {
|
||||
if (is_array($http_response_header) && isset($http_response_header[0]) && preg_match('/^HTTP\/\d+(?:\.\d+)*\s+(\d+\s+\w.*)/i', $http_response_header[0], $matches)) {
|
||||
throw new InvalidArgumentException(sprintf('Failed to read from URL %s: %s', $this->path, $matches[1]));
|
||||
}
|
||||
throw new InvalidArgumentException(sprintf('Failed to read from URL %s', $this->path));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
50
vendor/imagine/imagine/src/File/LoaderInterface.php
vendored
Normal file
50
vendor/imagine/imagine/src/File/LoaderInterface.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\File;
|
||||
|
||||
/**
|
||||
* Interface for classes that can load local or remote files.
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Is this a local file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocalFile();
|
||||
|
||||
/**
|
||||
* Get the path of the file (local or remote).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Is the binary content already loaded?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasReadData();
|
||||
|
||||
/**
|
||||
* Get the file binary contents.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getData();
|
||||
|
||||
/**
|
||||
* The string representation of this object must be the file path (local or remote).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
68
vendor/imagine/imagine/src/Filter/Advanced/BlackWhite.php
vendored
Normal file
68
vendor/imagine/imagine/src/Filter/Advanced/BlackWhite.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Image\Point;
|
||||
|
||||
/**
|
||||
* This filter calculates, for each pixel of an image, whether it is ligher or darker than a threshold.
|
||||
* If the pixel is lighter than the thresold it will be black, otherwise it will be light.
|
||||
* The result is an image with only black and white pixels (black pixels for ligher colors, white pixels for darker colors).
|
||||
*/
|
||||
class BlackWhite extends OnPixelBased implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Filter\Advanced\Grayscale
|
||||
*/
|
||||
protected $grayScaleFilter;
|
||||
|
||||
/**
|
||||
* Initialize this filter.
|
||||
*
|
||||
* @param int $threshold the dask/light threshold, from 0 (all black) to 255 (all white)
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($threshold)
|
||||
{
|
||||
if (!(0 <= $threshold && $threshold <= 255)) {
|
||||
throw new InvalidArgumentException('$threshold has to be between 0 and 255');
|
||||
}
|
||||
|
||||
$this->grayScaleFilter = new Grayscale();
|
||||
|
||||
$rgb = new RGB();
|
||||
parent::__construct(
|
||||
function (ImageInterface $image, Point $point) use ($threshold, $rgb) {
|
||||
$newRedValue = $image->getColorAt($point)->getValue(ColorInterface::COLOR_RED) < $threshold ? 255 : 0;
|
||||
$image->draw()->dot($point, $rgb->color(array($newRedValue, $newRedValue, $newRedValue)));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\Advanced\OnPixelBased::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$grayScaledImage = $this->grayScaleFilter->apply($image);
|
||||
|
||||
return parent::apply($grayScaledImage);
|
||||
}
|
||||
}
|
||||
100
vendor/imagine/imagine/src/Filter/Advanced/Border.php
vendored
Normal file
100
vendor/imagine/imagine/src/Filter/Advanced/Border.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Point;
|
||||
|
||||
/**
|
||||
* A border filter.
|
||||
*/
|
||||
class Border implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $color;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* Constructs Border filter with given color, width and height.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
* @param int $width Width of the border on the left and right sides of the image
|
||||
* @param int $height Height of the border on the top and bottom sides of the image
|
||||
*/
|
||||
public function __construct(ColorInterface $color, $width = 1, $height = 1)
|
||||
{
|
||||
$this->color = $color;
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$size = $image->getSize();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$draw = $image->draw();
|
||||
|
||||
// Draw top and bottom lines
|
||||
$draw
|
||||
->line(
|
||||
new Point(0, 0),
|
||||
new Point($width - 1, 0),
|
||||
$this->color,
|
||||
$this->height
|
||||
)
|
||||
->line(
|
||||
new Point($width - 1, $height - 1),
|
||||
new Point(0, $height - 1),
|
||||
$this->color,
|
||||
$this->height
|
||||
)
|
||||
;
|
||||
|
||||
// Draw sides
|
||||
$draw
|
||||
->line(
|
||||
new Point(0, 0),
|
||||
new Point(0, $height - 1),
|
||||
$this->color,
|
||||
$this->width
|
||||
)
|
||||
->line(
|
||||
new Point($width - 1, 0),
|
||||
new Point($width - 1, $height - 1),
|
||||
$this->color,
|
||||
$this->width
|
||||
)
|
||||
;
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
91
vendor/imagine/imagine/src/Filter/Advanced/BorderDetection.php
vendored
Normal file
91
vendor/imagine/imagine/src/Filter/Advanced/BorderDetection.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* BorderDetection based on Laplace-Operator. Three different variants are offered:.
|
||||
* <code><pre>
|
||||
* First Second Third
|
||||
* 0, 1, 0 1, 1, 1, -1, 2, -1,
|
||||
* 1, -4, 1 and 1, -8, 1, and 2, -4, 2,
|
||||
* 0, 1, 0 1, 1, 1 -1, 2, -1
|
||||
* </pre></code>.
|
||||
*
|
||||
* Consider to apply this filter on a grayscaled image.
|
||||
*/
|
||||
class BorderDetection extends Neighborhood implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* First variant of the detection matrix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const VARIANT_ONE = 0;
|
||||
|
||||
/**
|
||||
* Second variant of the detection matrix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const VARIANT_TWO = 1;
|
||||
|
||||
/**
|
||||
* Third variant of the detection matrix.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const VARIANT_THREE = 2;
|
||||
|
||||
/**
|
||||
* Initialize this filter.
|
||||
*
|
||||
* @param int $variant One of the BorderDetection::VARIANT_... constants.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException throws an InvalidArgumentException if $variant is not valid
|
||||
*/
|
||||
public function __construct($variant = self::VARIANT_ONE)
|
||||
{
|
||||
$matrix = null;
|
||||
|
||||
switch ($variant) {
|
||||
case self::VARIANT_ONE:
|
||||
$matrix = new Matrix(3, 3, array(
|
||||
0, 1, 0,
|
||||
1, -4, 1,
|
||||
0, 1, 0,
|
||||
));
|
||||
break;
|
||||
case self::VARIANT_TWO:
|
||||
$matrix = new Matrix(3, 3, array(
|
||||
1, 1, 1,
|
||||
1, -8, 1,
|
||||
1, 1, 1,
|
||||
));
|
||||
break;
|
||||
case self::VARIANT_THREE:
|
||||
$matrix = new Matrix(3, 3, array(
|
||||
-1, 2, -1,
|
||||
2, -4, 2,
|
||||
-1, 2, -1,
|
||||
));
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException('Unknown variant ' . $variant);
|
||||
}
|
||||
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
}
|
||||
75
vendor/imagine/imagine/src/Filter/Advanced/Canvas.php
vendored
Normal file
75
vendor/imagine/imagine/src/Filter/Advanced/Canvas.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\ImagineInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* A canvas filter.
|
||||
*/
|
||||
class Canvas implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\BoxInterface
|
||||
*/
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\PointInterface
|
||||
*/
|
||||
private $placement;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $background;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\ImagineInterface
|
||||
*/
|
||||
private $imagine;
|
||||
|
||||
/**
|
||||
* Constructs Canvas filter with given width and height and the placement of the current image inside the new canvas.
|
||||
*
|
||||
* @param \Imagine\Image\ImagineInterface $imagine
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param \Imagine\Image\PointInterface $placement
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $background
|
||||
*/
|
||||
public function __construct(ImagineInterface $imagine, BoxInterface $size, PointInterface $placement = null, ColorInterface $background = null)
|
||||
{
|
||||
$this->imagine = $imagine;
|
||||
$this->size = $size;
|
||||
$this->placement = $placement ?: new Point(0, 0);
|
||||
$this->background = $background;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$canvas = $this->imagine->create($this->size, $this->background);
|
||||
$canvas->paste($image, $this->placement);
|
||||
|
||||
return $canvas;
|
||||
}
|
||||
}
|
||||
30
vendor/imagine/imagine/src/Filter/Advanced/Grayscale.php
vendored
Normal file
30
vendor/imagine/imagine/src/Filter/Advanced/Grayscale.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Point;
|
||||
|
||||
/**
|
||||
* The Grayscale filter calculates the gray-value based on RGB.
|
||||
*/
|
||||
class Grayscale extends OnPixelBased implements FilterInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(function (ImageInterface $image, Point $point) {
|
||||
$color = $image->getColorAt($point);
|
||||
$image->draw()->dot($point, $color->grayscale());
|
||||
});
|
||||
}
|
||||
}
|
||||
33
vendor/imagine/imagine/src/Filter/Advanced/Negation.php
vendored
Normal file
33
vendor/imagine/imagine/src/Filter/Advanced/Negation.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* This filter negates every color of every pixel of an image.
|
||||
*/
|
||||
class Negation implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$image->effects()->negative();
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
100
vendor/imagine/imagine/src/Filter/Advanced/Neighborhood.php
vendored
Normal file
100
vendor/imagine/imagine/src/Filter/Advanced/Neighborhood.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* The Neighborhood filter takes a matrix and calculates the color current pixel based on its neighborhood.
|
||||
*
|
||||
* @example
|
||||
* <code><pre>
|
||||
* a, b, c
|
||||
* Matrix = d, e, f
|
||||
* g, h, i
|
||||
* </pre></code>
|
||||
*
|
||||
* and color{i, j} the color of the pixel at position (i, j). It calculates the color of pixel (x, y) like that:
|
||||
*
|
||||
* <code><pre>
|
||||
* color (x, y) = a * color(x - 1, y - 1) + b * color(x, y - 1) + c * color(x + 1, y - 1)
|
||||
* + d * color(x - 1, y) + e * color(x, y) + f * color(x + 1, y)
|
||||
* + g * color(x - 1, y + 1) + h * color(x, y + 1) + i * color(x + 1, y + 1)
|
||||
* </pre></code>
|
||||
*/
|
||||
class Neighborhood implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Utils\Matrix
|
||||
*/
|
||||
protected $matrix;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param \Imagine\Utils\Matrix $matrix
|
||||
*/
|
||||
public function __construct(Matrix $matrix)
|
||||
{
|
||||
$this->matrix = $matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
// We reduce the usage of methods on the image to dramatically increase the performance of this algorithm.
|
||||
// Really... We need that performance...
|
||||
// Therefore we first build a matrix, that holds the colors of the image.
|
||||
$width = $image->getSize()->getWidth();
|
||||
$height = $image->getSize()->getHeight();
|
||||
$byteData = new Matrix($width, $height);
|
||||
|
||||
for ($y = 0; $y < $height; $y++) {
|
||||
for ($x = 0; $x < $width; $x++) {
|
||||
$byteData->setElementAt($x, $y, $image->getColorAt(new Point($x, $y)));
|
||||
}
|
||||
}
|
||||
|
||||
$dWidth = (int) (($this->matrix->getWidth() - 1) / 2);
|
||||
$dHeight = (int) (($this->matrix->getHeight() - 1) / 2);
|
||||
|
||||
// foreach point, which has a big enough neighborhood
|
||||
for ($y = $dHeight; $y < $height - $dHeight; $y++) {
|
||||
for ($x = $dWidth; $x < $width - $dWidth; $x++) {
|
||||
$currentColor = array_fill(0, count($image->palette()->pixelDefinition()), 0);
|
||||
|
||||
// calculate the new color based on the neighborhood
|
||||
for ($boxY = $y - $dHeight, $matrixY = 0; $boxY <= $y + $dHeight; $boxY++, $matrixY++) {
|
||||
for ($boxX = $x - $dWidth, $matrixX = 0; $boxX <= $x + $dWidth; $boxX++, $matrixX++) {
|
||||
foreach ($image->palette()->pixelDefinition() as $index => $stream) {
|
||||
$currentColor[$index] +=
|
||||
$byteData->getElementAt($boxX, $boxY)->getValue($stream) *
|
||||
$this->matrix->getElementAt($matrixX, $matrixY)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$image->draw()->dot(new Point($x, $y), $image->palette()->color($currentColor));
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
64
vendor/imagine/imagine/src/Filter/Advanced/OnPixelBased.php
vendored
Normal file
64
vendor/imagine/imagine/src/Filter/Advanced/OnPixelBased.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Point;
|
||||
|
||||
/**
|
||||
* The OnPixelBased takes a callable, and for each pixel, this callable is called with the
|
||||
* image (\Imagine\Image\ImageInterface) and the current point (\Imagine\Image\Point).
|
||||
*/
|
||||
class OnPixelBased implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param callable $callback
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
throw new InvalidArgumentException('$callback has to be callable');
|
||||
}
|
||||
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$size = $image->getSize();
|
||||
$w = $size->getWidth();
|
||||
$h = $size->getHeight();
|
||||
for ($y = 0; $y < $h; $y++) {
|
||||
for ($x = 0; $x < $w; $x++) {
|
||||
call_user_func($this->callback, $image, new Point($x, $y));
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
58
vendor/imagine/imagine/src/Filter/Advanced/RelativeResize.php
vendored
Normal file
58
vendor/imagine/imagine/src/Filter/Advanced/RelativeResize.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Advanced;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* The RelativeResize filter allows images to be resized relative to their existing dimensions.
|
||||
*/
|
||||
class RelativeResize implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $parameter;
|
||||
|
||||
/**
|
||||
* Constructs a RelativeResize filter with the given method and argument.
|
||||
*
|
||||
* @param string $method BoxInterface method
|
||||
* @param mixed $parameter Parameter for BoxInterface method
|
||||
*/
|
||||
public function __construct($method, $parameter)
|
||||
{
|
||||
if (!in_array($method, array('heighten', 'increase', 'scale', 'widen'))) {
|
||||
throw new InvalidArgumentException(sprintf('Unsupported method: ', $method));
|
||||
}
|
||||
|
||||
$this->method = $method;
|
||||
$this->parameter = $parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->resize(call_user_func(array($image->getSize(), $this->method), $this->parameter));
|
||||
}
|
||||
}
|
||||
46
vendor/imagine/imagine/src/Filter/Basic/ApplyMask.php
vendored
Normal file
46
vendor/imagine/imagine/src/Filter/Basic/ApplyMask.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* An apply mask filter.
|
||||
*/
|
||||
class ApplyMask implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\ImageInterface
|
||||
*/
|
||||
private $mask;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $mask
|
||||
*/
|
||||
public function __construct(ImageInterface $mask)
|
||||
{
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->applyMask($this->mask);
|
||||
}
|
||||
}
|
||||
133
vendor/imagine/imagine/src/Filter/Basic/Autorotate.php
vendored
Normal file
133
vendor/imagine/imagine/src/Filter/Basic/Autorotate.php
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* Rotates an image automatically based on exif information.
|
||||
*
|
||||
* Your attention please: This filter requires the use of the
|
||||
* ExifMetadataReader to work.
|
||||
*
|
||||
* @see https://imagine.readthedocs.org/en/latest/usage/metadata.html
|
||||
*/
|
||||
class Autorotate implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* Image transformation: flip vertically.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FLIP_VERTICALLY = 'V';
|
||||
|
||||
/**
|
||||
* Image transformation: flip horizontally.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FLIP_HORIZONTALLY = 'H';
|
||||
|
||||
/**
|
||||
* @var string|array|\Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $color;
|
||||
|
||||
/**
|
||||
* @param string|array|\Imagine\Image\Palette\Color\ColorInterface $color A color
|
||||
*/
|
||||
public function __construct($color = '000000')
|
||||
{
|
||||
$this->color = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
foreach ($this->getTransformations($image) as $transformation) {
|
||||
if ($transformation === self::FLIP_HORIZONTALLY) {
|
||||
$image->flipHorizontally();
|
||||
} elseif ($transformation === self::FLIP_VERTICALLY) {
|
||||
$image->flipVertically();
|
||||
} elseif (is_int($transformation)) {
|
||||
$image->rotate($transformation, $this->getColor($image));
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the transformations.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
*
|
||||
* @return array an array containing Autorotate::FLIP_VERTICALLY, Autorotate::FLIP_HORIZONTALLY, rotation degrees
|
||||
*/
|
||||
public function getTransformations(ImageInterface $image)
|
||||
{
|
||||
$transformations = array();
|
||||
$metadata = $image->metadata();
|
||||
switch (isset($metadata['ifd0.Orientation']) ? $metadata['ifd0.Orientation'] : null) {
|
||||
case 1: // top-left
|
||||
break;
|
||||
case 2: // top-right
|
||||
$transformations[] = self::FLIP_HORIZONTALLY;
|
||||
break;
|
||||
case 3: // bottom-right
|
||||
$transformations[] = 180;
|
||||
break;
|
||||
case 4: // bottom-left
|
||||
$transformations[] = self::FLIP_HORIZONTALLY;
|
||||
$transformations[] = 180;
|
||||
break;
|
||||
case 5: // left-top
|
||||
$transformations[] = self::FLIP_HORIZONTALLY;
|
||||
$transformations[] = -90;
|
||||
break;
|
||||
case 6: // right-top
|
||||
$transformations[] = 90;
|
||||
break;
|
||||
case 7: // right-bottom
|
||||
$transformations[] = self::FLIP_HORIZONTALLY;
|
||||
$transformations[] = 90;
|
||||
break;
|
||||
case 8: // left-bottom
|
||||
$transformations[] = -90;
|
||||
break;
|
||||
default: // Invalid orientation
|
||||
break;
|
||||
}
|
||||
|
||||
return $transformations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private function getColor(ImageInterface $image)
|
||||
{
|
||||
if ($this->color instanceof ColorInterface) {
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
return $image->palette()->color($this->color);
|
||||
}
|
||||
}
|
||||
31
vendor/imagine/imagine/src/Filter/Basic/Copy.php
vendored
Normal file
31
vendor/imagine/imagine/src/Filter/Basic/Copy.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A copy filter.
|
||||
*/
|
||||
class Copy implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->copy();
|
||||
}
|
||||
}
|
||||
55
vendor/imagine/imagine/src/Filter/Basic/Crop.php
vendored
Normal file
55
vendor/imagine/imagine/src/Filter/Basic/Crop.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* A crop filter.
|
||||
*/
|
||||
class Crop implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\PointInterface
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\BoxInterface
|
||||
*/
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* Constructs a Crop filter with given x, y, coordinates and crop width and height values.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
*/
|
||||
public function __construct(PointInterface $start, BoxInterface $size)
|
||||
{
|
||||
$this->start = $start;
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->crop($this->start, $this->size);
|
||||
}
|
||||
}
|
||||
45
vendor/imagine/imagine/src/Filter/Basic/Fill.php
vendored
Normal file
45
vendor/imagine/imagine/src/Filter/Basic/Fill.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A fill filter.
|
||||
*/
|
||||
class Fill implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Fill\FillInterface
|
||||
*/
|
||||
private $fill;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\Fill\FillInterface $fill
|
||||
*/
|
||||
public function __construct(FillInterface $fill)
|
||||
{
|
||||
$this->fill = $fill;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->fill($this->fill);
|
||||
}
|
||||
}
|
||||
31
vendor/imagine/imagine/src/Filter/Basic/FlipHorizontally.php
vendored
Normal file
31
vendor/imagine/imagine/src/Filter/Basic/FlipHorizontally.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A "flip horizontally" filter.
|
||||
*/
|
||||
class FlipHorizontally implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->flipHorizontally();
|
||||
}
|
||||
}
|
||||
31
vendor/imagine/imagine/src/Filter/Basic/FlipVertically.php
vendored
Normal file
31
vendor/imagine/imagine/src/Filter/Basic/FlipVertically.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A "flip vertically" filter.
|
||||
*/
|
||||
class FlipVertically implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->flipVertically();
|
||||
}
|
||||
}
|
||||
69
vendor/imagine/imagine/src/Filter/Basic/Paste.php
vendored
Normal file
69
vendor/imagine/imagine/src/Filter/Basic/Paste.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* A paste filter.
|
||||
*/
|
||||
class Paste implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\ImageInterface
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\PointInterface
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* How to paste the image, from 0 (fully transparent) to 100 (fully opaque).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $alpha;
|
||||
|
||||
/**
|
||||
* Constructs a Paste filter with given ImageInterface to paste and x, y
|
||||
* coordinates of target position.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
* @param int $alpha how to paste the image, from 0 (fully transparent) to 100 (fully opaque)
|
||||
*/
|
||||
public function __construct(ImageInterface $image, PointInterface $start, $alpha = 100)
|
||||
{
|
||||
$this->image = $image;
|
||||
$this->start = $start;
|
||||
$alpha = (int) round($alpha);
|
||||
if ($alpha < 0 || $alpha > 100) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$alpha', 0, 100, $alpha));
|
||||
}
|
||||
$this->alpha = $alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->paste($this->image, $this->start, $this->alpha);
|
||||
}
|
||||
}
|
||||
54
vendor/imagine/imagine/src/Filter/Basic/Resize.php
vendored
Normal file
54
vendor/imagine/imagine/src/Filter/Basic/Resize.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A resize filter.
|
||||
*/
|
||||
class Resize implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\BoxInterface
|
||||
*/
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* Constructs Resize filter with given width and height.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param string $filter
|
||||
*/
|
||||
public function __construct(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
$this->size = $size;
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->resize($this->size, $this->filter);
|
||||
}
|
||||
}
|
||||
54
vendor/imagine/imagine/src/Filter/Basic/Rotate.php
vendored
Normal file
54
vendor/imagine/imagine/src/Filter/Basic/Rotate.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* A rotate filter.
|
||||
*/
|
||||
class Rotate implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $angle;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $background;
|
||||
|
||||
/**
|
||||
* Constructs Rotate filter with given angle and background color.
|
||||
*
|
||||
* @param int $angle
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $background
|
||||
*/
|
||||
public function __construct($angle, ColorInterface $background = null)
|
||||
{
|
||||
$this->angle = $angle;
|
||||
$this->background = $background;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->rotate($this->angle, $this->background);
|
||||
}
|
||||
}
|
||||
53
vendor/imagine/imagine/src/Filter/Basic/Save.php
vendored
Normal file
53
vendor/imagine/imagine/src/Filter/Basic/Save.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A save filter.
|
||||
*/
|
||||
class Save implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Constructs Save filter with given path and options.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($path = null, array $options = array())
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->save($this->path, $this->options);
|
||||
}
|
||||
}
|
||||
53
vendor/imagine/imagine/src/Filter/Basic/Show.php
vendored
Normal file
53
vendor/imagine/imagine/src/Filter/Basic/Show.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A show filter.
|
||||
*/
|
||||
class Show implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $format;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Constructs the Show filter with given format and options.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($format, array $options = array())
|
||||
{
|
||||
$this->format = $format;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->show($this->format, $this->options);
|
||||
}
|
||||
}
|
||||
31
vendor/imagine/imagine/src/Filter/Basic/Strip.php
vendored
Normal file
31
vendor/imagine/imagine/src/Filter/Basic/Strip.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A strip filter.
|
||||
*/
|
||||
class Strip implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->strip();
|
||||
}
|
||||
}
|
||||
61
vendor/imagine/imagine/src/Filter/Basic/Thumbnail.php
vendored
Normal file
61
vendor/imagine/imagine/src/Filter/Basic/Thumbnail.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* A thumbnail filter.
|
||||
*/
|
||||
class Thumbnail implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\BoxInterface
|
||||
*/
|
||||
private $size;
|
||||
|
||||
/**
|
||||
* @var int|string
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* Constructs the Thumbnail filter.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param int|string $settings One or more of the ManipulatorInterface::THUMBNAIL_ flags (joined with |). It may be a string for backward compatibility with old constant values that were strings.
|
||||
* @param string $filter See ImageInterface::FILTER_... constants
|
||||
*/
|
||||
public function __construct(BoxInterface $size, $settings = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
$this->size = $size;
|
||||
$this->settings = $settings;
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return $image->thumbnail($this->size, $this->settings, $this->filter);
|
||||
}
|
||||
}
|
||||
74
vendor/imagine/imagine/src/Filter/Basic/WebOptimization.php
vendored
Normal file
74
vendor/imagine/imagine/src/Filter/Basic/WebOptimization.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter\Basic;
|
||||
|
||||
use Imagine\Filter\FilterInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
|
||||
/**
|
||||
* A filter to render web-optimized images.
|
||||
*/
|
||||
class WebOptimization implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\RGB
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @var string|callable|null
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param string|callable|null $path
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($path = null, array $options = array())
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->options = array_replace(array(
|
||||
'resolution-units' => ImageInterface::RESOLUTION_PIXELSPERINCH,
|
||||
'resolution-y' => 72,
|
||||
'resolution-x' => 72,
|
||||
), $options);
|
||||
$this->palette = new RGB();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
$image
|
||||
->usePalette($this->palette)
|
||||
->strip();
|
||||
|
||||
if (is_callable($this->path)) {
|
||||
$path = call_user_func($this->path, $image);
|
||||
} elseif (null !== $this->path) {
|
||||
$path = $this->path;
|
||||
} else {
|
||||
return $image;
|
||||
}
|
||||
|
||||
return $image->save($path, $this->options);
|
||||
}
|
||||
}
|
||||
29
vendor/imagine/imagine/src/Filter/FilterInterface.php
vendored
Normal file
29
vendor/imagine/imagine/src/Filter/FilterInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter;
|
||||
|
||||
use Imagine\Image\ImageInterface;
|
||||
|
||||
/**
|
||||
* Interface for imagine filters.
|
||||
*/
|
||||
interface FilterInterface
|
||||
{
|
||||
/**
|
||||
* Applies scheduled transformation to an ImageInterface instance.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface returns the processed ImageInterface instance
|
||||
*/
|
||||
public function apply(ImageInterface $image);
|
||||
}
|
||||
54
vendor/imagine/imagine/src/Filter/ImagineAware.php
vendored
Normal file
54
vendor/imagine/imagine/src/Filter/ImagineAware.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Image\ImagineInterface;
|
||||
|
||||
/**
|
||||
* ImagineAware base class.
|
||||
*/
|
||||
abstract class ImagineAware implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* An ImagineInterface instance.
|
||||
*
|
||||
* @var \Imagine\Image\ImagineInterface
|
||||
*/
|
||||
private $imagine;
|
||||
|
||||
/**
|
||||
* Set ImagineInterface instance.
|
||||
*
|
||||
* @param \Imagine\Image\ImagineInterface $imagine An ImagineInterface instance
|
||||
*/
|
||||
public function setImagine(ImagineInterface $imagine)
|
||||
{
|
||||
$this->imagine = $imagine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ImagineInterface instance.
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return \Imagine\Image\ImagineInterface
|
||||
*/
|
||||
public function getImagine()
|
||||
{
|
||||
if (!$this->imagine instanceof ImagineInterface) {
|
||||
throw new InvalidArgumentException(sprintf('In order to use %s pass an Imagine\Image\ImagineInterface instance to filter constructor', get_class($this)));
|
||||
}
|
||||
|
||||
return $this->imagine;
|
||||
}
|
||||
}
|
||||
268
vendor/imagine/imagine/src/Filter/Transformation.php
vendored
Normal file
268
vendor/imagine/imagine/src/Filter/Transformation.php
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Filter;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Filter\Basic\ApplyMask;
|
||||
use Imagine\Filter\Basic\Copy;
|
||||
use Imagine\Filter\Basic\Crop;
|
||||
use Imagine\Filter\Basic\Fill;
|
||||
use Imagine\Filter\Basic\FlipHorizontally;
|
||||
use Imagine\Filter\Basic\FlipVertically;
|
||||
use Imagine\Filter\Basic\Paste;
|
||||
use Imagine\Filter\Basic\Resize;
|
||||
use Imagine\Filter\Basic\Rotate;
|
||||
use Imagine\Filter\Basic\Save;
|
||||
use Imagine\Filter\Basic\Show;
|
||||
use Imagine\Filter\Basic\Strip;
|
||||
use Imagine\Filter\Basic\Thumbnail;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\ImagineInterface;
|
||||
use Imagine\Image\ManipulatorInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* A transformation filter.
|
||||
*/
|
||||
final class Transformation implements FilterInterface, ManipulatorInterface
|
||||
{
|
||||
/**
|
||||
* @var array[\Imagine\Filter\FilterInterface[]]
|
||||
*/
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
* @var array[\Imagine\Filter\FilterInterface[]]|null
|
||||
*/
|
||||
private $sorted;
|
||||
|
||||
/**
|
||||
* An ImagineInterface instance.
|
||||
*
|
||||
* @var \Imagine\Image\ImageInterface|null
|
||||
*/
|
||||
private $imagine;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface|null $imagine An ImagineInterface instance
|
||||
*/
|
||||
public function __construct(ImagineInterface $imagine = null)
|
||||
{
|
||||
$this->imagine = $imagine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a given FilterInterface onto given ImageInterface and returns modified ImageInterface.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
* @param \Imagine\Filter\FilterInterface $filter
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function applyFilter(ImageInterface $image, FilterInterface $filter)
|
||||
{
|
||||
if ($filter instanceof ImagineAware) {
|
||||
if ($this->imagine === null) {
|
||||
throw new InvalidArgumentException(sprintf('In order to use %s pass an Imagine\Image\ImagineInterface instance to Transformation constructor', get_class($filter)));
|
||||
}
|
||||
$filter->setImagine($this->imagine);
|
||||
}
|
||||
|
||||
return $filter->apply($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of filters sorted by their priority. Filters with same priority will be returned in the order they were added.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
if (null === $this->sorted) {
|
||||
if (!empty($this->filters)) {
|
||||
ksort($this->filters);
|
||||
$this->sorted = call_user_func_array('array_merge', $this->filters);
|
||||
} else {
|
||||
$this->sorted = array();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Filter\FilterInterface::apply()
|
||||
*/
|
||||
public function apply(ImageInterface $image)
|
||||
{
|
||||
return array_reduce(
|
||||
$this->getFilters(),
|
||||
array($this, 'applyFilter'),
|
||||
$image
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::copy()
|
||||
*/
|
||||
public function copy()
|
||||
{
|
||||
return $this->add(new Copy());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::crop()
|
||||
*/
|
||||
public function crop(PointInterface $start, BoxInterface $size)
|
||||
{
|
||||
return $this->add(new Crop($start, $size));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipHorizontally()
|
||||
*/
|
||||
public function flipHorizontally()
|
||||
{
|
||||
return $this->add(new FlipHorizontally());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipVertically()
|
||||
*/
|
||||
public function flipVertically()
|
||||
{
|
||||
return $this->add(new FlipVertically());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::strip()
|
||||
*/
|
||||
public function strip()
|
||||
{
|
||||
return $this->add(new Strip());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::paste()
|
||||
*/
|
||||
public function paste(ImageInterface $image, PointInterface $start, $alpha = 100)
|
||||
{
|
||||
return $this->add(new Paste($image, $start, $alpha));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::applyMask()
|
||||
*/
|
||||
public function applyMask(ImageInterface $mask)
|
||||
{
|
||||
return $this->add(new ApplyMask($mask));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::fill()
|
||||
*/
|
||||
public function fill(FillInterface $fill)
|
||||
{
|
||||
return $this->add(new Fill($fill));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::resize()
|
||||
*/
|
||||
public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
return $this->add(new Resize($size, $filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::rotate()
|
||||
*/
|
||||
public function rotate($angle, ColorInterface $background = null)
|
||||
{
|
||||
return $this->add(new Rotate($angle, $background));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::save()
|
||||
*/
|
||||
public function save($path = null, array $options = array())
|
||||
{
|
||||
return $this->add(new Save($path, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::show()
|
||||
*/
|
||||
public function show($format, array $options = array())
|
||||
{
|
||||
return $this->add(new Show($format, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::thumbnail()
|
||||
*/
|
||||
public function thumbnail(BoxInterface $size, $settings = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
return $this->add(new Thumbnail($size, $settings, $filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a given FilterInterface in an internal array of filters for later application to an instance of ImageInterface.
|
||||
*
|
||||
* @param \Imagine\Filter\FilterInterface $filter
|
||||
* @param int $priority
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add(FilterInterface $filter, $priority = 0)
|
||||
{
|
||||
$this->filters[$priority][] = $filter;
|
||||
$this->sorted = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
422
vendor/imagine/imagine/src/Gd/Drawer.php
vendored
Normal file
422
vendor/imagine/imagine/src/Gd/Drawer.php
vendored
Normal file
@@ -0,0 +1,422 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Draw\DrawerInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Drawer implementation using the GD PHP extension.
|
||||
*/
|
||||
final class Drawer implements DrawerInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $info;
|
||||
|
||||
/**
|
||||
* Constructs Drawer with a given gd image resource.
|
||||
*
|
||||
* @param resource $resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
$this->loadGdInfo();
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::arc()
|
||||
*/
|
||||
public function arc(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw arc operation failed');
|
||||
}
|
||||
|
||||
if (false === imagearc($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $start, $end, $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw arc operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw arc operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function does not work properly because of a bug in GD.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::chord()
|
||||
*/
|
||||
public function chord(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
|
||||
if ($fill) {
|
||||
$style = IMG_ARC_CHORD;
|
||||
if (false === imagefilledarc($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $start, $end, $this->getColor($color), $style)) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
} else {
|
||||
foreach (array(IMG_ARC_NOFILL, IMG_ARC_NOFILL | IMG_ARC_CHORD) as $style) {
|
||||
if (false === imagefilledarc($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $start, $end, $this->getColor($color), $style)) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::circle()
|
||||
*/
|
||||
public function circle(PointInterface $center, $radius, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$diameter = $radius * 2;
|
||||
|
||||
return $this->ellipse($center, new Box($diameter, $diameter), $color, $fill, $thickness);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::ellipse()
|
||||
*/
|
||||
public function ellipse(PointInterface $center, BoxInterface $size, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
if (function_exists('imageantialias')) {
|
||||
imageantialias($this->resource, true);
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if ($fill) {
|
||||
$callback = 'imagefilledellipse';
|
||||
} else {
|
||||
$callback = 'imageellipse';
|
||||
}
|
||||
|
||||
if (function_exists('imageantialias')) {
|
||||
imageantialias($this->resource, true);
|
||||
}
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw ellipse operation failed');
|
||||
}
|
||||
|
||||
if (function_exists('imageantialias')) {
|
||||
imageantialias($this->resource, true);
|
||||
}
|
||||
if (false === $callback($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw ellipse operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw ellipse operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::line()
|
||||
*/
|
||||
public function line(PointInterface $start, PointInterface $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw line operation failed');
|
||||
}
|
||||
|
||||
if (false === imageline($this->resource, $start->getX(), $start->getY(), $end->getX(), $end->getY(), $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw line operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw line operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::pieSlice()
|
||||
*/
|
||||
public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if ($fill) {
|
||||
$style = IMG_ARC_EDGED;
|
||||
} else {
|
||||
$style = IMG_ARC_EDGED | IMG_ARC_NOFILL;
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
|
||||
if (false === imagefilledarc($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $start, $end, $this->getColor($color), $style)) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw chord operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::dot()
|
||||
*/
|
||||
public function dot(PointInterface $position, ColorInterface $color)
|
||||
{
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw point operation failed');
|
||||
}
|
||||
|
||||
if (false === imagesetpixel($this->resource, $position->getX(), $position->getY(), $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw point operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw point operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::rectangle()
|
||||
*/
|
||||
public function rectangle(PointInterface $leftTop, PointInterface $rightBottom, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
$minX = min($leftTop->getX(), $rightBottom->getX());
|
||||
$maxX = max($leftTop->getX(), $rightBottom->getX());
|
||||
$minY = min($leftTop->getY(), $rightBottom->getY());
|
||||
$maxY = max($leftTop->getY(), $rightBottom->getY());
|
||||
|
||||
if ($fill) {
|
||||
$callback = 'imagefilledrectangle';
|
||||
} else {
|
||||
$callback = 'imagerectangle';
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
if (false === $callback($this->resource, $minX, $minY, $maxX, $maxY, $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::polygon()
|
||||
*/
|
||||
public function polygon(array $coordinates, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
imagesetthickness($this->resource, $thickness);
|
||||
|
||||
if (count($coordinates) < 3) {
|
||||
throw new InvalidArgumentException(sprintf('A polygon must consist of at least 3 points, %d given', count($coordinates)));
|
||||
}
|
||||
|
||||
$points = call_user_func_array('array_merge', array_map(function (PointInterface $p) {
|
||||
return array($p->getX(), $p->getY());
|
||||
}, $coordinates));
|
||||
|
||||
if ($fill) {
|
||||
$callback = 'imagefilledpolygon';
|
||||
} else {
|
||||
$callback = 'imagepolygon';
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
if (false === $callback($this->resource, $points, count($coordinates), $this->getColor($color))) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Draw polygon operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::text()
|
||||
*/
|
||||
public function text($string, AbstractFont $font, PointInterface $position, $angle = 0, $width = null)
|
||||
{
|
||||
if (!$this->info['FreeType Support']) {
|
||||
throw new RuntimeException('GD is not compiled with FreeType support');
|
||||
}
|
||||
|
||||
$angle = -1 * $angle;
|
||||
$fontsize = $font->getSize();
|
||||
$fontfile = $font->getFile();
|
||||
$x = $position->getX();
|
||||
$y = $position->getY() + $fontsize;
|
||||
|
||||
if ($width !== null) {
|
||||
$string = $font->wrapText($string, $width, $angle);
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Font mask operation failed');
|
||||
}
|
||||
|
||||
if ($fontfile && DIRECTORY_SEPARATOR === '\\') {
|
||||
// On Windows imagefttext() throws a "Could not find/open font" error if $fontfile is not an absolute path.
|
||||
$fontfileRealpath = realpath($fontfile);
|
||||
if ($fontfileRealpath !== false) {
|
||||
$fontfile = $fontfileRealpath;
|
||||
}
|
||||
}
|
||||
if (false === imagefttext($this->resource, $fontsize, $angle, $x, $y, $this->getColor($font->getColor()), $fontfile, $string)) {
|
||||
imagealphablending($this->resource, false);
|
||||
throw new RuntimeException('Font mask operation failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, false)) {
|
||||
throw new RuntimeException('Font mask operation failed');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a GD color from Color instance.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function getColor(ColorInterface $color)
|
||||
{
|
||||
if (!$color instanceof RGBColor) {
|
||||
throw new InvalidArgumentException('GD driver only supports RGB colors');
|
||||
}
|
||||
|
||||
$gdColor = imagecolorallocatealpha($this->resource, $color->getRed(), $color->getGreen(), $color->getBlue(), (100 - $color->getAlpha()) * 127 / 100);
|
||||
if (false === $gdColor) {
|
||||
throw new RuntimeException(sprintf('Unable to allocate color "RGB(%s, %s, %s)" with transparency of %d percent', $color->getRed(), $color->getGreen(), $color->getBlue(), $color->getAlpha()));
|
||||
}
|
||||
|
||||
return $gdColor;
|
||||
}
|
||||
|
||||
private function loadGdInfo()
|
||||
{
|
||||
if (!function_exists('gd_info')) {
|
||||
throw new RuntimeException('Gd not installed');
|
||||
}
|
||||
|
||||
$this->info = gd_info();
|
||||
}
|
||||
}
|
||||
166
vendor/imagine/imagine/src/Gd/Effects.php
vendored
Normal file
166
vendor/imagine/imagine/src/Gd/Effects.php
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Effects\EffectsInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* Effects implementation using the GD PHP extension.
|
||||
*/
|
||||
class Effects implements EffectsInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param resource $resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::gamma()
|
||||
*/
|
||||
public function gamma($correction)
|
||||
{
|
||||
if (false === imagegammacorrect($this->resource, 1.0, $correction)) {
|
||||
throw new RuntimeException('Failed to apply gamma correction to the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::negative()
|
||||
*/
|
||||
public function negative()
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_NEGATE)) {
|
||||
throw new RuntimeException('Failed to negate the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_GRAYSCALE)) {
|
||||
throw new RuntimeException('Failed to grayscale the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::colorize()
|
||||
*/
|
||||
public function colorize(ColorInterface $color)
|
||||
{
|
||||
if (!$color instanceof RGBColor) {
|
||||
throw new RuntimeException('Colorize effects only accepts RGB color in GD context');
|
||||
}
|
||||
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_COLORIZE, $color->getRed(), $color->getGreen(), $color->getBlue())) {
|
||||
throw new RuntimeException('Failed to colorize the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::sharpen()
|
||||
*/
|
||||
public function sharpen()
|
||||
{
|
||||
$sharpenMatrix = array(array(-1, -1, -1), array(-1, 16, -1), array(-1, -1, -1));
|
||||
$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
|
||||
|
||||
if (false === imageconvolution($this->resource, $sharpenMatrix, $divisor, 0)) {
|
||||
throw new RuntimeException('Failed to sharpen the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::blur()
|
||||
*/
|
||||
public function blur($sigma = 1)
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_GAUSSIAN_BLUR)) {
|
||||
throw new RuntimeException('Failed to blur the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::brightness()
|
||||
*/
|
||||
public function brightness($brightness)
|
||||
{
|
||||
$gdBrightness = (int) round($brightness / 100 * 255);
|
||||
if ($gdBrightness < -255 || $gdBrightness > 255) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$brightness', -100, 100, $brightness));
|
||||
}
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_BRIGHTNESS, $gdBrightness)) {
|
||||
throw new RuntimeException('Failed to brightness the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::convolve()
|
||||
*/
|
||||
public function convolve(Matrix $matrix)
|
||||
{
|
||||
if ($matrix->getWidth() !== 3 || $matrix->getHeight() !== 3) {
|
||||
throw new InvalidArgumentException(sprintf('A convolution matrix must be 3x3 (%dx%d provided).', $matrix->getWidth(), $matrix->getHeight()));
|
||||
}
|
||||
if (false === imageconvolution($this->resource, $matrix->getMatrix(), 1, 0)) {
|
||||
throw new RuntimeException('Failed to convolve the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
50
vendor/imagine/imagine/src/Gd/Font.php
vendored
Normal file
50
vendor/imagine/imagine/src/Gd/Font.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\AbstractFont;
|
||||
|
||||
/**
|
||||
* Font implementation using the GD library.
|
||||
*/
|
||||
final class Font extends AbstractFont
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::box()
|
||||
*/
|
||||
public function box($string, $angle = 0)
|
||||
{
|
||||
if (!function_exists('imageftbbox')) {
|
||||
throw new RuntimeException('GD must have been compiled with `--with-freetype-dir` option to use the Font feature.');
|
||||
}
|
||||
$fontfile = $this->file;
|
||||
if ($fontfile && DIRECTORY_SEPARATOR === '\\') {
|
||||
// On Windows imageftbbox() throws a "Could not find/open font" error if $fontfile is not an absolute path.
|
||||
$fontfileRealpath = realpath($fontfile);
|
||||
if ($fontfileRealpath !== false) {
|
||||
$fontfile = $fontfileRealpath;
|
||||
}
|
||||
}
|
||||
|
||||
$angle = -1 * $angle;
|
||||
$info = imageftbbox($this->size, $angle, $fontfile, $string);
|
||||
$xs = array($info[0], $info[2], $info[4], $info[6]);
|
||||
$ys = array($info[1], $info[3], $info[5], $info[7]);
|
||||
$width = abs(max($xs) - min($xs));
|
||||
$height = abs(max($ys) - min($ys));
|
||||
|
||||
return $this->getClassFactory()->createBox($width, $height);
|
||||
}
|
||||
}
|
||||
818
vendor/imagine/imagine/src/Gd/Image.php
vendored
Normal file
818
vendor/imagine/imagine/src/Gd/Image.php
vendored
Normal file
@@ -0,0 +1,818 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\AbstractImage;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
use Imagine\Utils\ErrorHandling;
|
||||
|
||||
/**
|
||||
* Image implementation using the GD library.
|
||||
*/
|
||||
final class Image extends AbstractImage
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Gd\Layers|null
|
||||
*/
|
||||
private $layers;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* Constructs a new Image instance.
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*/
|
||||
public function __construct($resource, PaletteInterface $palette, MetadataBag $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
$this->palette = $palette;
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the current image resource is destroyed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_resource($this->resource) && 'gd' === get_resource_type($this->resource)) {
|
||||
imagedestroy($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\AbstractImage::__clone()
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
parent::__clone();
|
||||
$size = $this->getSize();
|
||||
$copy = $this->createImage($size, 'copy');
|
||||
if (false === imagecopy($copy, $this->resource, 0, 0, 0, 0, $size->getWidth(), $size->getHeight())) {
|
||||
imagedestroy($copy);
|
||||
throw new RuntimeException('Image copy operation failed');
|
||||
}
|
||||
$this->resource = $copy;
|
||||
$this->palette = clone $this->palette;
|
||||
if ($this->layers !== null) {
|
||||
$this->layers = $this->getClassFactory()->createLayers(ClassFactoryInterface::HANDLE_GD, $this, $this->layers->key());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Gd resource.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getGdResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::copy()
|
||||
*/
|
||||
final public function copy()
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::crop()
|
||||
*/
|
||||
final public function crop(PointInterface $start, BoxInterface $size)
|
||||
{
|
||||
if (!$start->in($this->getSize())) {
|
||||
throw new OutOfBoundsException('Crop coordinates must start at minimum 0, 0 position from top left corner, crop height and width must be positive integers and must not exceed the current image borders');
|
||||
}
|
||||
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$dest = $this->createImage($size, 'crop');
|
||||
|
||||
if (false === imagecopy($dest, $this->resource, 0, 0, $start->getX(), $start->getY(), $width, $height)) {
|
||||
imagedestroy($dest);
|
||||
throw new RuntimeException('Image crop operation failed');
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::paste()
|
||||
*/
|
||||
final public function paste(ImageInterface $image, PointInterface $start, $alpha = 100)
|
||||
{
|
||||
if (!$image instanceof self) {
|
||||
throw new InvalidArgumentException(sprintf('Gd\Image can only paste() Gd\Image instances, %s given', get_class($image)));
|
||||
}
|
||||
|
||||
$alpha = (int) round($alpha);
|
||||
if ($alpha < 0 || $alpha > 100) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$alpha', 0, 100, $alpha));
|
||||
}
|
||||
|
||||
$size = $image->getSize();
|
||||
|
||||
if ($alpha === 100) {
|
||||
imagealphablending($this->resource, true);
|
||||
imagealphablending($image->resource, true);
|
||||
|
||||
$success = imagecopy($this->resource, $image->resource, $start->getX(), $start->getY(), 0, 0, $size->getWidth(), $size->getHeight());
|
||||
|
||||
imagealphablending($this->resource, false);
|
||||
imagealphablending($image->resource, false);
|
||||
|
||||
if ($success === false) {
|
||||
throw new RuntimeException('Image paste operation failed');
|
||||
}
|
||||
} elseif ($alpha > 0) {
|
||||
if (false === imagecopymerge(/*dst_im*/$this->resource, /*src_im*/$image->resource, /*dst_x*/$start->getX(), /*dst_y*/$start->getY(), /*src_x*/0, /*src_y*/0, /*src_w*/$size->getWidth(), /*src_h*/$size->getHeight(), /*pct*/$alpha)) {
|
||||
throw new RuntimeException('Image paste operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::resize()
|
||||
*/
|
||||
final public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
if (ImageInterface::FILTER_UNDEFINED !== $filter) {
|
||||
throw new InvalidArgumentException('Unsupported filter type, GD only supports ImageInterface::FILTER_UNDEFINED filter');
|
||||
}
|
||||
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$dest = $this->createImage($size, 'resize');
|
||||
|
||||
imagealphablending($this->resource, true);
|
||||
imagealphablending($dest, true);
|
||||
|
||||
$success = imagecopyresampled($dest, $this->resource, 0, 0, 0, 0, $width, $height, imagesx($this->resource), imagesy($this->resource));
|
||||
|
||||
imagealphablending($this->resource, false);
|
||||
imagealphablending($dest, false);
|
||||
|
||||
if ($success === false) {
|
||||
imagedestroy($dest);
|
||||
throw new RuntimeException('Image resize operation failed');
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::rotate()
|
||||
*/
|
||||
final public function rotate($angle, ColorInterface $background = null)
|
||||
{
|
||||
if ($background === null) {
|
||||
$background = $this->palette->color('fff');
|
||||
}
|
||||
$color = $this->getColor($background);
|
||||
$resource = imagerotate($this->resource, -1 * $angle, $color);
|
||||
|
||||
if (false === $resource) {
|
||||
throw new RuntimeException('Image rotate operation failed');
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
$this->resource = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::save()
|
||||
*/
|
||||
final public function save($path = null, array $options = array())
|
||||
{
|
||||
$path = null === $path ? (isset($this->metadata['filepath']) ? $this->metadata['filepath'] : $path) : $path;
|
||||
|
||||
if (null === $path) {
|
||||
throw new RuntimeException('You can omit save path only if image has been open from a file');
|
||||
}
|
||||
|
||||
if (isset($options['format'])) {
|
||||
$format = $options['format'];
|
||||
} elseif ('' !== $extension = pathinfo($path, \PATHINFO_EXTENSION)) {
|
||||
$format = $extension;
|
||||
} else {
|
||||
$originalPath = isset($this->metadata['filepath']) ? $this->metadata['filepath'] : null;
|
||||
$format = pathinfo($originalPath, \PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
$this->saveOrOutput($format, $options, $path);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::show()
|
||||
*/
|
||||
public function show($format, array $options = array())
|
||||
{
|
||||
header('Content-type: ' . $this->getMimeType($format));
|
||||
|
||||
$this->saveOrOutput($format, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::get()
|
||||
*/
|
||||
public function get($format, array $options = array())
|
||||
{
|
||||
ob_start();
|
||||
$this->saveOrOutput($format, $options);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->get('png');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipHorizontally()
|
||||
*/
|
||||
final public function flipHorizontally()
|
||||
{
|
||||
if (function_exists('imageflip')) {
|
||||
imageflip($this->resource, IMG_FLIP_HORIZONTAL);
|
||||
} else {
|
||||
$size = $this->getSize();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
$dest = $this->createImage($size, 'flip');
|
||||
|
||||
for ($i = 0; $i < $width; $i++) {
|
||||
if (false === imagecopy($dest, $this->resource, $i, 0, ($width - 1) - $i, 0, 1, $height)) {
|
||||
imagedestroy($dest);
|
||||
throw new RuntimeException('Horizontal flip operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipVertically()
|
||||
*/
|
||||
final public function flipVertically()
|
||||
{
|
||||
if (function_exists('imageflip')) {
|
||||
imageflip($this->resource, IMG_FLIP_VERTICAL);
|
||||
} else {
|
||||
$size = $this->getSize();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
$dest = $this->createImage($size, 'flip');
|
||||
|
||||
for ($i = 0; $i < $height; $i++) {
|
||||
if (false === imagecopy($dest, $this->resource, 0, $i, 0, ($height - 1) - $i, $width, 1)) {
|
||||
imagedestroy($dest);
|
||||
throw new RuntimeException('Vertical flip operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::strip()
|
||||
*/
|
||||
final public function strip()
|
||||
{
|
||||
// GD strips profiles and comment, so there's nothing to do here
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::draw()
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
return $this->getClassFactory()->createDrawer(ClassFactoryInterface::HANDLE_GD, $this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::effects()
|
||||
*/
|
||||
public function effects()
|
||||
{
|
||||
return $this->getClassFactory()->createEffects(ClassFactoryInterface::HANDLE_GD, $this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::getSize()
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->getClassFactory()->createBox(imagesx($this->resource), imagesy($this->resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::applyMask()
|
||||
*/
|
||||
public function applyMask(ImageInterface $mask)
|
||||
{
|
||||
if (!$mask instanceof self) {
|
||||
throw new InvalidArgumentException('Cannot mask non-gd images');
|
||||
}
|
||||
|
||||
$size = $this->getSize();
|
||||
$maskSize = $mask->getSize();
|
||||
|
||||
if ($size != $maskSize) {
|
||||
throw new InvalidArgumentException(sprintf('The given mask doesn\'t match current image\'s size, Current mask\'s dimensions are %s, while image\'s dimensions are %s', $maskSize, $size));
|
||||
}
|
||||
|
||||
for ($x = 0, $width = $size->getWidth(); $x < $width; $x++) {
|
||||
for ($y = 0, $height = $size->getHeight(); $y < $height; $y++) {
|
||||
$position = new Point($x, $y);
|
||||
$color = $this->getColorAt($position);
|
||||
$maskColor = $mask->getColorAt($position);
|
||||
$round = (int) round(max($color->getAlpha(), (100 - $color->getAlpha()) * $maskColor->getRed() / 255));
|
||||
|
||||
if (false === imagesetpixel($this->resource, $x, $y, $this->getColor($color->dissolve($round - $color->getAlpha())))) {
|
||||
throw new RuntimeException('Apply mask operation failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::fill()
|
||||
*/
|
||||
public function fill(FillInterface $fill)
|
||||
{
|
||||
$size = $this->getSize();
|
||||
|
||||
for ($x = 0, $width = $size->getWidth(); $x < $width; $x++) {
|
||||
for ($y = 0, $height = $size->getHeight(); $y < $height; $y++) {
|
||||
if (false === imagesetpixel($this->resource, $x, $y, $this->getColor($fill->getColor(new Point($x, $y))))) {
|
||||
throw new RuntimeException('Fill operation failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::mask()
|
||||
*/
|
||||
public function mask()
|
||||
{
|
||||
$mask = $this->copy();
|
||||
|
||||
if (false === imagefilter($mask->resource, IMG_FILTER_GRAYSCALE)) {
|
||||
throw new RuntimeException('Mask operation failed');
|
||||
}
|
||||
|
||||
return $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::histogram()
|
||||
*/
|
||||
public function histogram()
|
||||
{
|
||||
$size = $this->getSize();
|
||||
$colors = array();
|
||||
|
||||
for ($x = 0, $width = $size->getWidth(); $x < $width; $x++) {
|
||||
for ($y = 0, $height = $size->getHeight(); $y < $height; $y++) {
|
||||
$colors[] = $this->getColorAt(new Point($x, $y));
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::getColorAt()
|
||||
*/
|
||||
public function getColorAt(PointInterface $point)
|
||||
{
|
||||
if (!$point->in($this->getSize())) {
|
||||
throw new RuntimeException(sprintf('Error getting color at point [%s,%s]. The point must be inside the image of size [%s,%s]', $point->getX(), $point->getY(), $this->getSize()->getWidth(), $this->getSize()->getHeight()));
|
||||
}
|
||||
|
||||
$index = imagecolorat($this->resource, $point->getX(), $point->getY());
|
||||
$info = imagecolorsforindex($this->resource, $index);
|
||||
|
||||
return $this->palette->color(array($info['red'], $info['green'], $info['blue']), max(min(100 - (int) round($info['alpha'] / 127 * 100), 100), 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::layers()
|
||||
*/
|
||||
public function layers()
|
||||
{
|
||||
if (null === $this->layers) {
|
||||
$this->layers = $this->getClassFactory()->createLayers(ClassFactoryInterface::HANDLE_GD, $this);
|
||||
}
|
||||
|
||||
return $this->layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::interlace()
|
||||
*/
|
||||
public function interlace($scheme)
|
||||
{
|
||||
static $supportedInterlaceSchemes = array(
|
||||
ImageInterface::INTERLACE_NONE => 0,
|
||||
ImageInterface::INTERLACE_LINE => 1,
|
||||
ImageInterface::INTERLACE_PLANE => 1,
|
||||
ImageInterface::INTERLACE_PARTITION => 1,
|
||||
);
|
||||
|
||||
if (!array_key_exists($scheme, $supportedInterlaceSchemes)) {
|
||||
throw new InvalidArgumentException('Unsupported interlace type');
|
||||
}
|
||||
|
||||
imageinterlace($this->resource, $supportedInterlaceSchemes[$scheme]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::palette()
|
||||
*/
|
||||
public function palette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::profile()
|
||||
*/
|
||||
public function profile(ProfileInterface $profile)
|
||||
{
|
||||
throw new RuntimeException('GD driver does not support color profiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::usePalette()
|
||||
*/
|
||||
public function usePalette(PaletteInterface $palette)
|
||||
{
|
||||
if (!$palette instanceof RGB) {
|
||||
throw new RuntimeException('GD driver only supports RGB palette');
|
||||
}
|
||||
|
||||
$this->palette = $palette;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs save or show operation using one of GD's image... functions.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $options
|
||||
* @param string $filename
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
private function saveOrOutput($format, array $options, $filename = null)
|
||||
{
|
||||
$format = $this->normalizeFormat($format);
|
||||
|
||||
if (!$this->supported($format)) {
|
||||
throw new InvalidArgumentException(sprintf('Saving image in "%s" format is not supported, please use one of the following extensions: "%s"', $format, implode('", "', $this->supported())));
|
||||
}
|
||||
|
||||
$save = 'image' . $format;
|
||||
$args = array(&$this->resource, $filename);
|
||||
|
||||
switch ($format) {
|
||||
case 'bmp':
|
||||
if (isset($options['compressed'])) {
|
||||
$args[] = (bool) $options['compressed'];
|
||||
}
|
||||
break;
|
||||
case 'jpeg':
|
||||
if (!isset($options['jpeg_quality'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['jpeg_quality'] = $options['quality'];
|
||||
}
|
||||
}
|
||||
if (isset($options['jpeg_quality'])) {
|
||||
$args[] = $options['jpeg_quality'];
|
||||
}
|
||||
break;
|
||||
case 'png':
|
||||
if (!isset($options['png_compression_level'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['png_compression_level'] = round((100 - $options['quality']) * 9 / 100);
|
||||
}
|
||||
}
|
||||
if (isset($options['png_compression_level'])) {
|
||||
if ($options['png_compression_level'] < 0 || $options['png_compression_level'] > 9) {
|
||||
throw new InvalidArgumentException('png_compression_level option should be an integer from 0 to 9');
|
||||
}
|
||||
$args[] = $options['png_compression_level'];
|
||||
} else {
|
||||
$args[] = -1; // use default level
|
||||
}
|
||||
if (!isset($options['png_compression_filter'])) {
|
||||
if (isset($options['filters'])) {
|
||||
$options['png_compression_filter'] = $options['filters'];
|
||||
}
|
||||
}
|
||||
if (isset($options['png_compression_filter'])) {
|
||||
if (~PNG_ALL_FILTERS & $options['png_compression_filter']) {
|
||||
throw new InvalidArgumentException('png_compression_filter option should be a combination of the PNG_FILTER_XXX constants');
|
||||
}
|
||||
$args[] = $options['png_compression_filter'];
|
||||
}
|
||||
break;
|
||||
case 'wbmp':
|
||||
case 'xbm':
|
||||
if (isset($options['foreground'])) {
|
||||
$args[] = $options['foreground'];
|
||||
}
|
||||
break;
|
||||
case 'webp':
|
||||
if (!isset($options['webp_quality'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['webp_quality'] = $options['quality'];
|
||||
}
|
||||
}
|
||||
if (isset($options['webp_quality'])) {
|
||||
if ($options['webp_quality'] < 0 || $options['webp_quality'] > 100) {
|
||||
throw new InvalidArgumentException('webp_quality option should be an integer from 0 to 100');
|
||||
}
|
||||
$args[] = $options['webp_quality'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ErrorHandling::throwingRuntimeException(E_WARNING | E_NOTICE, function () use ($save, $args) {
|
||||
if (false === call_user_func_array($save, $args)) {
|
||||
throw new RuntimeException('Save operation failed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a GD image.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param string $operation the operation initiating the creation
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function createImage(BoxInterface $size, $operation)
|
||||
{
|
||||
$resource = imagecreatetruecolor($size->getWidth(), $size->getHeight());
|
||||
|
||||
if (false === $resource) {
|
||||
throw new RuntimeException('Image ' . $operation . ' failed');
|
||||
}
|
||||
|
||||
if (false === imagealphablending($resource, false) || false === imagesavealpha($resource, true)) {
|
||||
throw new RuntimeException('Image ' . $operation . ' failed');
|
||||
}
|
||||
|
||||
if (function_exists('imageantialias')) {
|
||||
imageantialias($resource, true);
|
||||
}
|
||||
|
||||
$transparent = imagecolorallocatealpha($resource, 255, 255, 255, 127);
|
||||
imagefill($resource, 0, 0, $transparent);
|
||||
imagecolortransparent($resource, $transparent);
|
||||
|
||||
return $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a GD color from Color instance.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return int A color identifier
|
||||
*/
|
||||
private function getColor(ColorInterface $color)
|
||||
{
|
||||
if (!$color instanceof RGBColor) {
|
||||
throw new InvalidArgumentException('GD driver only supports RGB colors');
|
||||
}
|
||||
|
||||
$index = imagecolorallocatealpha($this->resource, $color->getRed(), $color->getGreen(), $color->getBlue(), round(127 * (100 - $color->getAlpha()) / 100));
|
||||
|
||||
if (false === $index) {
|
||||
throw new RuntimeException(sprintf('Unable to allocate color "RGB(%s, %s, %s)" with transparency of %d percent', $color->getRed(), $color->getGreen(), $color->getBlue(), $color->getAlpha()));
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a given format name.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalizeFormat($format)
|
||||
{
|
||||
$format = strtolower($format);
|
||||
|
||||
if ('jpg' === $format || 'pjpeg' === $format || 'jfif' === $format) {
|
||||
$format = 'jpeg';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given format is supported by GD library.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function supported($format = null)
|
||||
{
|
||||
$formats = self::getSupportedFormats();
|
||||
|
||||
if (null === $format) {
|
||||
return array_keys($formats);
|
||||
}
|
||||
|
||||
return is_string($format) && isset($formats[$format]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mime type based on format.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return string mime-type
|
||||
*/
|
||||
private function getMimeType($format)
|
||||
{
|
||||
$format = $this->normalizeFormat($format);
|
||||
$formats = self::getSupportedFormats();
|
||||
|
||||
if (!isset($formats[$format])) {
|
||||
throw new RuntimeException('Invalid format');
|
||||
}
|
||||
|
||||
return $formats[$format]['mimeType'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private static function getSupportedFormats()
|
||||
{
|
||||
static $supportedFormats;
|
||||
if (!isset($supportedFormats)) {
|
||||
$supportedFormats = array(
|
||||
'gif' => array('mimeType' => 'image/gif'),
|
||||
'jpeg' => array('mimeType' => 'image/jpeg'),
|
||||
'png' => array('mimeType' => 'image/png'),
|
||||
'wbmp' => array('mimeType' => 'image/vnd.wap.wbmp'),
|
||||
'xbm' => array('mimeType' => 'image/xbm'),
|
||||
);
|
||||
if (function_exists('imagebmp')) {
|
||||
$supportedFormats['bmp'] = array('mimeType' => 'image/bmp');
|
||||
}
|
||||
if (function_exists('imagewebp')) {
|
||||
$supportedFormats['webp'] = array('mimeType' => 'image/webp');
|
||||
}
|
||||
ksort($supportedFormats);
|
||||
}
|
||||
|
||||
return $supportedFormats;
|
||||
}
|
||||
}
|
||||
250
vendor/imagine/imagine/src/Gd/Imagine.php
vendored
Normal file
250
vendor/imagine/imagine/src/Gd/Imagine.php
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\File\LoaderInterface;
|
||||
use Imagine\Image\AbstractImagine;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Utils\ErrorHandling;
|
||||
|
||||
/**
|
||||
* Imagine implementation using the GD library.
|
||||
*/
|
||||
final class Imagine extends AbstractImagine
|
||||
{
|
||||
/**
|
||||
* Initialize the class.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->requireGdVersion('2.0.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::create()
|
||||
*/
|
||||
public function create(BoxInterface $size, ColorInterface $color = null)
|
||||
{
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$resource = imagecreatetruecolor($width, $height);
|
||||
|
||||
if (false === $resource) {
|
||||
throw new RuntimeException('Create operation failed');
|
||||
}
|
||||
|
||||
$palette = null !== $color ? $color->getPalette() : new RGB();
|
||||
$color = $color ? $color : $palette->color('fff');
|
||||
|
||||
if (!$color instanceof RGBColor) {
|
||||
throw new InvalidArgumentException('GD driver only supports RGB colors');
|
||||
}
|
||||
|
||||
$index = imagecolorallocatealpha($resource, $color->getRed(), $color->getGreen(), $color->getBlue(), round(127 * (100 - $color->getAlpha()) / 100));
|
||||
|
||||
if (false === $index) {
|
||||
throw new RuntimeException('Unable to allocate color');
|
||||
}
|
||||
|
||||
if (false === imagefill($resource, 0, 0, $index)) {
|
||||
throw new RuntimeException('Could not set background color fill');
|
||||
}
|
||||
|
||||
if ($color->getAlpha() <= 5) {
|
||||
imagecolortransparent($resource, $index);
|
||||
}
|
||||
|
||||
return $this->wrap($resource, $palette, new MetadataBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::open()
|
||||
*/
|
||||
public function open($path)
|
||||
{
|
||||
$loader = $path instanceof LoaderInterface ? $path : $this->getClassFactory()->createFileLoader($path);
|
||||
$path = $loader->getPath();
|
||||
|
||||
$data = $loader->getData();
|
||||
|
||||
$resource = $this->createImageFromString($data);
|
||||
|
||||
if (!\is_resource($resource)) {
|
||||
throw new RuntimeException(sprintf('Unable to open image %s', $path));
|
||||
}
|
||||
|
||||
return $this->wrap($resource, new RGB(), $this->getMetadataReader()->readFile($loader));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::load()
|
||||
*/
|
||||
public function load($string)
|
||||
{
|
||||
return $this->doLoad($string, $this->getMetadataReader()->readData($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::read()
|
||||
*/
|
||||
public function read($resource)
|
||||
{
|
||||
if (!\is_resource($resource)) {
|
||||
throw new InvalidArgumentException('Variable does not contain a stream resource');
|
||||
}
|
||||
|
||||
$content = stream_get_contents($resource);
|
||||
|
||||
if (false === $content) {
|
||||
throw new InvalidArgumentException('Cannot read resource content');
|
||||
}
|
||||
|
||||
return $this->doLoad($content, $this->getMetadataReader()->readData($content, $resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::font()
|
||||
*/
|
||||
public function font($file, $size, ColorInterface $color)
|
||||
{
|
||||
return $this->getClassFactory()->createFont(ClassFactoryInterface::HANDLE_GD, $file, $size, $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $resource
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
private function wrap($resource, PaletteInterface $palette, MetadataBag $metadata)
|
||||
{
|
||||
if (!imageistruecolor($resource)) {
|
||||
if (\function_exists('imagepalettetotruecolor')) {
|
||||
if (false === imagepalettetotruecolor($resource)) {
|
||||
throw new RuntimeException('Could not convert a palette based image to true color');
|
||||
}
|
||||
} else {
|
||||
list($width, $height) = array(imagesx($resource), imagesy($resource));
|
||||
|
||||
// create transparent truecolor canvas
|
||||
$truecolor = imagecreatetruecolor($width, $height);
|
||||
$transparent = imagecolorallocatealpha($truecolor, 255, 255, 255, 127);
|
||||
|
||||
imagealphablending($truecolor, false);
|
||||
imagefilledrectangle($truecolor, 0, 0, $width, $height, $transparent);
|
||||
imagealphablending($truecolor, false);
|
||||
|
||||
imagecopy($truecolor, $resource, 0, 0, 0, 0, $width, $height);
|
||||
|
||||
imagedestroy($resource);
|
||||
$resource = $truecolor;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === imagealphablending($resource, false) || false === imagesavealpha($resource, true)) {
|
||||
throw new RuntimeException('Could not set alphablending, savealpha and antialias values');
|
||||
}
|
||||
|
||||
if (\function_exists('imageantialias')) {
|
||||
imageantialias($resource, true);
|
||||
}
|
||||
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GD, $resource, $palette, $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
private function requireGdVersion($version)
|
||||
{
|
||||
if (!\function_exists('gd_info')) {
|
||||
throw new RuntimeException('Gd not installed');
|
||||
}
|
||||
if (version_compare(GD_VERSION, $version, '<')) {
|
||||
throw new RuntimeException(sprintf('GD2 version %s or higher is required, %s provided', $version, GD_VERSION));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
private function doLoad($string, MetadataBag $metadata)
|
||||
{
|
||||
$resource = $this->createImageFromString($string);
|
||||
|
||||
if (!\is_resource($resource)) {
|
||||
throw new RuntimeException('An image could not be created from the given input');
|
||||
}
|
||||
|
||||
return $this->wrap($resource, new RGB(), $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the raw image data represents an image in WebP format.
|
||||
*
|
||||
* @param string $data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isWebP(&$data)
|
||||
{
|
||||
return substr($data, 8, 7) === 'WEBPVP8';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an image resource starting from its raw daa.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return resource|false
|
||||
*/
|
||||
private function createImageFromString(&$string)
|
||||
{
|
||||
return ErrorHandling::ignoring(-1, function () use (&$string) {
|
||||
// imagecreatefromstring() does not support webp images before PHP 7.3.0
|
||||
if (PHP_VERSION_ID < 70300 && function_exists('imagecreatefromwebp') && $this->isWebP($string)) {
|
||||
return @imagecreatefromwebp('data:image/webp;base64,' . base64_encode($string));
|
||||
}
|
||||
|
||||
return @imagecreatefromstring($string);
|
||||
});
|
||||
}
|
||||
}
|
||||
195
vendor/imagine/imagine/src/Gd/Layers.php
vendored
Normal file
195
vendor/imagine/imagine/src/Gd/Layers.php
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gd;
|
||||
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\AbstractLayers;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
|
||||
class Layers extends AbstractLayers
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Gd\Image
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Gd\Image $image
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param resource $resource
|
||||
* @param int $initialOffset
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
public function __construct(Image $image, PaletteInterface $palette, $resource, $initialOffset = 0)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new RuntimeException('Invalid Gd resource provided');
|
||||
}
|
||||
|
||||
$this->image = $image;
|
||||
$this->resource = $resource;
|
||||
$this->offset = (int) $initialOffset;
|
||||
$this->palette = $palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::merge()
|
||||
*/
|
||||
public function merge()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::coalesce()
|
||||
*/
|
||||
public function coalesce()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::animate()
|
||||
*/
|
||||
public function animate($format, $delay, $loops)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::current()
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GD, $this->resource, $this->palette, new MetadataBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::key()
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::valid()
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->offset < 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetExists()
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return 0 === $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetGet()
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (0 === $offset) {
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GD, $this->resource, $this->palette, new MetadataBag());
|
||||
}
|
||||
|
||||
throw new RuntimeException('GD only supports one layer at offset 0');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetSet()
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new NotSupportedException('GD does not support layer set');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetUnset()
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new NotSupportedException('GD does not support layer unset');
|
||||
}
|
||||
}
|
||||
445
vendor/imagine/imagine/src/Gmagick/Drawer.php
vendored
Normal file
445
vendor/imagine/imagine/src/Gmagick/Drawer.php
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Draw\DrawerInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Drawer implementation using the Gmagick PHP extension.
|
||||
*/
|
||||
final class Drawer implements DrawerInterface
|
||||
{
|
||||
/**
|
||||
* @var \Gmagick
|
||||
*/
|
||||
private $gmagick;
|
||||
|
||||
/**
|
||||
* @param \Gmagick $gmagick
|
||||
*/
|
||||
public function __construct(\Gmagick $gmagick)
|
||||
{
|
||||
$this->gmagick = $gmagick;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::arc()
|
||||
*/
|
||||
public function arc(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
$x = $center->getX();
|
||||
$y = $center->getY();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$arc = new \GmagickDraw();
|
||||
|
||||
$arc->setstrokecolor($pixel);
|
||||
$arc->setstrokewidth($thickness);
|
||||
$arc->setfillcolor('transparent');
|
||||
$arc->arc(
|
||||
$x - $width / 2,
|
||||
$y - $height / 2,
|
||||
$x + $width / 2,
|
||||
$y + $height / 2,
|
||||
$start,
|
||||
$end
|
||||
);
|
||||
|
||||
$this->gmagick->drawImage($arc);
|
||||
|
||||
$pixel = null;
|
||||
|
||||
$arc = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw arc operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::chord()
|
||||
*/
|
||||
public function chord(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$x = $center->getX();
|
||||
$y = $center->getY();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$chord = new \GmagickDraw();
|
||||
|
||||
$chord->setstrokecolor($pixel);
|
||||
$chord->setstrokewidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$chord->setfillcolor($pixel);
|
||||
} else {
|
||||
$x1 = round($x + $width / 2 * cos(deg2rad($start)));
|
||||
$y1 = round($y + $height / 2 * sin(deg2rad($start)));
|
||||
$x2 = round($x + $width / 2 * cos(deg2rad($end)));
|
||||
$y2 = round($y + $height / 2 * sin(deg2rad($end)));
|
||||
|
||||
$this->line(new Point($x1, $y1), new Point($x2, $y2), $color, $thickness);
|
||||
|
||||
$chord->setfillcolor('transparent');
|
||||
}
|
||||
|
||||
$chord->arc($x - $width / 2, $y - $height / 2, $x + $width / 2, $y + $height / 2, $start, $end);
|
||||
|
||||
$this->gmagick->drawImage($chord);
|
||||
|
||||
$pixel = null;
|
||||
|
||||
$chord = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw chord operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::circle()
|
||||
*/
|
||||
public function circle(PointInterface $center, $radius, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$diameter = $radius * 2;
|
||||
|
||||
return $this->ellipse($center, new Box($diameter, $diameter), $color, $fill, $thickness);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::ellipse()
|
||||
*/
|
||||
public function ellipse(PointInterface $center, BoxInterface $size, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$ellipse = new \GmagickDraw();
|
||||
|
||||
$ellipse->setstrokecolor($pixel);
|
||||
$ellipse->setstrokewidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$ellipse->setfillcolor($pixel);
|
||||
} else {
|
||||
$ellipse->setfillcolor('transparent');
|
||||
}
|
||||
|
||||
$ellipse->ellipse(
|
||||
$center->getX(),
|
||||
$center->getY(),
|
||||
$width / 2,
|
||||
$height / 2,
|
||||
0, 360
|
||||
);
|
||||
|
||||
$this->gmagick->drawImage($ellipse);
|
||||
|
||||
$pixel = null;
|
||||
|
||||
$ellipse = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw ellipse operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::line()
|
||||
*/
|
||||
public function line(PointInterface $start, PointInterface $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$line = new \GmagickDraw();
|
||||
|
||||
$line->setstrokecolor($pixel);
|
||||
$line->setstrokewidth($thickness);
|
||||
$line->setfillcolor($pixel);
|
||||
$line->line(
|
||||
$start->getX(),
|
||||
$start->getY(),
|
||||
$end->getX(),
|
||||
$end->getY()
|
||||
);
|
||||
|
||||
$this->gmagick->drawImage($line);
|
||||
|
||||
$pixel = null;
|
||||
|
||||
$line = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw line operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::pieSlice()
|
||||
*/
|
||||
public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$x1 = round($center->getX() + $width / 2 * cos(deg2rad($start)));
|
||||
$y1 = round($center->getY() + $height / 2 * sin(deg2rad($start)));
|
||||
$x2 = round($center->getX() + $width / 2 * cos(deg2rad($end)));
|
||||
$y2 = round($center->getY() + $height / 2 * sin(deg2rad($end)));
|
||||
|
||||
if ($fill) {
|
||||
$this->chord($center, $size, $start, $end, $color, true, $thickness);
|
||||
$this->polygon(
|
||||
array(
|
||||
$center,
|
||||
new Point($x1, $y1),
|
||||
new Point($x2, $y2),
|
||||
),
|
||||
$color,
|
||||
true,
|
||||
$thickness
|
||||
);
|
||||
} else {
|
||||
$this->arc($center, $size, $start, $end, $color, $thickness);
|
||||
$this->line($center, new Point($x1, $y1), $color, $thickness);
|
||||
$this->line($center, new Point($x2, $y2), $color, $thickness);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::dot()
|
||||
*/
|
||||
public function dot(PointInterface $position, ColorInterface $color)
|
||||
{
|
||||
$x = $position->getX();
|
||||
$y = $position->getY();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$point = new \GmagickDraw();
|
||||
|
||||
$point->setfillcolor($pixel);
|
||||
$point->point($x, $y);
|
||||
|
||||
$this->gmagick->drawimage($point);
|
||||
|
||||
$pixel = null;
|
||||
$point = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw point operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::rectangle()
|
||||
*/
|
||||
public function rectangle(PointInterface $leftTop, PointInterface $rightBottom, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$minX = min($leftTop->getX(), $rightBottom->getX());
|
||||
$maxX = max($leftTop->getX(), $rightBottom->getX());
|
||||
$minY = min($leftTop->getY(), $rightBottom->getY());
|
||||
$maxY = max($leftTop->getY(), $rightBottom->getY());
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$rectangle = new \GmagickDraw();
|
||||
|
||||
$rectangle->setstrokecolor($pixel);
|
||||
$rectangle->setstrokewidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$rectangle->setfillcolor($pixel);
|
||||
} else {
|
||||
$rectangle->setfillcolor('transparent');
|
||||
}
|
||||
$rectangle->rectangle($minX, $minY, $maxX, $maxY);
|
||||
$this->gmagick->drawImage($rectangle);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw polygon operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::polygon()
|
||||
*/
|
||||
public function polygon(array $coordinates, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
if (count($coordinates) < 3) {
|
||||
throw new InvalidArgumentException(sprintf('Polygon must consist of at least 3 coordinates, %d given', count($coordinates)));
|
||||
}
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$points = array_map(function (PointInterface $p) {
|
||||
return array('x' => $p->getX(), 'y' => $p->getY());
|
||||
}, $coordinates);
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$polygon = new \GmagickDraw();
|
||||
|
||||
$polygon->setstrokecolor($pixel);
|
||||
$polygon->setstrokewidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$polygon->setfillcolor($pixel);
|
||||
} else {
|
||||
$polygon->setfillcolor('transparent');
|
||||
}
|
||||
|
||||
$polygon->polygon($points);
|
||||
|
||||
$this->gmagick->drawImage($polygon);
|
||||
|
||||
unset($pixel, $polygon);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw polygon operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::text()
|
||||
*/
|
||||
public function text($string, AbstractFont $font, PointInterface $position, $angle = 0, $width = null)
|
||||
{
|
||||
try {
|
||||
$pixel = $this->getColor($font->getColor());
|
||||
$text = new \GmagickDraw();
|
||||
|
||||
$text->setfont($font->getFile());
|
||||
/*
|
||||
* @see http://www.php.net/manual/en/imagick.queryfontmetrics.php#101027
|
||||
*
|
||||
* ensure font resolution is the same as GD's hard-coded 96
|
||||
*/
|
||||
$text->setfontsize((int) ($font->getSize() * (96 / 72)));
|
||||
$text->setfillcolor($pixel);
|
||||
|
||||
if ($width !== null) {
|
||||
$string = $font->wrapText($string, $width, $angle);
|
||||
}
|
||||
|
||||
$info = $this->gmagick->queryfontmetrics($text, $string);
|
||||
$rad = deg2rad($angle);
|
||||
$cos = cos($rad);
|
||||
$sin = sin($rad);
|
||||
|
||||
$x1 = round(0 * $cos - 0 * $sin);
|
||||
$x2 = round($info['textWidth'] * $cos - $info['textHeight'] * $sin);
|
||||
$y1 = round(0 * $sin + 0 * $cos);
|
||||
$y2 = round($info['textWidth'] * $sin + $info['textHeight'] * $cos);
|
||||
|
||||
$xdiff = 0 - min($x1, $x2);
|
||||
$ydiff = 0 - min($y1, $y2);
|
||||
|
||||
$this->gmagick->annotateimage($text, $position->getX() + $x1 + $xdiff, $position->getY() + $y2 + $ydiff, $angle, $string);
|
||||
|
||||
unset($pixel, $text);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Draw text operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets specifically formatted color string from Color instance.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException In case a non-opaque color is passed
|
||||
*
|
||||
* @return \GmagickPixel
|
||||
*/
|
||||
private function getColor(ColorInterface $color)
|
||||
{
|
||||
if (!$color->isOpaque()) {
|
||||
throw new InvalidArgumentException('Gmagick doesn\'t support transparency');
|
||||
}
|
||||
|
||||
return new \GmagickPixel((string) $color);
|
||||
}
|
||||
}
|
||||
177
vendor/imagine/imagine/src/Gmagick/Effects.php
vendored
Normal file
177
vendor/imagine/imagine/src/Gmagick/Effects.php
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Effects\EffectsInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* Effects implementation using the Gmagick PHP extension.
|
||||
*/
|
||||
class Effects implements EffectsInterface
|
||||
{
|
||||
/**
|
||||
* @var \Gmagick
|
||||
*/
|
||||
private $gmagick;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param \Gmagick $gmagick
|
||||
*/
|
||||
public function __construct(\Gmagick $gmagick)
|
||||
{
|
||||
$this->gmagick = $gmagick;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::gamma()
|
||||
*/
|
||||
public function gamma($correction)
|
||||
{
|
||||
try {
|
||||
$this->gmagick->gammaimage($correction);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to apply gamma correction to the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::negative()
|
||||
*/
|
||||
public function negative()
|
||||
{
|
||||
if (!method_exists($this->gmagick, 'negateimage')) {
|
||||
throw new NotSupportedException('Gmagick version 1.1.0 RC3 is required for negative effect');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->gmagick->negateimage(false, \Gmagick::CHANNEL_ALL);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to negate the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
try {
|
||||
$this->gmagick->setImageType(2);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to grayscale the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::colorize()
|
||||
*/
|
||||
public function colorize(ColorInterface $color)
|
||||
{
|
||||
throw new NotSupportedException('Gmagick does not support colorize');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::sharpen()
|
||||
*/
|
||||
public function sharpen()
|
||||
{
|
||||
throw new NotSupportedException('Gmagick does not support sharpen yet');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::blur()
|
||||
*/
|
||||
public function blur($sigma = 1)
|
||||
{
|
||||
try {
|
||||
$this->gmagick->blurImage(0, $sigma);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to blur the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::brightness()
|
||||
*/
|
||||
public function brightness($brightness)
|
||||
{
|
||||
$brightness = (int) round($brightness);
|
||||
if ($brightness < -100 || $brightness > 100) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$brightness', -100, 100, $brightness));
|
||||
}
|
||||
try {
|
||||
// This *emulates* setting the brightness
|
||||
$sign = $brightness < 0 ? -1 : 1;
|
||||
$v = abs($brightness) / 100;
|
||||
if ($sign > 0) {
|
||||
$v = (2 / (sin(($v * .99999 * M_PI_2) + M_PI_2))) - 2;
|
||||
}
|
||||
$this->gmagick->modulateimage(100 + $sign * $v * 100, 100, 100);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to brightness the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::convolve()
|
||||
*/
|
||||
public function convolve(Matrix $matrix)
|
||||
{
|
||||
if (!method_exists($this->gmagick, 'convolveimage')) {
|
||||
// convolveimage has been added in gmagick 2.0.1RC2
|
||||
throw new NotSupportedException('The version of Gmagick extension is too old: it does not support convolve.');
|
||||
}
|
||||
if ($matrix->getWidth() !== 3 || $matrix->getHeight() !== 3) {
|
||||
throw new InvalidArgumentException(sprintf('A convolution matrix must be 3x3 (%dx%d provided).', $matrix->getWidth(), $matrix->getHeight()));
|
||||
}
|
||||
try {
|
||||
$this->gmagick->convolveimage($matrix->getValueList());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to convolve the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
64
vendor/imagine/imagine/src/Gmagick/Font.php
vendored
Normal file
64
vendor/imagine/imagine/src/Gmagick/Font.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* Font implementation using the Gmagick PHP extension.
|
||||
*/
|
||||
final class Font extends AbstractFont
|
||||
{
|
||||
/**
|
||||
* @var \Gmagick
|
||||
*/
|
||||
private $gmagick;
|
||||
|
||||
/**
|
||||
* @param \Gmagick $gmagick
|
||||
* @param string $file
|
||||
* @param int $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*/
|
||||
public function __construct(\Gmagick $gmagick, $file, $size, ColorInterface $color)
|
||||
{
|
||||
$this->gmagick = $gmagick;
|
||||
|
||||
parent::__construct($file, $size, $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::box()
|
||||
*/
|
||||
public function box($string, $angle = 0)
|
||||
{
|
||||
$text = new \GmagickDraw();
|
||||
|
||||
$text->setfont($this->file);
|
||||
/*
|
||||
* @see http://www.php.net/manual/en/imagick.queryfontmetrics.php#101027
|
||||
*
|
||||
* ensure font resolution is the same as GD's hard-coded 96
|
||||
*/
|
||||
$text->setfontsize((int) ($this->size * (96 / 72)));
|
||||
$text->setfontstyle(\Gmagick::STYLE_OBLIQUE);
|
||||
|
||||
$info = $this->gmagick->queryfontmetrics($text, $string);
|
||||
|
||||
$box = $this->getClassFactory()->createBox($info['textWidth'], $info['textHeight']);
|
||||
|
||||
return $box;
|
||||
}
|
||||
}
|
||||
890
vendor/imagine/imagine/src/Gmagick/Image.php
vendored
Normal file
890
vendor/imagine/imagine/src/Gmagick/Image.php
vendored
Normal file
@@ -0,0 +1,890 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\AbstractImage;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
|
||||
/**
|
||||
* Image implementation using the Gmagick PHP extension.
|
||||
*/
|
||||
final class Image extends AbstractImage
|
||||
{
|
||||
/**
|
||||
* @var \Gmagick
|
||||
*/
|
||||
private $gmagick;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Gmagick\Layers|null
|
||||
*/
|
||||
private $layers;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private static $colorspaceMapping = null;
|
||||
|
||||
/**
|
||||
* Constructs a new Image instance.
|
||||
*
|
||||
* @param \Gmagick $gmagick
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*/
|
||||
public function __construct(\Gmagick $gmagick, PaletteInterface $palette, MetadataBag $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
$this->gmagick = $gmagick;
|
||||
$this->setColorspace($palette);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys allocated gmagick resources.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->gmagick instanceof \Gmagick) {
|
||||
$this->gmagick->clear();
|
||||
$this->gmagick->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\AbstractImage::__clone()
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
parent::__clone();
|
||||
$this->gmagick = clone $this->gmagick;
|
||||
$this->palette = clone $this->palette;
|
||||
if ($this->layers !== null) {
|
||||
$this->layers = $this->getClassFactory()->createLayers(ClassFactoryInterface::HANDLE_GMAGICK, $this, $this->layers->key());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gmagick instance.
|
||||
*
|
||||
* @return \Gmagick
|
||||
*/
|
||||
public function getGmagick()
|
||||
{
|
||||
return $this->gmagick;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::copy()
|
||||
*/
|
||||
public function copy()
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::crop()
|
||||
*/
|
||||
public function crop(PointInterface $start, BoxInterface $size)
|
||||
{
|
||||
if (!$start->in($this->getSize())) {
|
||||
throw new OutOfBoundsException('Crop coordinates must start at minimum 0, 0 position from top left corner, crop height and width must be positive integers and must not exceed the current image borders');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->gmagick->cropimage($size->getWidth(), $size->getHeight(), $start->getX(), $start->getY());
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Crop operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipHorizontally()
|
||||
*/
|
||||
public function flipHorizontally()
|
||||
{
|
||||
try {
|
||||
$this->gmagick->flopimage();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Horizontal flip operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::flipVertically()
|
||||
*/
|
||||
public function flipVertically()
|
||||
{
|
||||
try {
|
||||
$this->gmagick->flipimage();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Vertical flip operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::strip()
|
||||
*/
|
||||
public function strip()
|
||||
{
|
||||
try {
|
||||
try {
|
||||
$this->profile($this->palette->profile());
|
||||
} catch (\Exception $e) {
|
||||
// here we discard setting the profile as the previous incorporated profile
|
||||
// is corrupted, let's now strip the image
|
||||
}
|
||||
$this->gmagick->stripimage();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Strip operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::paste()
|
||||
*/
|
||||
public function paste(ImageInterface $image, PointInterface $start, $alpha = 100)
|
||||
{
|
||||
if (!$image instanceof self) {
|
||||
throw new InvalidArgumentException(sprintf('Gmagick\Image can only paste() Gmagick\Image instances, %s given', get_class($image)));
|
||||
}
|
||||
|
||||
$alpha = (int) round($alpha);
|
||||
if ($alpha < 0 || $alpha > 100) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$alpha', 0, 100, $alpha));
|
||||
}
|
||||
|
||||
if ($alpha === 100) {
|
||||
try {
|
||||
$this->gmagick->compositeimage($image->gmagick, \Gmagick::COMPOSITE_DEFAULT, $start->getX(), $start->getY());
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Paste operation failed', $e->getCode(), $e);
|
||||
}
|
||||
} elseif ($alpha > 0) {
|
||||
throw new NotSupportedException('Gmagick doesn\'t support paste with alpha.', 1);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::resize()
|
||||
*/
|
||||
public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
static $supportedFilters = array(
|
||||
ImageInterface::FILTER_UNDEFINED => \Gmagick::FILTER_UNDEFINED,
|
||||
ImageInterface::FILTER_BESSEL => \Gmagick::FILTER_BESSEL,
|
||||
ImageInterface::FILTER_BLACKMAN => \Gmagick::FILTER_BLACKMAN,
|
||||
ImageInterface::FILTER_BOX => \Gmagick::FILTER_BOX,
|
||||
ImageInterface::FILTER_CATROM => \Gmagick::FILTER_CATROM,
|
||||
ImageInterface::FILTER_CUBIC => \Gmagick::FILTER_CUBIC,
|
||||
ImageInterface::FILTER_GAUSSIAN => \Gmagick::FILTER_GAUSSIAN,
|
||||
ImageInterface::FILTER_HANNING => \Gmagick::FILTER_HANNING,
|
||||
ImageInterface::FILTER_HAMMING => \Gmagick::FILTER_HAMMING,
|
||||
ImageInterface::FILTER_HERMITE => \Gmagick::FILTER_HERMITE,
|
||||
ImageInterface::FILTER_LANCZOS => \Gmagick::FILTER_LANCZOS,
|
||||
ImageInterface::FILTER_MITCHELL => \Gmagick::FILTER_MITCHELL,
|
||||
ImageInterface::FILTER_POINT => \Gmagick::FILTER_POINT,
|
||||
ImageInterface::FILTER_QUADRATIC => \Gmagick::FILTER_QUADRATIC,
|
||||
ImageInterface::FILTER_SINC => \Gmagick::FILTER_SINC,
|
||||
ImageInterface::FILTER_TRIANGLE => \Gmagick::FILTER_TRIANGLE,
|
||||
);
|
||||
|
||||
if (!array_key_exists($filter, $supportedFilters)) {
|
||||
throw new InvalidArgumentException('Unsupported filter type');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->gmagick->resizeimage($size->getWidth(), $size->getHeight(), $supportedFilters[$filter], 1);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Resize operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::rotate()
|
||||
*/
|
||||
public function rotate($angle, ColorInterface $background = null)
|
||||
{
|
||||
try {
|
||||
if ($background === null) {
|
||||
$background = $this->palette->color('fff');
|
||||
}
|
||||
$pixel = $this->getColor($background);
|
||||
|
||||
$this->gmagick->rotateimage($pixel, $angle);
|
||||
|
||||
unset($pixel);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Rotate operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies options before save or output.
|
||||
*
|
||||
* @param \Gmagick $image
|
||||
* @param array $options
|
||||
* @param string $path
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function applyImageOptions(\Gmagick $image, array $options, $path)
|
||||
{
|
||||
if (isset($options['format'])) {
|
||||
$format = $options['format'];
|
||||
} elseif ('' !== $extension = pathinfo($path, \PATHINFO_EXTENSION)) {
|
||||
$format = $extension;
|
||||
} else {
|
||||
$format = pathinfo($image->getImageFilename(), \PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
$format = strtolower($format);
|
||||
|
||||
switch ($format) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
case 'pjpeg':
|
||||
if (!isset($options['jpeg_quality'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['jpeg_quality'] = $options['quality'];
|
||||
}
|
||||
}
|
||||
if (isset($options['jpeg_quality'])) {
|
||||
$image->setCompressionQuality($options['jpeg_quality']);
|
||||
}
|
||||
if (isset($options['jpeg_sampling_factors'])) {
|
||||
if (!is_array($options['jpeg_sampling_factors']) || \count($options['jpeg_sampling_factors']) < 1) {
|
||||
throw new InvalidArgumentException('jpeg_sampling_factors option should be an array of integers');
|
||||
}
|
||||
$image->setSamplingFactors(array_map(function ($factor) {
|
||||
return (int) $factor;
|
||||
}, $options['jpeg_sampling_factors']));
|
||||
}
|
||||
break;
|
||||
case 'png':
|
||||
if (!isset($options['png_compression_level'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['png_compression_level'] = round((100 - $options['quality']) * 9 / 100);
|
||||
}
|
||||
}
|
||||
if (isset($options['png_compression_level'])) {
|
||||
if ($options['png_compression_level'] < 0 || $options['png_compression_level'] > 9) {
|
||||
throw new InvalidArgumentException('png_compression_level option should be an integer from 0 to 9');
|
||||
}
|
||||
}
|
||||
if (isset($options['png_compression_filter'])) {
|
||||
if ($options['png_compression_filter'] < 0 || $options['png_compression_filter'] > 9) {
|
||||
throw new InvalidArgumentException('png_compression_filter option should be an integer from 0 to 9');
|
||||
}
|
||||
}
|
||||
if (isset($options['png_compression_level']) || isset($options['png_compression_filter'])) {
|
||||
// first digit: compression level (default: 7)
|
||||
$compression = isset($options['png_compression_level']) ? $options['png_compression_level'] * 10 : 70;
|
||||
// second digit: compression filter (default: 5)
|
||||
$compression += isset($options['png_compression_filter']) ? $options['png_compression_filter'] : 5;
|
||||
$image->setCompressionQuality($compression);
|
||||
}
|
||||
break;
|
||||
case 'webp':
|
||||
if (!isset($options['webp_quality'])) {
|
||||
if (isset($options['quality'])) {
|
||||
$options['webp_quality'] = $options['quality'];
|
||||
}
|
||||
}
|
||||
if (isset($options['webp_quality'])) {
|
||||
$image->setCompressionQuality($options['webp_quality']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (isset($options['resolution-units']) && isset($options['resolution-x']) && isset($options['resolution-y'])) {
|
||||
switch ($options['resolution-units']) {
|
||||
case ImageInterface::RESOLUTION_PIXELSPERCENTIMETER:
|
||||
$image->setimageunits(\Gmagick::RESOLUTION_PIXELSPERCENTIMETER);
|
||||
break;
|
||||
case ImageInterface::RESOLUTION_PIXELSPERINCH:
|
||||
$image->setimageunits(\Gmagick::RESOLUTION_PIXELSPERINCH);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException('Unsupported image unit format');
|
||||
}
|
||||
$image->setimageresolution($options['resolution-x'], $options['resolution-y']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::save()
|
||||
*/
|
||||
public function save($path = null, array $options = array())
|
||||
{
|
||||
$path = null === $path ? $this->gmagick->getImageFilename() : $path;
|
||||
|
||||
if ('' === trim($path)) {
|
||||
throw new RuntimeException('You can omit save path only if image has been open from a file');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->prepareOutput($options, $path);
|
||||
$allFrames = !isset($options['animated']) || false === $options['animated'];
|
||||
$this->gmagick->writeimage($path, $allFrames);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Save operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::show()
|
||||
*/
|
||||
public function show($format, array $options = array())
|
||||
{
|
||||
header('Content-type: ' . $this->getMimeType($format));
|
||||
echo $this->get($format, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::get()
|
||||
*/
|
||||
public function get($format, array $options = array())
|
||||
{
|
||||
try {
|
||||
$options['format'] = $format;
|
||||
$this->prepareOutput($options);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Get operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this->gmagick->getimagesblob();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @param string $path
|
||||
*/
|
||||
private function prepareOutput(array $options, $path = null)
|
||||
{
|
||||
if (isset($options['format'])) {
|
||||
$this->gmagick->setimageformat($options['format']);
|
||||
}
|
||||
|
||||
if (isset($options['animated']) && true === $options['animated']) {
|
||||
$format = isset($options['format']) ? $options['format'] : 'gif';
|
||||
$delay = isset($options['animated.delay']) ? $options['animated.delay'] : null;
|
||||
$loops = isset($options['animated.loops']) ? $options['animated.loops'] : 0;
|
||||
|
||||
$options['flatten'] = false;
|
||||
|
||||
$this->layers()->animate($format, $delay, $loops);
|
||||
} else {
|
||||
$this->layers()->merge();
|
||||
}
|
||||
$this->applyImageOptions($this->gmagick, $options, $path);
|
||||
|
||||
// flatten only if image has multiple layers
|
||||
if ((!isset($options['flatten']) || $options['flatten'] === true) && $this->layers()->count() > 1) {
|
||||
$this->flatten();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->get('png');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::draw()
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
return $this->getClassFactory()->createDrawer(ClassFactoryInterface::HANDLE_GMAGICK, $this->gmagick);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::effects()
|
||||
*/
|
||||
public function effects()
|
||||
{
|
||||
return $this->getClassFactory()->createEffects(ClassFactoryInterface::HANDLE_GMAGICK, $this->gmagick);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::getSize()
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
try {
|
||||
$i = $this->gmagick->getimageindex();
|
||||
$this->gmagick->setimageindex(0); //rewind
|
||||
$width = $this->gmagick->getimagewidth();
|
||||
$height = $this->gmagick->getimageheight();
|
||||
$this->gmagick->setimageindex($i);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Get size operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this->getClassFactory()->createBox($width, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::applyMask()
|
||||
*/
|
||||
public function applyMask(ImageInterface $mask)
|
||||
{
|
||||
if (!$mask instanceof self) {
|
||||
throw new InvalidArgumentException('Can only apply instances of Imagine\Gmagick\Image as masks');
|
||||
}
|
||||
|
||||
$size = $this->getSize();
|
||||
$maskSize = $mask->getSize();
|
||||
|
||||
if ($size != $maskSize) {
|
||||
throw new InvalidArgumentException(sprintf('The given mask doesn\'t match current image\'s size, current mask\'s dimensions are %s, while image\'s dimensions are %s', $maskSize, $size));
|
||||
}
|
||||
|
||||
try {
|
||||
$mask = $mask->copy();
|
||||
$this->gmagick->compositeimage($mask->gmagick, \Gmagick::COMPOSITE_DEFAULT, 0, 0);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Apply mask operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::mask()
|
||||
*/
|
||||
public function mask()
|
||||
{
|
||||
$mask = $this->copy();
|
||||
|
||||
try {
|
||||
$mask->gmagick->modulateimage(100, 0, 100);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Mask operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::fill()
|
||||
*/
|
||||
public function fill(FillInterface $fill)
|
||||
{
|
||||
try {
|
||||
$draw = new \GmagickDraw();
|
||||
$size = $this->getSize();
|
||||
|
||||
$w = $size->getWidth();
|
||||
$h = $size->getHeight();
|
||||
|
||||
for ($x = 0; $x < $w; $x++) {
|
||||
for ($y = 0; $y < $h; $y++) {
|
||||
$pixel = $this->getColor($fill->getColor(new Point($x, $y)));
|
||||
|
||||
$draw->setfillcolor($pixel);
|
||||
$draw->point($x, $y);
|
||||
|
||||
$pixel = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->gmagick->drawimage($draw);
|
||||
|
||||
$draw = null;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Fill operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::histogram()
|
||||
*/
|
||||
public function histogram()
|
||||
{
|
||||
try {
|
||||
$pixels = $this->gmagick->getimagehistogram();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Error while fetching histogram', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$image = $this;
|
||||
|
||||
return array_map(function (\GmagickPixel $pixel) use ($image) {
|
||||
return $image->pixelToColor($pixel);
|
||||
}, $pixels);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::getColorAt()
|
||||
*/
|
||||
public function getColorAt(PointInterface $point)
|
||||
{
|
||||
if (!$point->in($this->getSize())) {
|
||||
throw new InvalidArgumentException(sprintf('Error getting color at point [%s,%s]. The point must be inside the image of size [%s,%s]', $point->getX(), $point->getY(), $this->getSize()->getWidth(), $this->getSize()->getHeight()));
|
||||
}
|
||||
|
||||
try {
|
||||
$cropped = clone $this->gmagick;
|
||||
$histogram = $cropped
|
||||
->rollimage(-$point->getX(), -$point->getY())
|
||||
->cropImage(1, 1, 0, 0)
|
||||
->getImageHistogram();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Unable to get the pixel', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$pixel = array_shift($histogram);
|
||||
|
||||
unset($histogram, $cropped);
|
||||
|
||||
return $this->pixelToColor($pixel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a color given a pixel, depending the Palette context.
|
||||
*
|
||||
* Note : this method is public for PHP 5.3 compatibility
|
||||
*
|
||||
* @param \GmagickPixel $pixel
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException In case a unknown color is requested
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function pixelToColor(\GmagickPixel $pixel)
|
||||
{
|
||||
static $colorMapping = array(
|
||||
ColorInterface::COLOR_RED => \Gmagick::COLOR_RED,
|
||||
ColorInterface::COLOR_GREEN => \Gmagick::COLOR_GREEN,
|
||||
ColorInterface::COLOR_BLUE => \Gmagick::COLOR_BLUE,
|
||||
ColorInterface::COLOR_CYAN => \Gmagick::COLOR_CYAN,
|
||||
ColorInterface::COLOR_MAGENTA => \Gmagick::COLOR_MAGENTA,
|
||||
ColorInterface::COLOR_YELLOW => \Gmagick::COLOR_YELLOW,
|
||||
ColorInterface::COLOR_KEYLINE => \Gmagick::COLOR_BLACK,
|
||||
// There is no gray component in \Gmagick, let's use one of the RGB comp
|
||||
ColorInterface::COLOR_GRAY => \Gmagick::COLOR_RED,
|
||||
);
|
||||
|
||||
$alpha = null;
|
||||
if ($this->palette->supportsAlpha()) {
|
||||
if ($alpha === null && defined('Gmagick::COLOR_ALPHA')) {
|
||||
try {
|
||||
$alpha = (int) round($pixel->getcolorvalue(\Gmagick::COLOR_ALPHA) * 100);
|
||||
} catch (\GmagickPixelException $e) {
|
||||
}
|
||||
}
|
||||
if ($alpha === null && defined('Gmagick::COLOR_OPACITY')) {
|
||||
try {
|
||||
$alpha = (int) round(100 - $pixel->getcolorvalue(\Gmagick::COLOR_OPACITY) * 100);
|
||||
} catch (\GmagickPixelException $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$multiplier = $this->palette()->getChannelsMaxValue();
|
||||
|
||||
return $this->palette->color(array_map(function ($color) use ($multiplier, $pixel, $colorMapping) {
|
||||
if (!isset($colorMapping[$color])) {
|
||||
throw new InvalidArgumentException(sprintf('Color %s is not mapped in Gmagick', $color));
|
||||
}
|
||||
|
||||
return $pixel->getcolorvalue($colorMapping[$color]) * $multiplier;
|
||||
}, $this->palette->pixelDefinition()), $alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::layers()
|
||||
*/
|
||||
public function layers()
|
||||
{
|
||||
if ($this->layers === null) {
|
||||
$this->layers = $this->getClassFactory()->createLayers(ClassFactoryInterface::HANDLE_GMAGICK, $this);
|
||||
}
|
||||
|
||||
return $this->layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::interlace()
|
||||
*/
|
||||
public function interlace($scheme)
|
||||
{
|
||||
static $supportedInterlaceSchemes = array(
|
||||
ImageInterface::INTERLACE_NONE => \Gmagick::INTERLACE_NO,
|
||||
ImageInterface::INTERLACE_LINE => \Gmagick::INTERLACE_LINE,
|
||||
ImageInterface::INTERLACE_PLANE => \Gmagick::INTERLACE_PLANE,
|
||||
ImageInterface::INTERLACE_PARTITION => \Gmagick::INTERLACE_PARTITION,
|
||||
);
|
||||
|
||||
if (!array_key_exists($scheme, $supportedInterlaceSchemes)) {
|
||||
throw new InvalidArgumentException('Unsupported interlace type');
|
||||
}
|
||||
|
||||
$this->gmagick->setInterlaceScheme($supportedInterlaceSchemes[$scheme]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::usePalette()
|
||||
*/
|
||||
public function usePalette(PaletteInterface $palette)
|
||||
{
|
||||
$colorspaceMapping = self::getColorspaceMapping();
|
||||
if (!isset($colorspaceMapping[$palette->name()])) {
|
||||
throw new InvalidArgumentException(sprintf('The palette %s is not supported by Gmagick driver', $palette->name()));
|
||||
}
|
||||
|
||||
if ($this->palette->name() === $palette->name()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
$hasICCProfile = (bool) $this->gmagick->getimageprofile('ICM');
|
||||
} catch (\GmagickException $e) {
|
||||
$hasICCProfile = false;
|
||||
}
|
||||
|
||||
if (!$hasICCProfile) {
|
||||
$this->profile($this->palette->profile());
|
||||
}
|
||||
|
||||
$this->profile($palette->profile());
|
||||
|
||||
$this->setColorspace($palette);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to set colorspace', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::palette()
|
||||
*/
|
||||
public function palette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::profile()
|
||||
*/
|
||||
public function profile(ProfileInterface $profile)
|
||||
{
|
||||
try {
|
||||
$this->gmagick->profileimage('ICM', $profile->data());
|
||||
} catch (\GmagickException $e) {
|
||||
if (false !== strpos($e->getMessage(), 'LCMS encoding not enabled')) {
|
||||
throw new RuntimeException(sprintf('Unable to add profile %s to image, be sue to compile graphicsmagick with `--with-lcms2` option', $profile->name()), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Unable to add profile %s to image', $profile->name()), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten the image.
|
||||
*/
|
||||
private function flatten()
|
||||
{
|
||||
/*
|
||||
* @see http://pecl.php.net/bugs/bug.php?id=22435
|
||||
*/
|
||||
if (method_exists($this->gmagick, 'flattenImages')) {
|
||||
try {
|
||||
$this->gmagick = $this->gmagick->flattenImages();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Flatten operation failed', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets specifically formatted color string from Color instance.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return \GmagickPixel
|
||||
*/
|
||||
private function getColor(ColorInterface $color)
|
||||
{
|
||||
if (!$color->isOpaque()) {
|
||||
throw new InvalidArgumentException('Gmagick doesn\'t support transparency');
|
||||
}
|
||||
|
||||
return new \GmagickPixel((string) $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mime type based on format.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return string mime-type
|
||||
*/
|
||||
private function getMimeType($format)
|
||||
{
|
||||
static $mimeTypes = array(
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'webp' => 'image/webp',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'xbm' => 'image/xbm',
|
||||
'bmp' => 'image/bmp',
|
||||
);
|
||||
|
||||
if (!isset($mimeTypes[$format])) {
|
||||
throw new InvalidArgumentException(sprintf('Unsupported format given. Only %s are supported, %s given', implode(', ', array_keys($mimeTypes)), $format));
|
||||
}
|
||||
|
||||
return $mimeTypes[$format];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets colorspace and image type, assigns the palette.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setColorspace(PaletteInterface $palette)
|
||||
{
|
||||
$colorspaceMapping = self::getColorspaceMapping();
|
||||
if (!isset($colorspaceMapping[$palette->name()])) {
|
||||
throw new InvalidArgumentException(sprintf('The palette %s is not supported by Gmagick driver', $palette->name()));
|
||||
}
|
||||
|
||||
$this->gmagick->setimagecolorspace($colorspaceMapping[$palette->name()]);
|
||||
$this->palette = $palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private static function getColorspaceMapping()
|
||||
{
|
||||
if (self::$colorspaceMapping === null) {
|
||||
$csm = array(
|
||||
PaletteInterface::PALETTE_CMYK => \Gmagick::COLORSPACE_CMYK,
|
||||
PaletteInterface::PALETTE_RGB => \Gmagick::COLORSPACE_RGB,
|
||||
);
|
||||
if (defined('Gmagick::COLORSPACE_GRAY')) {
|
||||
$csm[PaletteInterface::PALETTE_GRAYSCALE] = \Gmagick::COLORSPACE_GRAY;
|
||||
}
|
||||
self::$colorspaceMapping = $csm;
|
||||
}
|
||||
|
||||
return self::$colorspaceMapping;
|
||||
}
|
||||
}
|
||||
194
vendor/imagine/imagine/src/Gmagick/Imagine.php
vendored
Normal file
194
vendor/imagine/imagine/src/Gmagick/Imagine.php
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\File\LoaderInterface;
|
||||
use Imagine\Image\AbstractImagine;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\CMYK;
|
||||
use Imagine\Image\Palette\Color\CMYK as CMYKColor;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Grayscale;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
|
||||
/**
|
||||
* Imagine implementation using the Gmagick PHP extension.
|
||||
*/
|
||||
class Imagine extends AbstractImagine
|
||||
{
|
||||
/**
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!class_exists('Gmagick')) {
|
||||
throw new RuntimeException('Gmagick not installed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::open()
|
||||
*/
|
||||
public function open($path)
|
||||
{
|
||||
$loader = $path instanceof LoaderInterface ? $path : $this->getClassFactory()->createFileLoader($path);
|
||||
$path = $loader->getPath();
|
||||
|
||||
try {
|
||||
if ($loader->isLocalFile()) {
|
||||
$gmagick = new \Gmagick($path);
|
||||
$image = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GMAGICK, $gmagick, $this->createPalette($gmagick), $this->getMetadataReader()->readFile($loader));
|
||||
} else {
|
||||
$image = $this->doLoad($loader->getData(), $this->getMetadataReader()->readFile($loader));
|
||||
}
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException(sprintf('Unable to open image %s', $path), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::create()
|
||||
*/
|
||||
public function create(BoxInterface $size, ColorInterface $color = null)
|
||||
{
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$palette = null !== $color ? $color->getPalette() : new RGB();
|
||||
$color = null !== $color ? $color : $palette->color('fff');
|
||||
|
||||
try {
|
||||
$gmagick = new \Gmagick();
|
||||
// Gmagick does not support creation of CMYK GmagickPixel
|
||||
// see https://bugs.php.net/bug.php?id=64466
|
||||
if ($color instanceof CMYKColor) {
|
||||
$switchPalette = $palette;
|
||||
$palette = new RGB();
|
||||
$pixel = new \GmagickPixel($palette->color((string) $color));
|
||||
} else {
|
||||
$switchPalette = null;
|
||||
$pixel = new \GmagickPixel((string) $color);
|
||||
}
|
||||
|
||||
if (!$color->getPalette()->supportsAlpha() && $color->getAlpha() !== null && $color->getAlpha() < 100) {
|
||||
throw new NotSupportedException('alpha transparency is not supported');
|
||||
}
|
||||
|
||||
$gmagick->newimage($width, $height, $pixel->getcolor(false));
|
||||
$gmagick->setimagecolorspace(\Gmagick::COLORSPACE_TRANSPARENT);
|
||||
$gmagick->setimagebackgroundcolor($pixel);
|
||||
|
||||
$image = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GMAGICK, $gmagick, $palette, new MetadataBag());
|
||||
|
||||
if ($switchPalette) {
|
||||
$image->usePalette($switchPalette);
|
||||
}
|
||||
|
||||
return $image;
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Could not create empty image', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::load()
|
||||
*/
|
||||
public function load($string)
|
||||
{
|
||||
return $this->doLoad($string, $this->getMetadataReader()->readData($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::read()
|
||||
*/
|
||||
public function read($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new InvalidArgumentException('Variable does not contain a stream resource');
|
||||
}
|
||||
|
||||
$content = stream_get_contents($resource);
|
||||
|
||||
if (false === $content) {
|
||||
throw new InvalidArgumentException('Couldn\'t read given resource');
|
||||
}
|
||||
|
||||
return $this->doLoad($content, $this->getMetadataReader()->readData($content, $resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::font()
|
||||
*/
|
||||
public function font($file, $size, ColorInterface $color)
|
||||
{
|
||||
return $this->getClassFactory()->createFont(ClassFactoryInterface::HANDLE_GMAGICK, $file, $size, $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Gmagick $gmagick
|
||||
*
|
||||
* @throws \Imagine\Exception\NotSupportedException
|
||||
*
|
||||
* @return \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private function createPalette(\Gmagick $gmagick)
|
||||
{
|
||||
switch ($gmagick->getimagecolorspace()) {
|
||||
case \Gmagick::COLORSPACE_SRGB:
|
||||
case \Gmagick::COLORSPACE_RGB:
|
||||
return new RGB();
|
||||
case \Gmagick::COLORSPACE_CMYK:
|
||||
return new CMYK();
|
||||
case \Gmagick::COLORSPACE_GRAY:
|
||||
return new Grayscale();
|
||||
default:
|
||||
throw new NotSupportedException('Only RGB and CMYK colorspace are currently supported');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @param \Imagine\Image\Metadata\MetadataBag $metadata
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
private function doLoad($content, MetadataBag $metadata)
|
||||
{
|
||||
try {
|
||||
$gmagick = new \Gmagick();
|
||||
$gmagick->readimageblob($content);
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Could not load image from string', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GMAGICK, $gmagick, $this->createPalette($gmagick), $metadata);
|
||||
}
|
||||
}
|
||||
308
vendor/imagine/imagine/src/Gmagick/Layers.php
vendored
Normal file
308
vendor/imagine/imagine/src/Gmagick/Layers.php
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Gmagick;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\AbstractLayers;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
|
||||
class Layers extends AbstractLayers
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Gmagick\Image
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @var \Gmagick
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Gmagick\Image[]
|
||||
*/
|
||||
private $layers = array();
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Gmagick\Image $image
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
* @param \Gmagick $resource
|
||||
* @param int $initialOffset
|
||||
*/
|
||||
public function __construct(Image $image, PaletteInterface $palette, \Gmagick $resource, $initialOffset = 0)
|
||||
{
|
||||
$this->image = $image;
|
||||
$this->resource = $resource;
|
||||
$this->palette = $palette;
|
||||
$this->offset = (int) $initialOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::merge()
|
||||
*/
|
||||
public function merge()
|
||||
{
|
||||
foreach ($this->layers as $offset => $image) {
|
||||
try {
|
||||
$this->resource->setimageindex($offset);
|
||||
$this->resource->setimage($image->getGmagick());
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to substitute layer', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::coalesce()
|
||||
*/
|
||||
public function coalesce()
|
||||
{
|
||||
throw new NotSupportedException('Gmagick does not support coalescing');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::animate()
|
||||
*/
|
||||
public function animate($format, $delay, $loops)
|
||||
{
|
||||
if ('gif' !== strtolower($format)) {
|
||||
throw new NotSupportedException('Animated picture is currently only supported on gif');
|
||||
}
|
||||
|
||||
if (!is_int($loops) || $loops < 0) {
|
||||
throw new InvalidArgumentException('Loops must be a positive integer.');
|
||||
}
|
||||
|
||||
if (null !== $delay && (!is_int($delay) || $delay < 0)) {
|
||||
throw new InvalidArgumentException('Delay must be either null or a positive integer.');
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($this as $offset => $layer) {
|
||||
$this->resource->setimageindex($offset);
|
||||
$this->resource->setimageformat($format);
|
||||
|
||||
if (null !== $delay) {
|
||||
$this->resource->setimagedelay($delay / 10);
|
||||
}
|
||||
|
||||
$this->resource->setimageiterations($loops);
|
||||
}
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to animate layers', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::current()
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->extractAt($this->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to extract layer at given offset.
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Gmagick\Image
|
||||
*/
|
||||
private function extractAt($offset)
|
||||
{
|
||||
if (!isset($this->layers[$offset])) {
|
||||
try {
|
||||
$this->resource->setimageindex($offset);
|
||||
$this->layers[$offset] = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_GMAGICK, $this->resource->getimage(), $this->palette, new MetadataBag());
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException(sprintf('Failed to extract layer %d', $offset), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->layers[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::key()
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::valid()
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->offset < count($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
try {
|
||||
return $this->resource->getnumberimages();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Failed to count the number of layers', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetExists()
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return is_int($offset) && $offset >= 0 && $offset < count($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetGet()
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->extractAt($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetSet()
|
||||
*/
|
||||
public function offsetSet($offset, $image)
|
||||
{
|
||||
if (!$image instanceof Image) {
|
||||
throw new InvalidArgumentException('Only a Gmagick Image can be used as layer');
|
||||
}
|
||||
|
||||
if (null === $offset) {
|
||||
$offset = count($this) - 1;
|
||||
} else {
|
||||
if (!is_int($offset)) {
|
||||
throw new InvalidArgumentException('Invalid offset for layer, it must be an integer');
|
||||
}
|
||||
|
||||
if (count($this) < $offset || 0 > $offset) {
|
||||
throw new OutOfBoundsException(sprintf('Invalid offset for layer, it must be a value between 0 and %d, %d given', count($this), $offset));
|
||||
}
|
||||
|
||||
if (isset($this[$offset])) {
|
||||
unset($this[$offset]);
|
||||
$offset = $offset - 1;
|
||||
}
|
||||
}
|
||||
|
||||
$frame = $image->getGmagick();
|
||||
|
||||
try {
|
||||
if (count($this) > 0) {
|
||||
$this->resource->setimageindex($offset);
|
||||
$this->resource->nextimage();
|
||||
}
|
||||
$this->resource->addimage($frame);
|
||||
|
||||
/*
|
||||
* ugly hack to bypass issue https://bugs.php.net/bug.php?id=64623
|
||||
*/
|
||||
if (count($this) == 2) {
|
||||
$this->resource->setimageindex($offset + 1);
|
||||
$this->resource->nextimage();
|
||||
$this->resource->addimage($frame);
|
||||
unset($this[0]);
|
||||
}
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Unable to set the layer', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$this->layers = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetUnset()
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
try {
|
||||
$this->extractAt($offset);
|
||||
} catch (RuntimeException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->resource->setimageindex($offset);
|
||||
$this->resource->removeimage();
|
||||
} catch (\GmagickException $e) {
|
||||
throw new RuntimeException('Unable to remove layer', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
155
vendor/imagine/imagine/src/Image/AbstractFont.php
vendored
Normal file
155
vendor/imagine/imagine/src/Image/AbstractFont.php
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Factory\ClassFactory;
|
||||
use Imagine\Factory\ClassFactoryAwareInterface;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* Abstract font base class.
|
||||
*/
|
||||
abstract class AbstractFont implements FontInterface, ClassFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Factory\ClassFactoryInterface|null
|
||||
*/
|
||||
private $classFactory;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* Constructs a font with specified $file, $size and $color.
|
||||
*
|
||||
* The font size is to be specified in points (e.g. 10pt means 10)
|
||||
*
|
||||
* @param string $file
|
||||
* @param int $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*/
|
||||
public function __construct($file, $size, ColorInterface $color)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->size = $size;
|
||||
$this->color = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::getFile()
|
||||
*/
|
||||
final public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::getSize()
|
||||
*/
|
||||
final public function getSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::getColor()
|
||||
*/
|
||||
final public function getColor()
|
||||
{
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::wrapText()
|
||||
*/
|
||||
public function wrapText($string, $maxWidth, $angle = 0)
|
||||
{
|
||||
$string = (string) $string;
|
||||
if ($string === '') {
|
||||
return $string;
|
||||
}
|
||||
$maxWidth = (int) round($maxWidth);
|
||||
if ($maxWidth < 1) {
|
||||
throw new InvalidArgumentException(sprintf('The $maxWidth parameter of wrapText must be greater than 0.'));
|
||||
}
|
||||
$words = explode(' ', $string);
|
||||
$lines = array();
|
||||
$currentLine = null;
|
||||
foreach ($words as $word) {
|
||||
if ($currentLine === null) {
|
||||
$currentLine = $word;
|
||||
} else {
|
||||
$testLine = $currentLine . ' ' . $word;
|
||||
$testbox = $this->box($testLine, $angle);
|
||||
if ($testbox->getWidth() <= $maxWidth) {
|
||||
$currentLine = $testLine;
|
||||
} else {
|
||||
$lines[] = $currentLine;
|
||||
$currentLine = $word;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($currentLine !== null) {
|
||||
$lines[] = $currentLine;
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::getClassFactory()
|
||||
*/
|
||||
public function getClassFactory()
|
||||
{
|
||||
if ($this->classFactory === null) {
|
||||
$this->classFactory = new ClassFactory();
|
||||
}
|
||||
|
||||
return $this->classFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::setClassFactory()
|
||||
*/
|
||||
public function setClassFactory(ClassFactoryInterface $classFactory)
|
||||
{
|
||||
$this->classFactory = $classFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
216
vendor/imagine/imagine/src/Image/AbstractImage.php
vendored
Normal file
216
vendor/imagine/imagine/src/Image/AbstractImage.php
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Factory\ClassFactory;
|
||||
use Imagine\Factory\ClassFactoryAwareInterface;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
|
||||
abstract class AbstractImage implements ImageInterface, ClassFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Metadata\MetadataBag
|
||||
*/
|
||||
protected $metadata;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Factory\ClassFactoryInterface|null
|
||||
*/
|
||||
private $classFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ManipulatorInterface::thumbnail()
|
||||
*/
|
||||
public function thumbnail(BoxInterface $size, $settings = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED)
|
||||
{
|
||||
$settings = $this->checkThumbnailSettings($settings);
|
||||
|
||||
$mode = $settings & 0xffff;
|
||||
|
||||
$allowUpscale = (bool) ($settings & ImageInterface::THUMBNAIL_FLAG_UPSCALE);
|
||||
$noClone = (bool) ($settings & ImageInterface::THUMBNAIL_FLAG_NOCLONE);
|
||||
|
||||
$imageSize = $this->getSize();
|
||||
$palette = $this->palette();
|
||||
|
||||
$thumbnail = $noClone ? $this : $this->copy();
|
||||
|
||||
$thumbnail->usePalette($palette);
|
||||
$thumbnail->strip();
|
||||
|
||||
if ($size->getWidth() === $imageSize->getWidth() && $size->getHeight() === $imageSize->getHeight()) {
|
||||
// The thumbnail size is the same as the wanted size.
|
||||
return $thumbnail;
|
||||
}
|
||||
if (!$allowUpscale && $size->contains($imageSize)) {
|
||||
// Thumbnail is smaller than the image and we are not upscaling
|
||||
return $thumbnail;
|
||||
}
|
||||
|
||||
$ratios = array(
|
||||
$size->getWidth() / $imageSize->getWidth(),
|
||||
$size->getHeight() / $imageSize->getHeight(),
|
||||
);
|
||||
switch ($mode) {
|
||||
case ImageInterface::THUMBNAIL_OUTBOUND:
|
||||
// Crop the image so that it fits the wanted size
|
||||
$ratio = max($ratios);
|
||||
if ($imageSize->contains($size)) {
|
||||
// Downscale the image
|
||||
$imageSize = $imageSize->scale($ratio);
|
||||
$thumbnail->resize($imageSize, $filter);
|
||||
$thumbnailSize = $size;
|
||||
} else {
|
||||
if ($allowUpscale) {
|
||||
// Upscale the image so that the max dimension will be the wanted one
|
||||
$imageSize = $imageSize->scale($ratio);
|
||||
$thumbnail->resize($imageSize, $filter);
|
||||
}
|
||||
$thumbnailSize = new Box(
|
||||
min($imageSize->getWidth(), $size->getWidth()),
|
||||
min($imageSize->getHeight(), $size->getHeight())
|
||||
);
|
||||
}
|
||||
$thumbnail->crop(
|
||||
new Point(
|
||||
max(0, round(($imageSize->getWidth() - $size->getWidth()) / 2)),
|
||||
max(0, round(($imageSize->getHeight() - $size->getHeight()) / 2))
|
||||
),
|
||||
$thumbnailSize
|
||||
);
|
||||
break;
|
||||
case ImageInterface::THUMBNAIL_INSET:
|
||||
default:
|
||||
// Scale the image so that it fits the wanted size
|
||||
$ratio = min($ratios);
|
||||
$thumbnailSize = $imageSize->scale($ratio);
|
||||
$thumbnail->resize($thumbnailSize, $filter);
|
||||
break;
|
||||
}
|
||||
|
||||
return $thumbnail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the settings argument in thumbnail() method.
|
||||
*
|
||||
* @param int $settings
|
||||
*/
|
||||
private function checkThumbnailSettings($settings)
|
||||
{
|
||||
// Preserve BC until version 1.0
|
||||
if (is_string($settings)) {
|
||||
if ($settings === 'inset') {
|
||||
$settings = ImageInterface::THUMBNAIL_INSET;
|
||||
} elseif ($settings === 'outbound') {
|
||||
$settings = ImageInterface::THUMBNAIL_OUTBOUND;
|
||||
} elseif (is_numeric($settings)) {
|
||||
$settings = (int) $settings;
|
||||
}
|
||||
}
|
||||
if (!is_int($settings)) {
|
||||
throw new InvalidArgumentException('Invalid setting specified');
|
||||
}
|
||||
$mode = $settings & 0xffff;
|
||||
if ($mode === 0) {
|
||||
$settings |= ImageInterface::THUMBNAIL_INSET;
|
||||
} else {
|
||||
if (!in_array($mode, $this->getAllThumbnailModes())) {
|
||||
if (strlen(str_replace('0', '', decbin($mode))) === 1) {
|
||||
throw new InvalidArgumentException('Invalid setting specified');
|
||||
}
|
||||
throw new InvalidArgumentException('Only one mode should be specified');
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the available thumbnail modes.
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
protected function getAllThumbnailModes()
|
||||
{
|
||||
return array(
|
||||
ImageInterface::THUMBNAIL_INSET,
|
||||
ImageInterface::THUMBNAIL_OUTBOUND,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a given array of save options for backward compatibility with legacy names.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function updateSaveOptions(array $options)
|
||||
{
|
||||
// Preserve BC until version 1.0
|
||||
if (isset($options['quality']) && !isset($options['jpeg_quality'])) {
|
||||
$options['jpeg_quality'] = $options['quality'];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImageInterface::metadata()
|
||||
*/
|
||||
public function metadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones all the resources associated to this instance.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
if ($this->metadata !== null) {
|
||||
$this->metadata = clone $this->metadata;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::getClassFactory()
|
||||
*/
|
||||
public function getClassFactory()
|
||||
{
|
||||
if ($this->classFactory === null) {
|
||||
$this->classFactory = new ClassFactory();
|
||||
}
|
||||
|
||||
return $this->classFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::setClassFactory()
|
||||
*/
|
||||
public function setClassFactory(ClassFactoryInterface $classFactory)
|
||||
{
|
||||
$this->classFactory = $classFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
110
vendor/imagine/imagine/src/Image/AbstractImagine.php
vendored
Normal file
110
vendor/imagine/imagine/src/Image/AbstractImagine.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Factory\ClassFactory;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\Metadata\MetadataReaderInterface;
|
||||
|
||||
abstract class AbstractImagine implements ImagineInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Metadata\MetadataReaderInterface|null
|
||||
*/
|
||||
private $metadataReader;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Factory\ClassFactoryInterface
|
||||
*/
|
||||
private $classFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::setMetadataReader()
|
||||
*/
|
||||
public function setMetadataReader(MetadataReaderInterface $metadataReader)
|
||||
{
|
||||
$this->metadataReader = $metadataReader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::getMetadataReader()
|
||||
*/
|
||||
public function getMetadataReader()
|
||||
{
|
||||
if (null === $this->metadataReader) {
|
||||
$this->metadataReader = $this->getClassFactory()->createMetadataReader();
|
||||
}
|
||||
|
||||
return $this->metadataReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::setClassFactory()
|
||||
*/
|
||||
public function setClassFactory(ClassFactoryInterface $classFactory)
|
||||
{
|
||||
$this->classFactory = $classFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::getClassFactory()
|
||||
*/
|
||||
public function getClassFactory()
|
||||
{
|
||||
if ($this->classFactory === null) {
|
||||
$this->classFactory = new ClassFactory();
|
||||
}
|
||||
|
||||
return $this->classFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a path that could be used with ImagineInterface::open and returns
|
||||
* a proper string.
|
||||
*
|
||||
* @param string|object $path
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException in case the given path is invalid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function checkPath($path)
|
||||
{
|
||||
// provide compatibility with objects such as \SplFileInfo
|
||||
if (is_object($path) && method_exists($path, '__toString')) {
|
||||
$path = (string) $path;
|
||||
}
|
||||
|
||||
$handle = @fopen($path, 'r');
|
||||
|
||||
if (false === $handle) {
|
||||
throw new InvalidArgumentException(sprintf('File %s does not exist.', $path));
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
106
vendor/imagine/imagine/src/Image/AbstractLayers.php
vendored
Normal file
106
vendor/imagine/imagine/src/Image/AbstractLayers.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Factory\ClassFactory;
|
||||
use Imagine\Factory\ClassFactoryAwareInterface;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
|
||||
abstract class AbstractLayers implements LayersInterface, ClassFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Factory\ClassFactoryInterface|null
|
||||
*/
|
||||
private $classFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::add()
|
||||
*/
|
||||
public function add(ImageInterface $image)
|
||||
{
|
||||
$this[] = $image;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::set()
|
||||
*/
|
||||
public function set($offset, ImageInterface $image)
|
||||
{
|
||||
$this[$offset] = $image;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::remove()
|
||||
*/
|
||||
public function remove($offset)
|
||||
{
|
||||
unset($this[$offset]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::get()
|
||||
*/
|
||||
public function get($offset)
|
||||
{
|
||||
return $this[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::has()
|
||||
*/
|
||||
public function has($offset)
|
||||
{
|
||||
return isset($this[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::setClassFactory()
|
||||
*/
|
||||
public function setClassFactory(ClassFactoryInterface $classFactory)
|
||||
{
|
||||
$this->classFactory = $classFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Factory\ClassFactoryAwareInterface::getClassFactory()
|
||||
*/
|
||||
public function getClassFactory()
|
||||
{
|
||||
if ($this->classFactory === null) {
|
||||
$this->classFactory = new ClassFactory();
|
||||
}
|
||||
|
||||
return $this->classFactory;
|
||||
}
|
||||
}
|
||||
148
vendor/imagine/imagine/src/Image/Box.php
vendored
Normal file
148
vendor/imagine/imagine/src/Image/Box.php
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* A box implementation.
|
||||
*/
|
||||
final class Box implements BoxInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* Constructs the Size with given width and height.
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($width, $height)
|
||||
{
|
||||
if (!\is_int($width)) {
|
||||
$width = (int) round($width);
|
||||
}
|
||||
if (!\is_int($height)) {
|
||||
$height = (int) round($height);
|
||||
}
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
if ($this->width < 1 || $this->height < 1) {
|
||||
throw new InvalidArgumentException(sprintf('Length of either side cannot be 0 or negative, current size is %sx%s', $width, $height));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::getWidth()
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::getHeight()
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::scale()
|
||||
*/
|
||||
public function scale($ratio)
|
||||
{
|
||||
$width = max(1, round($ratio * $this->width));
|
||||
$height = max(1, round($ratio * $this->height));
|
||||
|
||||
return new self($width, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::increase()
|
||||
*/
|
||||
public function increase($size)
|
||||
{
|
||||
return new self((int) $size + $this->width, (int) $size + $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::contains()
|
||||
*/
|
||||
public function contains(BoxInterface $box, PointInterface $start = null)
|
||||
{
|
||||
$start = $start ? $start : new Point(0, 0);
|
||||
|
||||
return $start->in($this) && $this->width >= $box->getWidth() + $start->getX() && $this->height >= $box->getHeight() + $start->getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::square()
|
||||
*/
|
||||
public function square()
|
||||
{
|
||||
return $this->width * $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('%dx%d px', $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::widen()
|
||||
*/
|
||||
public function widen($width)
|
||||
{
|
||||
return $this->scale($width / $this->width);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\BoxInterface::heighten()
|
||||
*/
|
||||
public function heighten($height)
|
||||
{
|
||||
return $this->scale($height / $this->height);
|
||||
}
|
||||
}
|
||||
94
vendor/imagine/imagine/src/Image/BoxInterface.php
vendored
Normal file
94
vendor/imagine/imagine/src/Image/BoxInterface.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
/**
|
||||
* Interface for a box.
|
||||
*/
|
||||
interface BoxInterface
|
||||
{
|
||||
/**
|
||||
* Gets box height.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight();
|
||||
|
||||
/**
|
||||
* Gets box width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth();
|
||||
|
||||
/**
|
||||
* Creates new BoxInterface instance with ratios applied to both sides.
|
||||
*
|
||||
* @param float $ratio
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function scale($ratio);
|
||||
|
||||
/**
|
||||
* Creates new BoxInterface, adding given size to both sides.
|
||||
*
|
||||
* @param int $size
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function increase($size);
|
||||
|
||||
/**
|
||||
* Checks whether current box can fit given box at a given start position,
|
||||
* start position defaults to top left corner xy(0,0).
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $box
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains(BoxInterface $box, PointInterface $start = null);
|
||||
|
||||
/**
|
||||
* Gets current box square, useful for getting total number of pixels in a
|
||||
* given box.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function square();
|
||||
|
||||
/**
|
||||
* Returns a string representation of the current box.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Resizes box to given width, constraining proportions and returns the new box.
|
||||
*
|
||||
* @param int $width
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function widen($width);
|
||||
|
||||
/**
|
||||
* Resizes box to given height, constraining proportions and returns the new box.
|
||||
*
|
||||
* @param int $height
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function heighten($height);
|
||||
}
|
||||
29
vendor/imagine/imagine/src/Image/Fill/FillInterface.php
vendored
Normal file
29
vendor/imagine/imagine/src/Image/Fill/FillInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Fill;
|
||||
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Interface for the fill.
|
||||
*/
|
||||
interface FillInterface
|
||||
{
|
||||
/**
|
||||
* Gets color of the fill for the given position.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $position
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function getColor(PointInterface $position);
|
||||
}
|
||||
30
vendor/imagine/imagine/src/Image/Fill/Gradient/Horizontal.php
vendored
Normal file
30
vendor/imagine/imagine/src/Image/Fill/Gradient/Horizontal.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Fill\Gradient;
|
||||
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Horizontal gradient fill.
|
||||
*/
|
||||
final class Horizontal extends Linear
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Fill\Gradient\Linear::getDistance()
|
||||
*/
|
||||
public function getDistance(PointInterface $position)
|
||||
{
|
||||
return $position->getX();
|
||||
}
|
||||
}
|
||||
97
vendor/imagine/imagine/src/Image/Fill/Gradient/Linear.php
vendored
Normal file
97
vendor/imagine/imagine/src/Image/Fill/Gradient/Linear.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Fill\Gradient;
|
||||
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Linear gradient fill.
|
||||
*/
|
||||
abstract class Linear implements FillInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $length;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
private $end;
|
||||
|
||||
/**
|
||||
* Constructs a linear gradient with overall gradient length, and start and
|
||||
* end shades, which default to 0 and 255 accordingly.
|
||||
*
|
||||
* @param int $length
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $start
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $end
|
||||
*/
|
||||
final public function __construct($length, ColorInterface $start, ColorInterface $end)
|
||||
{
|
||||
$this->length = $length;
|
||||
$this->start = $start;
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Fill\FillInterface::getColor()
|
||||
*/
|
||||
final public function getColor(PointInterface $position)
|
||||
{
|
||||
$l = $this->getDistance($position);
|
||||
|
||||
if ($l >= $this->length) {
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
if ($l < 0) {
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
return $this->start->getPalette()->blend($this->start, $this->end, $l / $this->length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
final public function getStart()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
final public function getEnd()
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance of the position relative to the beginning of the gradient.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $position
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
abstract protected function getDistance(PointInterface $position);
|
||||
}
|
||||
30
vendor/imagine/imagine/src/Image/Fill/Gradient/Vertical.php
vendored
Normal file
30
vendor/imagine/imagine/src/Image/Fill/Gradient/Vertical.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Fill\Gradient;
|
||||
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Vertical gradient fill.
|
||||
*/
|
||||
final class Vertical extends Linear
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Fill\Gradient\Linear::getDistance()
|
||||
*/
|
||||
public function getDistance(PointInterface $position)
|
||||
{
|
||||
return $position->getY();
|
||||
}
|
||||
}
|
||||
60
vendor/imagine/imagine/src/Image/FontInterface.php
vendored
Normal file
60
vendor/imagine/imagine/src/Image/FontInterface.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
/**
|
||||
* The font interface.
|
||||
*/
|
||||
interface FontInterface
|
||||
{
|
||||
/**
|
||||
* Gets the fontfile for current font.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFile();
|
||||
|
||||
/**
|
||||
* Gets font's integer point size.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Gets font's color.
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function getColor();
|
||||
|
||||
/**
|
||||
* Gets BoxInterface of font size on the image based on string and angle.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $angle
|
||||
*
|
||||
* @return \Imagine\Image\BoxInterface
|
||||
*/
|
||||
public function box($string, $angle = 0);
|
||||
|
||||
/**
|
||||
* Split a string into multiple lines so that it fits a specific width.
|
||||
*
|
||||
* @param string $string The text to be wrapped
|
||||
* @param int $maxWidth The maximum width of the text
|
||||
* @param int $angle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function wrapText($string, $maxWidth, $angle = 0);
|
||||
}
|
||||
60
vendor/imagine/imagine/src/Image/Histogram/Bucket.php
vendored
Normal file
60
vendor/imagine/imagine/src/Image/Histogram/Bucket.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Histogram;
|
||||
|
||||
/**
|
||||
* Bucket histogram.
|
||||
*/
|
||||
final class Bucket implements \Countable
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Histogram\Range
|
||||
*/
|
||||
private $range;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $count;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\Histogram\Range $range
|
||||
* @param int $count
|
||||
*/
|
||||
public function __construct(Range $range, $count = 0)
|
||||
{
|
||||
$this->range = $range;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add($value)
|
||||
{
|
||||
if ($this->range->contains($value)) {
|
||||
$this->count++;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int the number of elements in the bucket
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
}
|
||||
56
vendor/imagine/imagine/src/Image/Histogram/Range.php
vendored
Normal file
56
vendor/imagine/imagine/src/Image/Histogram/Range.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Histogram;
|
||||
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Range histogram.
|
||||
*/
|
||||
final class Range
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $end;
|
||||
|
||||
/**
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
*
|
||||
* @throws \Imagine\Exception\OutOfBoundsException
|
||||
*/
|
||||
public function __construct($start, $end)
|
||||
{
|
||||
if ($end <= $start) {
|
||||
throw new OutOfBoundsException(sprintf('Range end cannot be bigger than start, %d %d given accordingly', $this->start, $this->end));
|
||||
}
|
||||
|
||||
$this->start = $start;
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($value)
|
||||
{
|
||||
return $value >= $this->start && $value < $this->end;
|
||||
}
|
||||
}
|
||||
297
vendor/imagine/imagine/src/Image/ImageInterface.php
vendored
Normal file
297
vendor/imagine/imagine/src/Image/ImageInterface.php
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
|
||||
/**
|
||||
* The image interface.
|
||||
*/
|
||||
interface ImageInterface extends ManipulatorInterface
|
||||
{
|
||||
/**
|
||||
* Resolution units: pixels per inch.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const RESOLUTION_PIXELSPERINCH = 'ppi';
|
||||
|
||||
/**
|
||||
* Resolution units: pixels per centimeter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const RESOLUTION_PIXELSPERCENTIMETER = 'ppc';
|
||||
|
||||
/**
|
||||
* Image interlacing: none.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const INTERLACE_NONE = 'none';
|
||||
|
||||
/**
|
||||
* Image interlacing: scanline.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const INTERLACE_LINE = 'line';
|
||||
|
||||
/**
|
||||
* Image interlacing: plane.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const INTERLACE_PLANE = 'plane';
|
||||
|
||||
/**
|
||||
* Image interlacing: like plane interlacing except the different planes are saved to individual files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const INTERLACE_PARTITION = 'partition';
|
||||
|
||||
/**
|
||||
* Image filter: none/undefined.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_UNDEFINED = 'undefined';
|
||||
|
||||
/**
|
||||
* Resampling filter: point (interpolated).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_POINT = 'point';
|
||||
|
||||
/**
|
||||
* Resampling filter: box.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_BOX = 'box';
|
||||
|
||||
/**
|
||||
* Resampling filter: triangle.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_TRIANGLE = 'triangle';
|
||||
|
||||
/**
|
||||
* Resampling filter: hermite.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_HERMITE = 'hermite';
|
||||
|
||||
/**
|
||||
* Resampling filter: hanning.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_HANNING = 'hanning';
|
||||
|
||||
/**
|
||||
* Resampling filter: hamming.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_HAMMING = 'hamming';
|
||||
|
||||
/**
|
||||
* Resampling filter: blackman.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_BLACKMAN = 'blackman';
|
||||
|
||||
/**
|
||||
* Resampling filter: gaussian.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_GAUSSIAN = 'gaussian';
|
||||
|
||||
/**
|
||||
* Resampling filter: quadratic.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_QUADRATIC = 'quadratic';
|
||||
|
||||
/**
|
||||
* Resampling filter: cubic.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_CUBIC = 'cubic';
|
||||
|
||||
/**
|
||||
* Resampling filter: catrom.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_CATROM = 'catrom';
|
||||
|
||||
/**
|
||||
* Resampling filter: mitchell.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_MITCHELL = 'mitchell';
|
||||
|
||||
/**
|
||||
* Resampling filter: lanczos.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_LANCZOS = 'lanczos';
|
||||
|
||||
/**
|
||||
* Resampling filter: bessel.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_BESSEL = 'bessel';
|
||||
|
||||
/**
|
||||
* Resampling filter: sinc.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILTER_SINC = 'sinc';
|
||||
|
||||
/**
|
||||
* Returns the image content as a binary string.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $options
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return string binary
|
||||
*/
|
||||
public function get($format, array $options = array());
|
||||
|
||||
/**
|
||||
* Returns the image content as a PNG binary string.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return string binary
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Instantiates and returns a DrawerInterface instance for image drawing.
|
||||
*
|
||||
* @return \Imagine\Draw\DrawerInterface
|
||||
*/
|
||||
public function draw();
|
||||
|
||||
/**
|
||||
* @return \Imagine\Effects\EffectsInterface
|
||||
*/
|
||||
public function effects();
|
||||
|
||||
/**
|
||||
* Returns current image size.
|
||||
*
|
||||
* @return \Imagine\Image\BoxInterface
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Transforms creates a grayscale mask from current image, returns a new
|
||||
* image, while keeping the existing image unmodified.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function mask();
|
||||
|
||||
/**
|
||||
* Returns array of image colors as Imagine\Image\Palette\Color\ColorInterface instances.
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface[]
|
||||
*/
|
||||
public function histogram();
|
||||
|
||||
/**
|
||||
* Returns color at specified positions of current image.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $point
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function getColorAt(PointInterface $point);
|
||||
|
||||
/**
|
||||
* Returns the image layers when applicable.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException In case the layer can not be returned
|
||||
* @throws \Imagine\Exception\OutOfBoundsException In case the index is not a valid value
|
||||
*
|
||||
* @return \Imagine\Image\LayersInterface
|
||||
*/
|
||||
public function layers();
|
||||
|
||||
/**
|
||||
* Enables or disables interlacing.
|
||||
*
|
||||
* @param string $scheme
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException When an unsupported Interface type is supplied
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function interlace($scheme);
|
||||
|
||||
/**
|
||||
* Return the current color palette.
|
||||
*
|
||||
* @return \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
public function palette();
|
||||
|
||||
/**
|
||||
* Set a palette for the image. Useful to change colorspace.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\PaletteInterface $palette
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function usePalette(PaletteInterface $palette);
|
||||
|
||||
/**
|
||||
* Applies a color profile on the Image.
|
||||
*
|
||||
* @param \Imagine\Image\ProfileInterface $profile
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function profile(ProfileInterface $profile);
|
||||
|
||||
/**
|
||||
* Returns the Image's meta data.
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataBag
|
||||
*/
|
||||
public function metadata();
|
||||
}
|
||||
99
vendor/imagine/imagine/src/Image/ImagineInterface.php
vendored
Normal file
99
vendor/imagine/imagine/src/Image/ImagineInterface.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Factory\ClassFactoryAwareInterface;
|
||||
use Imagine\Image\Metadata\MetadataReaderInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* The imagine interface.
|
||||
*/
|
||||
interface ImagineInterface extends ClassFactoryAwareInterface
|
||||
{
|
||||
const VERSION = '1.2.3';
|
||||
|
||||
/**
|
||||
* Creates a new empty image with an optional background color.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function create(BoxInterface $size, ColorInterface $color = null);
|
||||
|
||||
/**
|
||||
* Opens an existing image from $path.
|
||||
*
|
||||
* @param string|\Imagine\File\LoaderInterface|mixed $path the file path, a LoaderInterface instance, or an object whose string representation is the image path
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function open($path);
|
||||
|
||||
/**
|
||||
* Loads an image from a binary $string.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function load($string);
|
||||
|
||||
/**
|
||||
* Loads an image from a resource $resource.
|
||||
*
|
||||
* @param resource $resource
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function read($resource);
|
||||
|
||||
/**
|
||||
* Constructs a font with specified $file, $size and $color.
|
||||
*
|
||||
* The font size is to be specified in points (e.g. 10pt means 10)
|
||||
*
|
||||
* @param string $file
|
||||
* @param int $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @return \Imagine\Image\FontInterface
|
||||
*/
|
||||
public function font($file, $size, ColorInterface $color);
|
||||
|
||||
/**
|
||||
* Set the object to be used to read image metadata.
|
||||
*
|
||||
* @param \Imagine\Image\Metadata\MetadataReaderInterface $metadataReader
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMetadataReader(MetadataReaderInterface $metadataReader);
|
||||
|
||||
/**
|
||||
* Get the object to be used to read image metadata.
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataReaderInterface
|
||||
*/
|
||||
public function getMetadataReader();
|
||||
}
|
||||
107
vendor/imagine/imagine/src/Image/LayersInterface.php
vendored
Normal file
107
vendor/imagine/imagine/src/Image/LayersInterface.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
/**
|
||||
* The layers interface.
|
||||
*/
|
||||
interface LayersInterface extends \Iterator, \Countable, \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Merge layers into the original objects.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
public function merge();
|
||||
|
||||
/**
|
||||
* Animates layers.
|
||||
*
|
||||
* @param string $format The output output format
|
||||
* @param int $delay The delay in milliseconds between two frames
|
||||
* @param int $loops The number of loops, 0 means infinite
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException In case an invalid argument is provided
|
||||
* @throws \Imagine\Exception\RuntimeException In case the driver fails to animate
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function animate($format, $delay, $loops);
|
||||
|
||||
/**
|
||||
* Coalesce layers. Each layer in the sequence is the same size as the first and composited with the next layer in
|
||||
* the sequence.
|
||||
*
|
||||
* @throws \Imagine\Exception\NotSupportedException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function coalesce();
|
||||
|
||||
/**
|
||||
* Adds an image at the end of the layers stack.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add(ImageInterface $image);
|
||||
|
||||
/**
|
||||
* Set an image at offset.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\OutOfBoundsException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set($offset, ImageInterface $image);
|
||||
|
||||
/**
|
||||
* Removes the image at offset.
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function remove($offset);
|
||||
|
||||
/**
|
||||
* Returns the image at offset.
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return \Imagine\Image\ImageInterface
|
||||
*/
|
||||
public function get($offset);
|
||||
|
||||
/**
|
||||
* Returns true if a layer at offset is preset.
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($offset);
|
||||
}
|
||||
204
vendor/imagine/imagine/src/Image/ManipulatorInterface.php
vendored
Normal file
204
vendor/imagine/imagine/src/Image/ManipulatorInterface.php
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* The manipulator interface.
|
||||
*/
|
||||
interface ManipulatorInterface
|
||||
{
|
||||
/**
|
||||
* The original image is scaled so it is fully contained within the thumbnail dimensions (the image width/height ratio doesn't change).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const THUMBNAIL_INSET = 0x00000001;
|
||||
|
||||
/**
|
||||
* The thumbnail is scaled so that its smallest side equals the length of the corresponding side in the original image (the width or the height are cropped).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const THUMBNAIL_OUTBOUND = 0x00000002;
|
||||
|
||||
/**
|
||||
* Allow upscaling the image if it's smaller than the wanted thumbnail size.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const THUMBNAIL_FLAG_UPSCALE = 0x00010000;
|
||||
|
||||
/**
|
||||
* Instead of creating a new image instance, the thumbnail method modifies the original image (saving memory.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const THUMBNAIL_FLAG_NOCLONE = 0x00020000;
|
||||
|
||||
/**
|
||||
* Copies current source image into a new ImageInterface instance.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function copy();
|
||||
|
||||
/**
|
||||
* Crops a specified box out of the source image (modifies the source image)
|
||||
* Returns cropped self.
|
||||
*
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
*
|
||||
* @throws \Imagine\Exception\OutOfBoundsException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function crop(PointInterface $start, BoxInterface $size);
|
||||
|
||||
/**
|
||||
* Resizes current image and returns self.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param string $filter
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED);
|
||||
|
||||
/**
|
||||
* Rotates an image at the given angle.
|
||||
* Optional $background can be used to specify the fill color of the empty
|
||||
* area of rotated image.
|
||||
*
|
||||
* @param int $angle
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $background
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function rotate($angle, ColorInterface $background = null);
|
||||
|
||||
/**
|
||||
* Pastes an image into a parent image
|
||||
* Throws exceptions if image exceeds parent image borders or if paste
|
||||
* operation fails.
|
||||
*
|
||||
* Returns source image
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $image
|
||||
* @param \Imagine\Image\PointInterface $start
|
||||
* @param int $alpha How to paste the image, from 0 (fully transparent) to 100 (fully opaque)
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function paste(ImageInterface $image, PointInterface $start, $alpha = 100);
|
||||
|
||||
/**
|
||||
* Saves the image at a specified path, the target file extension is used
|
||||
* to determine file format, only jpg, jpeg, gif, png, wbmp, xbm, webp and bmp are
|
||||
* supported.
|
||||
* Please remark that bmp is supported by the GD driver only since PHP 7.2.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $options
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function save($path = null, array $options = array());
|
||||
|
||||
/**
|
||||
* Outputs the image content.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $options
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function show($format, array $options = array());
|
||||
|
||||
/**
|
||||
* Flips current image using vertical axis.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function flipHorizontally();
|
||||
|
||||
/**
|
||||
* Flips current image using horizontal axis.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function flipVertically();
|
||||
|
||||
/**
|
||||
* Remove all profiles and comments.
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function strip();
|
||||
|
||||
/**
|
||||
* Generates a thumbnail from a current image
|
||||
* Returns it as a new image without modifying the current image unless the THUMBNAIL_FLAG_NOCLONE flag is specified.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $size
|
||||
* @param int|string $settings One or more of the ManipulatorInterface::THUMBNAIL_ flags (joined with |). It may be a string for backward compatibility with old constant values that were strings.
|
||||
* @param string $filter The filter to use for resizing, one of ImageInterface::FILTER_*
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function thumbnail(BoxInterface $size, $settings = self::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED);
|
||||
|
||||
/**
|
||||
* Applies a given mask to current image's alpha channel.
|
||||
*
|
||||
* @param \Imagine\Image\ImageInterface $mask
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function applyMask(ImageInterface $mask);
|
||||
|
||||
/**
|
||||
* Fills image with provided filling, by replacing each pixel's color in
|
||||
* the current image with corresponding color from FillInterface, and
|
||||
* returns modified image.
|
||||
*
|
||||
* @param \Imagine\Image\Fill\FillInterface $fill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fill(FillInterface $fill);
|
||||
}
|
||||
117
vendor/imagine/imagine/src/Image/Metadata/AbstractMetadataReader.php
vendored
Normal file
117
vendor/imagine/imagine/src/Image/Metadata/AbstractMetadataReader.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Metadata;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\File\Loader;
|
||||
use Imagine\File\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Base class for the default metadata readers.
|
||||
*/
|
||||
abstract class AbstractMetadataReader implements MetadataReaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\MetadataReaderInterface::readFile()
|
||||
*/
|
||||
public function readFile($file)
|
||||
{
|
||||
$loader = $file instanceof LoaderInterface ? $file : new Loader($file);
|
||||
|
||||
return new MetadataBag(array_merge($this->getStreamMetadata($loader), $this->extractFromFile($loader)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\MetadataReaderInterface::readData()
|
||||
*/
|
||||
public function readData($data, $originalResource = null)
|
||||
{
|
||||
if (null !== $originalResource) {
|
||||
return new MetadataBag(array_merge($this->getStreamMetadata($originalResource), $this->extractFromData($data)));
|
||||
}
|
||||
|
||||
return new MetadataBag($this->extractFromData($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\MetadataReaderInterface::readStream()
|
||||
*/
|
||||
public function readStream($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new InvalidArgumentException('Invalid resource provided.');
|
||||
}
|
||||
|
||||
return new MetadataBag(array_merge($this->getStreamMetadata($resource), $this->extractFromStream($resource)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI from a stream resource.
|
||||
*
|
||||
* @param resource|\Imagine\File\LoaderInterface $resource
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getStreamMetadata($resource)
|
||||
{
|
||||
$metadata = array();
|
||||
|
||||
if ($resource instanceof LoaderInterface) {
|
||||
$metadata['uri'] = $resource->getPath();
|
||||
if ($resource->isLocalFile()) {
|
||||
$metadata['filepath'] = realpath($resource->getPath());
|
||||
}
|
||||
} elseif (false !== $data = @stream_get_meta_data($resource)) {
|
||||
if (isset($data['uri'])) {
|
||||
$metadata['uri'] = $data['uri'];
|
||||
if (stream_is_local($resource)) {
|
||||
$metadata['filepath'] = realpath($data['uri']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts metadata from a file.
|
||||
*
|
||||
* @param string|\Imagine\File\LoaderInterface $file
|
||||
*
|
||||
* @return array An associative array of metadata
|
||||
*/
|
||||
abstract protected function extractFromFile($file);
|
||||
|
||||
/**
|
||||
* Extracts metadata from raw data.
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return array An associative array of metadata
|
||||
*/
|
||||
abstract protected function extractFromData($data);
|
||||
|
||||
/**
|
||||
* Extracts metadata from a stream.
|
||||
*
|
||||
* @param $resource
|
||||
*
|
||||
* @return array An associative array of metadata
|
||||
*/
|
||||
abstract protected function extractFromStream($resource);
|
||||
}
|
||||
48
vendor/imagine/imagine/src/Image/Metadata/DefaultMetadataReader.php
vendored
Normal file
48
vendor/imagine/imagine/src/Image/Metadata/DefaultMetadataReader.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Metadata;
|
||||
|
||||
/**
|
||||
* A metadata reader that actually doesn't try to extract metadata.
|
||||
*/
|
||||
class DefaultMetadataReader extends AbstractMetadataReader
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromFile()
|
||||
*/
|
||||
protected function extractFromFile($file)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromData()
|
||||
*/
|
||||
protected function extractFromData($data)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromStream()
|
||||
*/
|
||||
protected function extractFromStream($resource)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
149
vendor/imagine/imagine/src/Image/Metadata/ExifMetadataReader.php
vendored
Normal file
149
vendor/imagine/imagine/src/Image/Metadata/ExifMetadataReader.php
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Metadata;
|
||||
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\File\Loader;
|
||||
use Imagine\File\LoaderInterface;
|
||||
use Imagine\Utils\ErrorHandling;
|
||||
|
||||
/**
|
||||
* Metadata driven by Exif information.
|
||||
*/
|
||||
class ExifMetadataReader extends AbstractMetadataReader
|
||||
{
|
||||
/**
|
||||
* @throws \Imagine\Exception\NotSupportedException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$whyNot = static::getUnsupportedReason();
|
||||
if ($whyNot !== '') {
|
||||
throw new NotSupportedException($whyNot);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reason why this metadata reader is not supported.
|
||||
*
|
||||
* @return string empty string if the reader is available
|
||||
*/
|
||||
public static function getUnsupportedReason()
|
||||
{
|
||||
if (!function_exists('exif_read_data')) {
|
||||
return 'The PHP EXIF extension is required to use the ExifMetadataReader';
|
||||
}
|
||||
if (!in_array('data', stream_get_wrappers(), true)) {
|
||||
return 'The data:// stream wrapper must be enabled';
|
||||
}
|
||||
if (in_array(ini_get('allow_url_fopen'), array('', '0', 0), true)) {
|
||||
return 'The allow_url_fopen php.ini configuration key must be set to 1';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this metadata reader supported?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return static::getUnsupportedReason() === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromFile()
|
||||
*/
|
||||
protected function extractFromFile($file)
|
||||
{
|
||||
$loader = $file instanceof LoaderInterface ? $file : new Loader($file);
|
||||
|
||||
return $this->doReadData($loader->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromData()
|
||||
*/
|
||||
protected function extractFromData($data)
|
||||
{
|
||||
return $this->doReadData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Metadata\AbstractMetadataReader::extractFromStream()
|
||||
*/
|
||||
protected function extractFromStream($resource)
|
||||
{
|
||||
return $this->doReadData(stream_get_contents($resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts metadata from raw data, merges with existing metadata.
|
||||
*
|
||||
* @param string $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function doReadData($data)
|
||||
{
|
||||
if (substr($data, 0, 2) === 'II') {
|
||||
$mime = 'image/tiff';
|
||||
} else {
|
||||
$mime = 'image/jpeg';
|
||||
}
|
||||
|
||||
return $this->extract('data://' . $mime . ';base64,' . base64_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the exif data extraction given a path or data-URI representation.
|
||||
*
|
||||
* @param string $path the path to the file or the data-URI representation
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extract($path)
|
||||
{
|
||||
try {
|
||||
$exifData = ErrorHandling::ignoring(-1, function () use ($path) {
|
||||
return @exif_read_data($path, null, true, false);
|
||||
});
|
||||
} catch (\Exception $e) {
|
||||
$exifData = false;
|
||||
} catch (\Throwable $e) {
|
||||
$exifData = false;
|
||||
}
|
||||
if (!is_array($exifData)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$metadata = array();
|
||||
foreach ($exifData as $prefix => $values) {
|
||||
if (is_array($values)) {
|
||||
$prefix = strtolower($prefix);
|
||||
foreach ($values as $prop => $value) {
|
||||
$metadata[$prefix . '.' . $prop] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
}
|
||||
114
vendor/imagine/imagine/src/Image/Metadata/MetadataBag.php
vendored
Normal file
114
vendor/imagine/imagine/src/Image/Metadata/MetadataBag.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Metadata;
|
||||
|
||||
/**
|
||||
* The container of the data extracted from metadata.
|
||||
*/
|
||||
class MetadataBag implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data = array())
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the metadata key, default value if it does not exist.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return array_key_exists($key, $this->data) ? $this->data[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IteratorAggregate::getIterator()
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetExists()
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return array_key_exists($offset, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetSet()
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetUnset()
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetGet()
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns metadata as an associative array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
50
vendor/imagine/imagine/src/Image/Metadata/MetadataReaderInterface.php
vendored
Normal file
50
vendor/imagine/imagine/src/Image/Metadata/MetadataReaderInterface.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Metadata;
|
||||
|
||||
/**
|
||||
* Interface that metadata readers must implement.
|
||||
*/
|
||||
interface MetadataReaderInterface
|
||||
{
|
||||
/**
|
||||
* Reads metadata from a file.
|
||||
*
|
||||
* @param string|\Imagine\File\LoaderInterface $file the path to the file where to read metadata
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException in case the file does not exist
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataBag
|
||||
*/
|
||||
public function readFile($file);
|
||||
|
||||
/**
|
||||
* Reads metadata from a binary string.
|
||||
*
|
||||
* @param string $data the binary string to read
|
||||
* @param resource $originalResource an optional resource to gather stream metadata
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataBag
|
||||
*/
|
||||
public function readData($data, $originalResource = null);
|
||||
|
||||
/**
|
||||
* Reads metadata from a stream.
|
||||
*
|
||||
* @param resource $resource the stream to read
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException in case the resource is not valid
|
||||
*
|
||||
* @return \Imagine\Image\Metadata\MetadataBag
|
||||
*/
|
||||
public function readStream($resource);
|
||||
}
|
||||
157
vendor/imagine/imagine/src/Image/Palette/CMYK.php
vendored
Normal file
157
vendor/imagine/imagine/src/Image/Palette/CMYK.php
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\CMYK as CMYKColor;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Profile;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
|
||||
/**
|
||||
* The CMYK palette.
|
||||
*/
|
||||
class CMYK implements PaletteInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\ColorParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\ProfileInterface|null
|
||||
*/
|
||||
private $profile;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\CMYK[]
|
||||
*/
|
||||
private static $colors = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new ColorParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::name()
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return PaletteInterface::PALETTE_CMYK;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::pixelDefinition()
|
||||
*/
|
||||
public function pixelDefinition()
|
||||
{
|
||||
return array(
|
||||
ColorInterface::COLOR_CYAN,
|
||||
ColorInterface::COLOR_MAGENTA,
|
||||
ColorInterface::COLOR_YELLOW,
|
||||
ColorInterface::COLOR_KEYLINE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::supportsAlpha()
|
||||
*/
|
||||
public function supportsAlpha()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::getChannelsMaxValue()
|
||||
*/
|
||||
public function getChannelsMaxValue()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::color()
|
||||
*/
|
||||
public function color($color, $alpha = null)
|
||||
{
|
||||
if (null !== $alpha && $alpha !== 100) {
|
||||
throw new InvalidArgumentException('CMYK palette does not support alpha');
|
||||
}
|
||||
|
||||
$color = $this->parser->parseToCMYK($color);
|
||||
$index = sprintf('cmyk(%d, %d, %d, %d)', $color[0], $color[1], $color[2], $color[3]);
|
||||
|
||||
if (false === array_key_exists($index, self::$colors)) {
|
||||
self::$colors[$index] = new CMYKColor($this, $color);
|
||||
}
|
||||
|
||||
return self::$colors[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::blend()
|
||||
*/
|
||||
public function blend(ColorInterface $color1, ColorInterface $color2, $amount)
|
||||
{
|
||||
if (!$color1 instanceof CMYKColor || !$color2 instanceof CMYKColor) {
|
||||
throw new RuntimeException('CMYK palette can only blend CMYK colors');
|
||||
}
|
||||
$max = $this->getChannelsMaxValue();
|
||||
|
||||
return $this->color(array(
|
||||
min($max, $color1->getCyan() + $color2->getCyan() * $amount),
|
||||
min($max, $color1->getMagenta() + $color2->getMagenta() * $amount),
|
||||
min($max, $color1->getYellow() + $color2->getYellow() * $amount),
|
||||
min($max, $color1->getKeyline() + $color2->getKeyline() * $amount),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::useProfile()
|
||||
*/
|
||||
public function useProfile(ProfileInterface $profile)
|
||||
{
|
||||
$this->profile = $profile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::profile()
|
||||
*/
|
||||
public function profile()
|
||||
{
|
||||
if (!$this->profile) {
|
||||
$this->profile = Profile::fromPath(__DIR__ . '/../../resources/Adobe/CMYK/USWebUncoated.icc');
|
||||
}
|
||||
|
||||
return $this->profile;
|
||||
}
|
||||
}
|
||||
238
vendor/imagine/imagine/src/Image/Palette/Color/CMYK.php
vendored
Normal file
238
vendor/imagine/imagine/src/Image/Palette/Color/CMYK.php
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette\Color;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\CMYK as CMYKPalette;
|
||||
|
||||
final class CMYK implements ColorInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $c;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $m;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $k;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\CMYK
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\Palette\CMYK $palette
|
||||
* @param int[] $color
|
||||
*/
|
||||
public function __construct(CMYKPalette $palette, array $color)
|
||||
{
|
||||
$this->palette = $palette;
|
||||
$this->setColor($color);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getValue()
|
||||
*/
|
||||
public function getValue($component)
|
||||
{
|
||||
switch ($component) {
|
||||
case ColorInterface::COLOR_CYAN:
|
||||
return $this->getCyan();
|
||||
case ColorInterface::COLOR_MAGENTA:
|
||||
return $this->getMagenta();
|
||||
case ColorInterface::COLOR_YELLOW:
|
||||
return $this->getYellow();
|
||||
case ColorInterface::COLOR_KEYLINE:
|
||||
return $this->getKeyline();
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Color component %s is not valid', $component));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Cyan value of the color (from 0 to 100).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCyan()
|
||||
{
|
||||
return $this->c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Magenta value of the color (from 0 to 100).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMagenta()
|
||||
{
|
||||
return $this->m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Yellow value of the color (from 0 to 100).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getYellow()
|
||||
{
|
||||
return $this->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Key value of the color (from 0 to 100).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getKeyline()
|
||||
{
|
||||
return $this->k;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getPalette()
|
||||
*/
|
||||
public function getPalette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getAlpha()
|
||||
*/
|
||||
public function getAlpha()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::dissolve()
|
||||
*/
|
||||
public function dissolve($alpha)
|
||||
{
|
||||
throw new RuntimeException('CMYK does not support dissolution');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::lighten()
|
||||
*/
|
||||
public function lighten($shade)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array(
|
||||
$this->c,
|
||||
$this->m,
|
||||
$this->y,
|
||||
max(0, $this->k - $shade),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::darken()
|
||||
*/
|
||||
public function darken($shade)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array(
|
||||
$this->c,
|
||||
$this->m,
|
||||
$this->y,
|
||||
min(100, $this->k + $shade),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
$color = array(
|
||||
$this->c * (1 - $this->k / 100) + $this->k,
|
||||
$this->m * (1 - $this->k / 100) + $this->k,
|
||||
$this->y * (1 - $this->k / 100) + $this->k,
|
||||
);
|
||||
|
||||
$gray = min(100, round(0.299 * $color[0] + 0.587 * $color[1] + 0.114 * $color[2]));
|
||||
|
||||
return $this->palette->color(array($gray, $gray, $gray, $this->k));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::isOpaque()
|
||||
*/
|
||||
public function isOpaque()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('cmyk(%d%%, %d%%, %d%%, %d%%)', $this->c, $this->m, $this->y, $this->k);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal, Performs checks for color validity (an of array(C, M, Y, K)).
|
||||
*
|
||||
* @param int[] $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setColor(array $color)
|
||||
{
|
||||
if (count($color) !== 4) {
|
||||
throw new InvalidArgumentException('Color argument must look like array(C, M, Y, K), where C, M, Y, K are the integer values between 0 and 100 for cyan, magenta, yellow and black color indexes accordingly');
|
||||
}
|
||||
|
||||
$colors = array_values($color);
|
||||
array_walk($colors, function (&$color) {
|
||||
$color = max(0, min(100, $color));
|
||||
});
|
||||
|
||||
list($this->c, $this->m, $this->y, $this->k) = $colors;
|
||||
}
|
||||
}
|
||||
146
vendor/imagine/imagine/src/Image/Palette/Color/ColorInterface.php
vendored
Normal file
146
vendor/imagine/imagine/src/Image/Palette/Color/ColorInterface.php
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette\Color;
|
||||
|
||||
interface ColorInterface
|
||||
{
|
||||
/**
|
||||
* Channel name: red.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_RED = 'red';
|
||||
|
||||
/**
|
||||
* Channel name: green.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_GREEN = 'green';
|
||||
|
||||
/**
|
||||
* Channel name: blue.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_BLUE = 'blue';
|
||||
|
||||
/**
|
||||
* Channel name: cyan.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_CYAN = 'cyan';
|
||||
|
||||
/**
|
||||
* Channel name: magenta.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_MAGENTA = 'magenta';
|
||||
|
||||
/**
|
||||
* Channel name: yellow.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_YELLOW = 'yellow';
|
||||
|
||||
/**
|
||||
* Channel name: key (black).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_KEYLINE = 'keyline';
|
||||
|
||||
/**
|
||||
* Channel name: gray.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COLOR_GRAY = 'gray';
|
||||
|
||||
/**
|
||||
* Return the value of one of the component.
|
||||
*
|
||||
* @param string $component One of the ColorInterface::COLOR_* component
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException if $component is not valid
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getValue($component);
|
||||
|
||||
/**
|
||||
* Returns percentage of transparency of the color (from 0 - fully transparent, to 100 - fully opaque).
|
||||
*
|
||||
* @return int|null return NULL if the color type does not support transparency
|
||||
*/
|
||||
public function getAlpha();
|
||||
|
||||
/**
|
||||
* Returns the palette attached to the current color.
|
||||
*
|
||||
* @return \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
public function getPalette();
|
||||
|
||||
/**
|
||||
* Returns a copy of current color, incrementing the alpha channel by the given amount.
|
||||
*
|
||||
* @param int $alpha
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException if the color type does not support transparency
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function dissolve($alpha);
|
||||
|
||||
/**
|
||||
* Returns a copy of the current color, lightened by the specified number of shades.
|
||||
*
|
||||
* @param int $shade
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function lighten($shade);
|
||||
|
||||
/**
|
||||
* Returns a copy of the current color, darkened by the specified number of shades.
|
||||
*
|
||||
* @param int $shade
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function darken($shade);
|
||||
|
||||
/**
|
||||
* Returns a gray related to the current color.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function grayscale();
|
||||
|
||||
/**
|
||||
* Checks if the current color is opaque.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpaque();
|
||||
|
||||
/**
|
||||
* Returns hex representation of the color.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
188
vendor/imagine/imagine/src/Image/Palette/Color/Gray.php
vendored
Normal file
188
vendor/imagine/imagine/src/Image/Palette/Color/Gray.php
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette\Color;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Image\Palette\Grayscale;
|
||||
|
||||
final class Gray implements ColorInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $gray;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $alpha;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Grayscale
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\Palette\Grayscale $palette
|
||||
* @param int[] $color
|
||||
* @param int $alpha
|
||||
*/
|
||||
public function __construct(Grayscale $palette, array $color, $alpha)
|
||||
{
|
||||
$this->palette = $palette;
|
||||
$this->setColor($color);
|
||||
$this->setAlpha($alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getValue()
|
||||
*/
|
||||
public function getValue($component)
|
||||
{
|
||||
switch ($component) {
|
||||
case ColorInterface::COLOR_GRAY:
|
||||
return $this->getGray();
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Color component %s is not valid', $component));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Gray value of the color (from 0 to 255).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGray()
|
||||
{
|
||||
return $this->gray;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getPalette()
|
||||
*/
|
||||
public function getPalette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getAlpha()
|
||||
*/
|
||||
public function getAlpha()
|
||||
{
|
||||
return $this->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::dissolve()
|
||||
*/
|
||||
public function dissolve($alpha)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array($this->gray),
|
||||
min(max((int) round($this->alpha + $alpha), 0), 100)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::lighten()
|
||||
*/
|
||||
public function lighten($shade)
|
||||
{
|
||||
return $this->palette->color(array(min(255, $this->gray + $shade)), $this->alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::darken()
|
||||
*/
|
||||
public function darken($shade)
|
||||
{
|
||||
return $this->palette->color(array(max(0, $this->gray - $shade)), $this->alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::isOpaque()
|
||||
*/
|
||||
public function isOpaque()
|
||||
{
|
||||
return 100 === $this->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('#%02x%02x%02x', $this->gray, $this->gray, $this->gray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs checks for validity of given alpha value and sets it.
|
||||
*
|
||||
* @param int $alpha
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setAlpha($alpha)
|
||||
{
|
||||
if (!is_int($alpha) || $alpha < 0 || $alpha > 100) {
|
||||
throw new InvalidArgumentException(sprintf('Alpha must be an integer between 0 and 100, %s given', $alpha));
|
||||
}
|
||||
|
||||
$this->alpha = $alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs checks for color validity (array of array(gray)).
|
||||
*
|
||||
* @param int[] $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setColor(array $color)
|
||||
{
|
||||
if (count($color) !== 1) {
|
||||
throw new InvalidArgumentException('Color argument must look like array(gray), where gray is the integer value between 0 and 255 for the grayscale');
|
||||
}
|
||||
|
||||
$color = array_values($color);
|
||||
$color[0] = max(0, min(255, $color[0]));
|
||||
|
||||
list($this->gray) = $color;
|
||||
}
|
||||
}
|
||||
242
vendor/imagine/imagine/src/Image/Palette/Color/RGB.php
vendored
Normal file
242
vendor/imagine/imagine/src/Image/Palette/Color/RGB.php
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette\Color;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Image\Palette\RGB as RGBPalette;
|
||||
|
||||
final class RGB implements ColorInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $r;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $g;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $b;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $alpha;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\RGB
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* @param \Imagine\Image\Palette\RGB $palette
|
||||
* @param int[] $color
|
||||
* @param int $alpha
|
||||
*/
|
||||
public function __construct(RGBPalette $palette, array $color, $alpha)
|
||||
{
|
||||
$this->palette = $palette;
|
||||
$this->setColor($color);
|
||||
$this->setAlpha($alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getValue()
|
||||
*/
|
||||
public function getValue($component)
|
||||
{
|
||||
switch ($component) {
|
||||
case ColorInterface::COLOR_RED:
|
||||
return $this->getRed();
|
||||
case ColorInterface::COLOR_GREEN:
|
||||
return $this->getGreen();
|
||||
case ColorInterface::COLOR_BLUE:
|
||||
return $this->getBlue();
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Color component %s is not valid', $component));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns RED value of the color (from 0 to 255).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRed()
|
||||
{
|
||||
return $this->r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns GREEN value of the color (from 0 to 255).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGreen()
|
||||
{
|
||||
return $this->g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BLUE value of the color (from 0 to 255).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBlue()
|
||||
{
|
||||
return $this->b;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getPalette()
|
||||
*/
|
||||
public function getPalette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::getAlpha()
|
||||
*/
|
||||
public function getAlpha()
|
||||
{
|
||||
return $this->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::dissolve()
|
||||
*/
|
||||
public function dissolve($alpha)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array($this->r, $this->g, $this->b),
|
||||
min(max((int) round($this->alpha + $alpha), 0), 100)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::lighten()
|
||||
*/
|
||||
public function lighten($shade)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array(
|
||||
min(255, $this->r + $shade),
|
||||
min(255, $this->g + $shade),
|
||||
min(255, $this->b + $shade),
|
||||
), $this->alpha
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::darken()
|
||||
*/
|
||||
public function darken($shade)
|
||||
{
|
||||
return $this->palette->color(
|
||||
array(
|
||||
max(0, $this->r - $shade),
|
||||
max(0, $this->g - $shade),
|
||||
max(0, $this->b - $shade),
|
||||
), $this->alpha
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
$gray = min(255, round(0.299 * $this->getRed() + 0.114 * $this->getBlue() + 0.587 * $this->getGreen()));
|
||||
|
||||
return $this->palette->color(array($gray, $gray, $gray), $this->alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::isOpaque()
|
||||
*/
|
||||
public function isOpaque()
|
||||
{
|
||||
return 100 === $this->alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\Color\ColorInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('#%02x%02x%02x', $this->r, $this->g, $this->b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal.
|
||||
*
|
||||
* Performs checks for validity of given alpha value and sets it
|
||||
*
|
||||
* @param int $alpha
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setAlpha($alpha)
|
||||
{
|
||||
if (!is_int($alpha) || $alpha < 0 || $alpha > 100) {
|
||||
throw new InvalidArgumentException(sprintf('Alpha must be an integer between 0 and 100, %s given', $alpha));
|
||||
}
|
||||
|
||||
$this->alpha = $alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal.
|
||||
*
|
||||
* Performs checks for color validity (array of array(R, G, B))
|
||||
*
|
||||
* @param array $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
private function setColor(array $color)
|
||||
{
|
||||
if (count($color) !== 3) {
|
||||
throw new InvalidArgumentException('Color argument must look like array(R, G, B), where R, G, B are the integer values between 0 and 255 for red, green and blue color indexes accordingly');
|
||||
}
|
||||
|
||||
$colors = array_values($color);
|
||||
array_walk($colors, function (&$color) {
|
||||
$color = max(0, min(255, $color));
|
||||
});
|
||||
|
||||
list($this->r, $this->g, $this->b) = $colors;
|
||||
}
|
||||
}
|
||||
157
vendor/imagine/imagine/src/Image/Palette/ColorParser.php
vendored
Normal file
157
vendor/imagine/imagine/src/Image/Palette/ColorParser.php
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
|
||||
class ColorParser
|
||||
{
|
||||
/**
|
||||
* Parses a color to a RGB tuple.
|
||||
*
|
||||
* @param string|array|int $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseToRGB($color)
|
||||
{
|
||||
$color = $this->parse($color);
|
||||
|
||||
if (4 === count($color)) {
|
||||
$color = array(
|
||||
255 * (1 - $color[0] / 100) * (1 - $color[3] / 100),
|
||||
255 * (1 - $color[1] / 100) * (1 - $color[3] / 100),
|
||||
255 * (1 - $color[2] / 100) * (1 - $color[3] / 100),
|
||||
);
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color to a CMYK tuple.
|
||||
*
|
||||
* @param string|array|int $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseToCMYK($color)
|
||||
{
|
||||
$color = $this->parse($color);
|
||||
|
||||
if (3 === count($color)) {
|
||||
$r = $color[0] / 255;
|
||||
$g = $color[1] / 255;
|
||||
$b = $color[2] / 255;
|
||||
|
||||
$k = 1 - max($r, $g, $b);
|
||||
|
||||
$color = array(
|
||||
1 === $k ? 0 : round((1 - $r - $k) / (1 - $k) * 100),
|
||||
1 === $k ? 0 : round((1 - $g - $k) / (1 - $k) * 100),
|
||||
1 === $k ? 0 : round((1 - $b - $k) / (1 - $k) * 100),
|
||||
round($k * 100),
|
||||
);
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color to a grayscale value.
|
||||
*
|
||||
* @param string|array|int $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function parseToGrayscale($color)
|
||||
{
|
||||
if (is_array($color) && 1 === count($color)) {
|
||||
return array((int) round(array_pop($color)));
|
||||
}
|
||||
|
||||
$color = array_unique($this->parse($color));
|
||||
|
||||
if (1 !== count($color)) {
|
||||
throw new InvalidArgumentException('The provided color has different values of red, green and blue components. Grayscale colors must have the same values for these.');
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color.
|
||||
*
|
||||
* @param string|array|int $color
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
private function parse($color)
|
||||
{
|
||||
if (!is_string($color) && !is_array($color) && !is_int($color)) {
|
||||
throw new InvalidArgumentException(sprintf('Color must be specified as a hexadecimal string, array or integer, %s given', gettype($color)));
|
||||
}
|
||||
|
||||
if (is_array($color)) {
|
||||
if (3 === count($color) || 4 === count($color)) {
|
||||
return array_map(
|
||||
function ($component) {
|
||||
return (int) round($component);
|
||||
},
|
||||
array_values($color)
|
||||
);
|
||||
}
|
||||
throw new InvalidArgumentException('Color argument if array, must look like array(R, G, B), or array(C, M, Y, K) where R, G, B are the integer values between 0 and 255 for red, green and blue or cyan, magenta, yellow and black color indexes accordingly');
|
||||
}
|
||||
if (is_string($color)) {
|
||||
if (0 === strpos($color, 'cmyk(')) {
|
||||
$substrColor = substr($color, 5, strlen($color) - 6);
|
||||
|
||||
$components = array_map(function ($component) {
|
||||
return (int) round(trim($component, ' %'));
|
||||
}, explode(',', $substrColor));
|
||||
|
||||
if (count($components) !== 4) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to parse color %s', $color));
|
||||
}
|
||||
|
||||
return $components;
|
||||
} else {
|
||||
$color = ltrim($color, '#');
|
||||
|
||||
if (strlen($color) !== 3 && strlen($color) !== 6) {
|
||||
throw new InvalidArgumentException(sprintf('Color must be a hex value in regular (6 characters) or short (3 characters) notation, "%s" given', $color));
|
||||
}
|
||||
|
||||
if (strlen($color) === 3) {
|
||||
$color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
|
||||
}
|
||||
|
||||
$color = array_map('hexdec', str_split($color, 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_int($color)) {
|
||||
$color = array(255 & ($color >> 16), 255 & ($color >> 8), 255 & $color);
|
||||
}
|
||||
|
||||
return $color;
|
||||
}
|
||||
}
|
||||
151
vendor/imagine/imagine/src/Image/Palette/Grayscale.php
vendored
Normal file
151
vendor/imagine/imagine/src/Image/Palette/Grayscale.php
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette;
|
||||
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\Gray as GrayColor;
|
||||
use Imagine\Image\Profile;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
|
||||
/**
|
||||
* The grayscale palette.
|
||||
*/
|
||||
class Grayscale implements PaletteInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\ColorParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\ProfileInterface|null
|
||||
*/
|
||||
private $profile;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\Gray[]
|
||||
*/
|
||||
protected static $colors = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new ColorParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::name()
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return PaletteInterface::PALETTE_GRAYSCALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::pixelDefinition()
|
||||
*/
|
||||
public function pixelDefinition()
|
||||
{
|
||||
return array(ColorInterface::COLOR_GRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::supportsAlpha()
|
||||
*/
|
||||
public function supportsAlpha()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::getChannelsMaxValue()
|
||||
*/
|
||||
public function getChannelsMaxValue()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::useProfile()
|
||||
*/
|
||||
public function useProfile(ProfileInterface $profile)
|
||||
{
|
||||
$this->profile = $profile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::profile()
|
||||
*/
|
||||
public function profile()
|
||||
{
|
||||
if (!$this->profile) {
|
||||
$this->profile = Profile::fromPath(__DIR__ . '/../../resources/colormanagement.org/ISOcoated_v2_grey1c_bas.ICC');
|
||||
}
|
||||
|
||||
return $this->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::color()
|
||||
*/
|
||||
public function color($color, $alpha = null)
|
||||
{
|
||||
if (null === $alpha) {
|
||||
$alpha = 0;
|
||||
}
|
||||
|
||||
$color = $this->parser->parseToGrayscale($color);
|
||||
$index = sprintf('#%02x%02x%02x-%d', $color[0], $color[0], $color[0], $alpha);
|
||||
|
||||
if (false === array_key_exists($index, static::$colors)) {
|
||||
static::$colors[$index] = new GrayColor($this, $color, $alpha);
|
||||
}
|
||||
|
||||
return static::$colors[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::blend()
|
||||
*/
|
||||
public function blend(ColorInterface $color1, ColorInterface $color2, $amount)
|
||||
{
|
||||
if (!$color1 instanceof GrayColor || !$color2 instanceof GrayColor) {
|
||||
throw new RuntimeException('Grayscale palette can only blend Grayscale colors');
|
||||
}
|
||||
$max = $this->getChannelsMaxValue();
|
||||
|
||||
return $this->color(
|
||||
array(
|
||||
(int) min($max, min($color1->getGray(), $color2->getGray()) + round(abs($color2->getGray() - $color1->getGray()) * $amount)),
|
||||
),
|
||||
(int) min(100, min($color1->getAlpha(), $color2->getAlpha()) + round(abs($color2->getAlpha() - $color1->getAlpha()) * $amount))
|
||||
);
|
||||
}
|
||||
}
|
||||
112
vendor/imagine/imagine/src/Image/Palette/PaletteInterface.php
vendored
Normal file
112
vendor/imagine/imagine/src/Image/Palette/PaletteInterface.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette;
|
||||
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
|
||||
/**
|
||||
* Interface that any palette must implement.
|
||||
*/
|
||||
interface PaletteInterface
|
||||
{
|
||||
/**
|
||||
* Palette name: grayscale.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PALETTE_GRAYSCALE = 'gray';
|
||||
|
||||
/**
|
||||
* Palette name: RGB.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PALETTE_RGB = 'rgb';
|
||||
|
||||
/**
|
||||
* Palette name: CMYK.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PALETTE_CMYK = 'cmyk';
|
||||
|
||||
/**
|
||||
* Returns a color given some values.
|
||||
*
|
||||
* @param string|int[]|int $color A color
|
||||
* @param int|null $alpha Set alpha to null to disable it
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException In case you pass an alpha value to a Palette that does not support alpha
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function color($color, $alpha = null);
|
||||
|
||||
/**
|
||||
* Blend two colors given an amount.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color1
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color2
|
||||
* @param float $amount The amount of color2 in color1
|
||||
*
|
||||
* @return \Imagine\Image\Palette\Color\ColorInterface
|
||||
*/
|
||||
public function blend(ColorInterface $color1, ColorInterface $color2, $amount);
|
||||
|
||||
/**
|
||||
* Attachs an ICC profile to this Palette.
|
||||
*
|
||||
* (A default profile is provided by default)
|
||||
*
|
||||
* @param \Imagine\Image\ProfileInterface $profile
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function useProfile(ProfileInterface $profile);
|
||||
|
||||
/**
|
||||
* Returns the ICC profile attached to this Palette.
|
||||
*
|
||||
* @return \Imagine\Image\ProfileInterface
|
||||
*/
|
||||
public function profile();
|
||||
|
||||
/**
|
||||
* Returns the name of this Palette, one of PaletteInterface::PALETTE_ constants.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name();
|
||||
|
||||
/**
|
||||
* Returns an array containing ColorInterface::COLOR_* constants that
|
||||
* define the structure of colors for a pixel.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function pixelDefinition();
|
||||
|
||||
/**
|
||||
* Tells if alpha channel is supported in this palette.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsAlpha();
|
||||
|
||||
/**
|
||||
* Get the max value of palette components (255 for RGB and Grayscale, 100 for CMYK).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getChannelsMaxValue();
|
||||
}
|
||||
159
vendor/imagine/imagine/src/Image/Palette/RGB.php
vendored
Normal file
159
vendor/imagine/imagine/src/Image/Palette/RGB.php
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Palette;
|
||||
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\Profile;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
|
||||
/**
|
||||
* The RGB palette.
|
||||
*/
|
||||
class RGB implements PaletteInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\ColorParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\ProfileInterface|null
|
||||
*/
|
||||
private $profile;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\Color\RGB[]
|
||||
*/
|
||||
protected static $colors = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new ColorParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::name()
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return PaletteInterface::PALETTE_RGB;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::pixelDefinition()
|
||||
*/
|
||||
public function pixelDefinition()
|
||||
{
|
||||
return array(
|
||||
ColorInterface::COLOR_RED,
|
||||
ColorInterface::COLOR_GREEN,
|
||||
ColorInterface::COLOR_BLUE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::supportsAlpha()
|
||||
*/
|
||||
public function supportsAlpha()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::getChannelsMaxValue()
|
||||
*/
|
||||
public function getChannelsMaxValue()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::useProfile()
|
||||
*/
|
||||
public function useProfile(ProfileInterface $profile)
|
||||
{
|
||||
$this->profile = $profile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::profile()
|
||||
*/
|
||||
public function profile()
|
||||
{
|
||||
if (!$this->profile) {
|
||||
$this->profile = Profile::fromPath(__DIR__ . '/../../resources/color.org/sRGB_IEC61966-2-1_black_scaled.icc');
|
||||
}
|
||||
|
||||
return $this->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::color()
|
||||
*/
|
||||
public function color($color, $alpha = null)
|
||||
{
|
||||
if (null === $alpha) {
|
||||
$alpha = 100;
|
||||
}
|
||||
|
||||
$color = $this->parser->parseToRGB($color);
|
||||
$index = sprintf('#%02x%02x%02x-%d', $color[0], $color[1], $color[2], $alpha);
|
||||
|
||||
if (false === array_key_exists($index, static::$colors)) {
|
||||
static::$colors[$index] = new RGBColor($this, $color, $alpha);
|
||||
}
|
||||
|
||||
return static::$colors[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\Palette\PaletteInterface::blend()
|
||||
*/
|
||||
public function blend(ColorInterface $color1, ColorInterface $color2, $amount)
|
||||
{
|
||||
if (!$color1 instanceof RGBColor || !$color2 instanceof RGBColor) {
|
||||
throw new RuntimeException('RGB palette can only blend RGB colors');
|
||||
}
|
||||
$amount = (float) $amount;
|
||||
$amountComplement = 1 - $amount;
|
||||
$max = $this->getChannelsMaxValue();
|
||||
|
||||
return $this->color(
|
||||
array(
|
||||
min(max((int) round($color2->getRed() * $amount + $color1->getRed() * $amountComplement), 0), $max),
|
||||
min(max((int) round($color2->getGreen() * $amount + $color1->getGreen() * $amountComplement), 0), $max),
|
||||
min(max((int) round($color2->getBlue() * $amount + $color1->getBlue() * $amountComplement), 0), $max),
|
||||
),
|
||||
min(max((int) round($color2->getAlpha() * $amount + $color1->getAlpha() * $amountComplement), 0), 100)
|
||||
);
|
||||
}
|
||||
}
|
||||
98
vendor/imagine/imagine/src/Image/Point.php
vendored
Normal file
98
vendor/imagine/imagine/src/Image/Point.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The point class.
|
||||
*/
|
||||
final class Point implements PointInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $x;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* Constructs a point of coordinates.
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($x, $y)
|
||||
{
|
||||
if ($x < 0 || $y < 0) {
|
||||
throw new InvalidArgumentException(sprintf('A coordinate cannot be positioned outside of a bounding box (x: %s, y: %s given)', $x, $y));
|
||||
}
|
||||
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getX()
|
||||
*/
|
||||
public function getX()
|
||||
{
|
||||
return $this->x;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getY()
|
||||
*/
|
||||
public function getY()
|
||||
{
|
||||
return $this->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::in()
|
||||
*/
|
||||
public function in(BoxInterface $box)
|
||||
{
|
||||
return $this->x < $box->getWidth() && $this->y < $box->getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::move()
|
||||
*/
|
||||
public function move($amount)
|
||||
{
|
||||
return new self($this->x + $amount, $this->y + $amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%d, %d)', $this->x, $this->y);
|
||||
}
|
||||
}
|
||||
87
vendor/imagine/imagine/src/Image/Point/Center.php
vendored
Normal file
87
vendor/imagine/imagine/src/Image/Point/Center.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image\Point;
|
||||
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Point as OriginalPoint;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Center point of a box.
|
||||
*/
|
||||
final class Center implements PointInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Image\BoxInterface
|
||||
*/
|
||||
private $box;
|
||||
|
||||
/**
|
||||
* Constructs coordinate with size instance, it needs to be relative to.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $box
|
||||
*/
|
||||
public function __construct(BoxInterface $box)
|
||||
{
|
||||
$this->box = $box;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getX()
|
||||
*/
|
||||
public function getX()
|
||||
{
|
||||
return ceil($this->box->getWidth() / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getY()
|
||||
*/
|
||||
public function getY()
|
||||
{
|
||||
return ceil($this->box->getHeight() / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::in()
|
||||
*/
|
||||
public function in(BoxInterface $box)
|
||||
{
|
||||
return $this->getX() < $box->getWidth() && $this->getY() < $box->getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::move()
|
||||
*/
|
||||
public function move($amount)
|
||||
{
|
||||
return new OriginalPoint($this->getX() + $amount, $this->getY() + $amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%d, %d)', $this->getX(), $this->getY());
|
||||
}
|
||||
}
|
||||
57
vendor/imagine/imagine/src/Image/PointInterface.php
vendored
Normal file
57
vendor/imagine/imagine/src/Image/PointInterface.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
/**
|
||||
* The point interface.
|
||||
*/
|
||||
interface PointInterface
|
||||
{
|
||||
/**
|
||||
* Gets points x coordinate.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getX();
|
||||
|
||||
/**
|
||||
* Gets points y coordinate.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getY();
|
||||
|
||||
/**
|
||||
* Checks if current coordinate is inside a given box.
|
||||
*
|
||||
* @param \Imagine\Image\BoxInterface $box
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function in(BoxInterface $box);
|
||||
|
||||
/**
|
||||
* Returns another point, moved by a given amount from current coordinates.
|
||||
*
|
||||
* @param int $amount
|
||||
*
|
||||
* @return \Imagine\Image\PointInterface
|
||||
*/
|
||||
public function move($amount);
|
||||
|
||||
/**
|
||||
* Gets a string representation for the current point.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
92
vendor/imagine/imagine/src/Image/PointSigned.php
vendored
Normal file
92
vendor/imagine/imagine/src/Image/PointSigned.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
/**
|
||||
* A point class that allows negative values of coordinates.
|
||||
*/
|
||||
final class PointSigned implements PointInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $x;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* Constructs a point of coordinates.
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getX()
|
||||
*/
|
||||
public function getX()
|
||||
{
|
||||
return $this->x;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::getY()
|
||||
*/
|
||||
public function getY()
|
||||
{
|
||||
return $this->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::in()
|
||||
*/
|
||||
public function in(BoxInterface $box)
|
||||
{
|
||||
return 0 <= $this->x && $this->x < $box->getWidth() && 0 <= $this->y && $this->y < $box->getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::move()
|
||||
*/
|
||||
public function move($amount)
|
||||
{
|
||||
return new self($this->x + $amount, $this->y + $amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\PointInterface::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('(%d, %d)', $this->x, $this->y);
|
||||
}
|
||||
}
|
||||
78
vendor/imagine/imagine/src/Image/Profile.php
vendored
Normal file
78
vendor/imagine/imagine/src/Image/Profile.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The default implementation of ProfileInterface.
|
||||
*/
|
||||
class Profile implements ProfileInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $data
|
||||
*/
|
||||
public function __construct($name, $data)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ProfileInterface::name()
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ProfileInterface::data()
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a profile from a path to a file.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException In case the provided path is not valid
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function fromPath($path)
|
||||
{
|
||||
if (!file_exists($path) || !is_file($path) || !is_readable($path)) {
|
||||
throw new InvalidArgumentException(sprintf('Path %s is an invalid profile file or is not readable', $path));
|
||||
}
|
||||
|
||||
return new static(basename($path), file_get_contents($path));
|
||||
}
|
||||
}
|
||||
29
vendor/imagine/imagine/src/Image/ProfileInterface.php
vendored
Normal file
29
vendor/imagine/imagine/src/Image/ProfileInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Image;
|
||||
|
||||
interface ProfileInterface
|
||||
{
|
||||
/**
|
||||
* Returns the name of the profile.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name();
|
||||
|
||||
/**
|
||||
* Returns the profile data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function data();
|
||||
}
|
||||
474
vendor/imagine/imagine/src/Imagick/Drawer.php
vendored
Normal file
474
vendor/imagine/imagine/src/Imagick/Drawer.php
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Imagick;
|
||||
|
||||
use Imagine\Draw\DrawerInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Drawer implementation using the Imagick PHP extension.
|
||||
*/
|
||||
final class Drawer implements DrawerInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagick
|
||||
*/
|
||||
private $imagick;
|
||||
|
||||
/**
|
||||
* @param \Imagick $imagick
|
||||
*/
|
||||
public function __construct(\Imagick $imagick)
|
||||
{
|
||||
$this->imagick = $imagick;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::arc()
|
||||
*/
|
||||
public function arc(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
$x = $center->getX();
|
||||
$y = $center->getY();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$arc = new \ImagickDraw();
|
||||
|
||||
$arc->setStrokeColor($pixel);
|
||||
$arc->setStrokeWidth($thickness);
|
||||
$arc->setFillColor('transparent');
|
||||
$arc->arc($x - $width / 2, $y - $height / 2, $x + $width / 2, $y + $height / 2, $start, $end);
|
||||
|
||||
$this->imagick->drawImage($arc);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$arc->clear();
|
||||
$arc->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw arc operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::chord()
|
||||
*/
|
||||
public function chord(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$x = $center->getX();
|
||||
$y = $center->getY();
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$chord = new \ImagickDraw();
|
||||
|
||||
$chord->setStrokeColor($pixel);
|
||||
$chord->setStrokeWidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$chord->setFillColor($pixel);
|
||||
} else {
|
||||
$from = new Point(round($x + $width / 2 * cos(deg2rad($start))), round($y + $height / 2 * sin(deg2rad($start))));
|
||||
$to = new Point(round($x + $width / 2 * cos(deg2rad($end))), round($y + $height / 2 * sin(deg2rad($end))));
|
||||
$this->line($from, $to, $color, $thickness);
|
||||
$chord->setFillColor('transparent');
|
||||
}
|
||||
|
||||
$chord->arc(
|
||||
$x - $width / 2,
|
||||
$y - $height / 2,
|
||||
$x + $width / 2,
|
||||
$y + $height / 2,
|
||||
$start,
|
||||
$end
|
||||
);
|
||||
|
||||
$this->imagick->drawImage($chord);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$chord->clear();
|
||||
$chord->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw chord operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::circle()
|
||||
*/
|
||||
public function circle(PointInterface $center, $radius, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$diameter = $radius * 2;
|
||||
|
||||
return $this->ellipse($center, new Box($diameter, $diameter), $color, $fill, $thickness);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::ellipse()
|
||||
*/
|
||||
public function ellipse(PointInterface $center, BoxInterface $size, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$ellipse = new \ImagickDraw();
|
||||
|
||||
$ellipse->setStrokeColor($pixel);
|
||||
$ellipse->setStrokeWidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$ellipse->setFillColor($pixel);
|
||||
} else {
|
||||
$ellipse->setFillColor('transparent');
|
||||
}
|
||||
|
||||
$ellipse->ellipse(
|
||||
$center->getX(),
|
||||
$center->getY(),
|
||||
$width / 2,
|
||||
$height / 2,
|
||||
0, 360
|
||||
);
|
||||
|
||||
if (false === $this->imagick->drawImage($ellipse)) {
|
||||
throw new RuntimeException('Ellipse operation failed');
|
||||
}
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$ellipse->clear();
|
||||
$ellipse->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw ellipse operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::line()
|
||||
*/
|
||||
public function line(PointInterface $start, PointInterface $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0) {
|
||||
return $this;
|
||||
}
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$line = new \ImagickDraw();
|
||||
|
||||
$line->setStrokeColor($pixel);
|
||||
$line->setStrokeWidth($thickness);
|
||||
$line->setFillColor($pixel);
|
||||
$line->line(
|
||||
$start->getX(),
|
||||
$start->getY(),
|
||||
$end->getX(),
|
||||
$end->getY()
|
||||
);
|
||||
|
||||
$this->imagick->drawImage($line);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$line->clear();
|
||||
$line->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw line operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::pieSlice()
|
||||
*/
|
||||
public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$x1 = round($center->getX() + $width / 2 * cos(deg2rad($start)));
|
||||
$y1 = round($center->getY() + $height / 2 * sin(deg2rad($start)));
|
||||
$x2 = round($center->getX() + $width / 2 * cos(deg2rad($end)));
|
||||
$y2 = round($center->getY() + $height / 2 * sin(deg2rad($end)));
|
||||
|
||||
if ($fill) {
|
||||
$this->chord($center, $size, $start, $end, $color, true, $thickness);
|
||||
$this->polygon(
|
||||
array(
|
||||
$center,
|
||||
new Point($x1, $y1),
|
||||
new Point($x2, $y2),
|
||||
),
|
||||
$color,
|
||||
true,
|
||||
$thickness
|
||||
);
|
||||
} else {
|
||||
$this->arc($center, $size, $start, $end, $color, $thickness);
|
||||
$this->line($center, new Point($x1, $y1), $color, $thickness);
|
||||
$this->line($center, new Point($x2, $y2), $color, $thickness);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::dot()
|
||||
*/
|
||||
public function dot(PointInterface $position, ColorInterface $color)
|
||||
{
|
||||
$x = $position->getX();
|
||||
$y = $position->getY();
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$point = new \ImagickDraw();
|
||||
|
||||
$point->setFillColor($pixel);
|
||||
$point->point($x, $y);
|
||||
|
||||
$this->imagick->drawimage($point);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$point->clear();
|
||||
$point->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw point operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::rectangle()
|
||||
*/
|
||||
public function rectangle(PointInterface $leftTop, PointInterface $rightBottom, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$minX = min($leftTop->getX(), $rightBottom->getX());
|
||||
$maxX = max($leftTop->getX(), $rightBottom->getX());
|
||||
$minY = min($leftTop->getY(), $rightBottom->getY());
|
||||
$maxY = max($leftTop->getY(), $rightBottom->getY());
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$rectangle = new \ImagickDraw();
|
||||
$rectangle->setStrokeColor($pixel);
|
||||
$rectangle->setStrokeWidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$rectangle->setFillColor($pixel);
|
||||
} else {
|
||||
$rectangle->setFillColor('transparent');
|
||||
}
|
||||
|
||||
$rectangle->rectangle($minX, $minY, $maxX, $maxY);
|
||||
$this->imagick->drawImage($rectangle);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$rectangle->clear();
|
||||
$rectangle->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw rectangle operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::polygon()
|
||||
*/
|
||||
public function polygon(array $coordinates, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
if (count($coordinates) < 3) {
|
||||
throw new InvalidArgumentException(sprintf('Polygon must consist of at least 3 coordinates, %d given', count($coordinates)));
|
||||
}
|
||||
|
||||
$thickness = max(0, (int) round($thickness));
|
||||
if ($thickness === 0 && !$fill) {
|
||||
return $this;
|
||||
}
|
||||
$points = array_map(function (PointInterface $p) {
|
||||
return array('x' => $p->getX(), 'y' => $p->getY());
|
||||
}, $coordinates);
|
||||
|
||||
try {
|
||||
$pixel = $this->getColor($color);
|
||||
$polygon = new \ImagickDraw();
|
||||
|
||||
$polygon->setStrokeColor($pixel);
|
||||
$polygon->setStrokeWidth($thickness);
|
||||
|
||||
if ($fill) {
|
||||
$polygon->setFillColor($pixel);
|
||||
} else {
|
||||
$polygon->setFillColor('transparent');
|
||||
}
|
||||
|
||||
$polygon->polygon($points);
|
||||
$this->imagick->drawImage($polygon);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$polygon->clear();
|
||||
$polygon->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw polygon operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Draw\DrawerInterface::text()
|
||||
*/
|
||||
public function text($string, AbstractFont $font, PointInterface $position, $angle = 0, $width = null)
|
||||
{
|
||||
try {
|
||||
$pixel = $this->getColor($font->getColor());
|
||||
$text = new \ImagickDraw();
|
||||
|
||||
$text->setFont($font->getFile());
|
||||
/*
|
||||
* @see http://www.php.net/manual/en/imagick.queryfontmetrics.php#101027
|
||||
*
|
||||
* ensure font resolution is the same as GD's hard-coded 96
|
||||
*/
|
||||
if (version_compare(phpversion('imagick'), '3.0.2', '>=')) {
|
||||
$text->setResolution(96, 96);
|
||||
$text->setFontSize($font->getSize());
|
||||
} else {
|
||||
$text->setFontSize((int) ($font->getSize() * (96 / 72)));
|
||||
}
|
||||
$text->setFillColor($pixel);
|
||||
$text->setTextAntialias(true);
|
||||
|
||||
if ($width !== null) {
|
||||
$string = $font->wrapText($string, $width, $angle);
|
||||
}
|
||||
|
||||
$info = $this->imagick->queryFontMetrics($text, $string);
|
||||
$rad = deg2rad($angle);
|
||||
$cos = cos($rad);
|
||||
$sin = sin($rad);
|
||||
|
||||
// round(0 * $cos - 0 * $sin)
|
||||
$x1 = 0;
|
||||
$x2 = round($info['characterWidth'] * $cos - $info['characterHeight'] * $sin);
|
||||
// round(0 * $sin + 0 * $cos)
|
||||
$y1 = 0;
|
||||
$y2 = round($info['characterWidth'] * $sin + $info['characterHeight'] * $cos);
|
||||
|
||||
$xdiff = 0 - min($x1, $x2);
|
||||
$ydiff = 0 - min($y1, $y2);
|
||||
|
||||
$this->imagick->annotateImage(
|
||||
$text, $position->getX() + $x1 + $xdiff,
|
||||
$position->getY() + $y2 + $ydiff, $angle, $string
|
||||
);
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
$text->clear();
|
||||
$text->destroy();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Draw text operation failed', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets specifically formatted color string from ColorInterface instance.
|
||||
*
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getColor(ColorInterface $color)
|
||||
{
|
||||
$pixel = new \ImagickPixel((string) $color);
|
||||
$pixel->setColorValue(\Imagick::COLOR_ALPHA, $color->getAlpha() / 100);
|
||||
|
||||
return $pixel;
|
||||
}
|
||||
}
|
||||
189
vendor/imagine/imagine/src/Imagick/Effects.php
vendored
Normal file
189
vendor/imagine/imagine/src/Imagick/Effects.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Imagick;
|
||||
|
||||
use Imagine\Effects\EffectsInterface;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB;
|
||||
use Imagine\Utils\Matrix;
|
||||
|
||||
/**
|
||||
* Effects implementation using the Imagick PHP extension.
|
||||
*/
|
||||
class Effects implements EffectsInterface
|
||||
{
|
||||
/**
|
||||
* @var \Imagick
|
||||
*/
|
||||
private $imagick;
|
||||
|
||||
/**
|
||||
* Initialize the instance.
|
||||
*
|
||||
* @param \Imagick $imagick
|
||||
*/
|
||||
public function __construct(\Imagick $imagick)
|
||||
{
|
||||
$this->imagick = $imagick;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::gamma()
|
||||
*/
|
||||
public function gamma($correction)
|
||||
{
|
||||
try {
|
||||
$this->imagick->gammaImage($correction, \Imagick::CHANNEL_ALL);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to apply gamma correction to the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::negative()
|
||||
*/
|
||||
public function negative()
|
||||
{
|
||||
try {
|
||||
$this->imagick->negateImage(false, \Imagick::CHANNEL_ALL);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to negate the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::grayscale()
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
try {
|
||||
$this->imagick->setImageType(\Imagick::IMGTYPE_GRAYSCALE);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to grayscale the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::colorize()
|
||||
*/
|
||||
public function colorize(ColorInterface $color)
|
||||
{
|
||||
if (!$color instanceof RGB) {
|
||||
throw new NotSupportedException('Colorize with non-rgb color is not supported');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->imagick->colorizeImage((string) $color, new \ImagickPixel(sprintf('rgba(%d, %d, %d, 1)', $color->getRed(), $color->getGreen(), $color->getBlue())));
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to colorize the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::sharpen()
|
||||
*/
|
||||
public function sharpen()
|
||||
{
|
||||
try {
|
||||
$this->imagick->sharpenImage(2, 1);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to sharpen the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::blur()
|
||||
*/
|
||||
public function blur($sigma = 1)
|
||||
{
|
||||
try {
|
||||
$this->imagick->gaussianBlurImage(0, $sigma);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to blur the image', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::brightness()
|
||||
*/
|
||||
public function brightness($brightness)
|
||||
{
|
||||
$brightness = (int) round($brightness);
|
||||
if ($brightness < -100 || $brightness > 100) {
|
||||
throw new InvalidArgumentException(sprintf('The %1$s argument can range from %2$d to %3$d, but you specified %4$d.', '$brightness', -100, 100, $brightness));
|
||||
}
|
||||
try {
|
||||
if (method_exists($this->imagick, 'brightnesscontrastimage')) {
|
||||
// Available since Imagick 3.3.0
|
||||
$this->imagick->brightnesscontrastimage($brightness, 0);
|
||||
} else {
|
||||
// This *emulates* brightnesscontrastimage
|
||||
$sign = $brightness < 0 ? -1 : 1;
|
||||
$v = abs($brightness) / 100;
|
||||
$v = (1 / (sin(($v * .99999 * M_PI_2) + M_PI_2))) - 1;
|
||||
$this->imagick->modulateimage(100 + $sign * $v * 100, 100, 100);
|
||||
}
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to brightness the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Effects\EffectsInterface::convolve()
|
||||
*/
|
||||
public function convolve(Matrix $matrix)
|
||||
{
|
||||
if ($matrix->getWidth() !== 3 || $matrix->getHeight() !== 3) {
|
||||
throw new InvalidArgumentException(sprintf('A convolution matrix must be 3x3 (%dx%d provided).', $matrix->getWidth(), $matrix->getHeight()));
|
||||
}
|
||||
try {
|
||||
$this->imagick->convolveImage($matrix->getValueList());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to convolve the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
69
vendor/imagine/imagine/src/Imagick/Font.php
vendored
Normal file
69
vendor/imagine/imagine/src/Imagick/Font.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Imagick;
|
||||
|
||||
use Imagine\Image\AbstractFont;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
|
||||
/**
|
||||
* Font implementation using the Imagick PHP extension.
|
||||
*/
|
||||
final class Font extends AbstractFont
|
||||
{
|
||||
/**
|
||||
* @var \Imagick
|
||||
*/
|
||||
private $imagick;
|
||||
|
||||
/**
|
||||
* @param \Imagick $imagick
|
||||
* @param string $file
|
||||
* @param int $size
|
||||
* @param \Imagine\Image\Palette\Color\ColorInterface $color
|
||||
*/
|
||||
public function __construct(\Imagick $imagick, $file, $size, ColorInterface $color)
|
||||
{
|
||||
$this->imagick = $imagick;
|
||||
|
||||
parent::__construct($file, $size, $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\FontInterface::box()
|
||||
*/
|
||||
public function box($string, $angle = 0)
|
||||
{
|
||||
$text = new \ImagickDraw();
|
||||
|
||||
$text->setFont($this->file);
|
||||
|
||||
/*
|
||||
* @see http://www.php.net/manual/en/imagick.queryfontmetrics.php#101027
|
||||
*
|
||||
* ensure font resolution is the same as GD's hard-coded 96
|
||||
*/
|
||||
if (version_compare(phpversion('imagick'), '3.0.2', '>=')) {
|
||||
$text->setResolution(96, 96);
|
||||
$text->setFontSize($this->size);
|
||||
} else {
|
||||
$text->setFontSize((int) ($this->size * (96 / 72)));
|
||||
}
|
||||
|
||||
$info = $this->imagick->queryFontMetrics($text, $string);
|
||||
|
||||
$box = $this->getClassFactory()->createBox($info['textWidth'], $info['textHeight']);
|
||||
|
||||
return $box;
|
||||
}
|
||||
}
|
||||
1081
vendor/imagine/imagine/src/Imagick/Image.php
vendored
Normal file
1081
vendor/imagine/imagine/src/Imagick/Image.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
215
vendor/imagine/imagine/src/Imagick/Imagine.php
vendored
Normal file
215
vendor/imagine/imagine/src/Imagick/Imagine.php
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Imagick;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\File\LoaderInterface;
|
||||
use Imagine\Image\AbstractImagine;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\CMYK;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Grayscale;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Utils\ErrorHandling;
|
||||
|
||||
/**
|
||||
* Imagine implementation using the Imagick PHP extension.
|
||||
*/
|
||||
final class Imagine extends AbstractImagine
|
||||
{
|
||||
/**
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!class_exists('Imagick')) {
|
||||
throw new RuntimeException('Imagick not installed');
|
||||
}
|
||||
|
||||
$version = $this->getVersion(new \Imagick());
|
||||
|
||||
if (version_compare('6.2.9', $version) > 0) {
|
||||
throw new RuntimeException(sprintf('ImageMagick version 6.2.9 or higher is required, %s provided', $version));
|
||||
}
|
||||
if ($version === '7.0.7-32') { // https://github.com/avalanche123/Imagine/issues/689
|
||||
throw new RuntimeException(sprintf('ImageMagick version %s has known bugs that prevent it from working', $version));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::open()
|
||||
*/
|
||||
public function open($path)
|
||||
{
|
||||
$loader = $path instanceof LoaderInterface ? $path : $this->getClassFactory()->createFileLoader($path);
|
||||
$path = $loader->getPath();
|
||||
|
||||
try {
|
||||
if ($loader->isLocalFile()) {
|
||||
if (DIRECTORY_SEPARATOR === '\\' && PHP_INT_SIZE === 8 && PHP_VERSION_ID >= 70100 && PHP_VERSION_ID < 70200) {
|
||||
$imagick = new \Imagick();
|
||||
// PHP 7.1 64 bit on Windows: don't pass the file name to the constructor: it may break PHP - see https://github.com/mkoppanen/imagick/issues/252
|
||||
$imagick->readImageBlob($loader->getData(), $path);
|
||||
} else {
|
||||
$imagick = new \Imagick($loader->getPath());
|
||||
}
|
||||
} else {
|
||||
$imagick = new \Imagick();
|
||||
$imagick->readImageBlob($loader->getData());
|
||||
}
|
||||
$image = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $imagick, $this->createPalette($imagick), $this->getMetadataReader()->readFile($loader));
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException(sprintf('Unable to open image %s', $path), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::create()
|
||||
*/
|
||||
public function create(BoxInterface $size, ColorInterface $color = null)
|
||||
{
|
||||
$width = $size->getWidth();
|
||||
$height = $size->getHeight();
|
||||
|
||||
$palette = null !== $color ? $color->getPalette() : new RGB();
|
||||
$color = null !== $color ? $color : $palette->color('fff');
|
||||
|
||||
try {
|
||||
$pixel = new \ImagickPixel((string) $color);
|
||||
$pixel->setColorValue(\Imagick::COLOR_ALPHA, $color->getAlpha() / 100);
|
||||
|
||||
$imagick = new \Imagick();
|
||||
$imagick->newImage($width, $height, $pixel);
|
||||
$imagick->setImageMatte(true);
|
||||
$imagick->setImageBackgroundColor($pixel);
|
||||
|
||||
if (version_compare('6.3.1', $this->getVersion($imagick)) < 0) {
|
||||
// setImageOpacity was replaced with setImageAlpha in php-imagick v3.4.3
|
||||
if (method_exists($imagick, 'setImageAlpha')) {
|
||||
$imagick->setImageAlpha($pixel->getColorValue(\Imagick::COLOR_ALPHA));
|
||||
} else {
|
||||
ErrorHandling::ignoring(E_DEPRECATED, function () use ($imagick, $pixel) {
|
||||
$imagick->setImageOpacity($pixel->getColorValue(\Imagick::COLOR_ALPHA));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$pixel->clear();
|
||||
$pixel->destroy();
|
||||
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $imagick, $palette, new MetadataBag());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Could not create empty image', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::load()
|
||||
*/
|
||||
public function load($string)
|
||||
{
|
||||
try {
|
||||
$imagick = new \Imagick();
|
||||
|
||||
$imagick->readImageBlob($string);
|
||||
$imagick->setImageMatte(true);
|
||||
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $imagick, $this->createPalette($imagick), $this->getMetadataReader()->readData($string));
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Could not load image from string', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::read()
|
||||
*/
|
||||
public function read($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new InvalidArgumentException('Variable does not contain a stream resource');
|
||||
}
|
||||
|
||||
$content = stream_get_contents($resource);
|
||||
|
||||
try {
|
||||
$imagick = new \Imagick();
|
||||
$imagick->readImageBlob($content);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Could not read image from resource', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $imagick, $this->createPalette($imagick), $this->getMetadataReader()->readData($content, $resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\ImagineInterface::font()
|
||||
*/
|
||||
public function font($file, $size, ColorInterface $color)
|
||||
{
|
||||
return $this->getClassFactory()->createFont(ClassFactoryInterface::HANDLE_IMAGICK, $file, $size, $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the palette corresponding to an \Imagick resource colorspace.
|
||||
*
|
||||
* @param \Imagick $imagick
|
||||
*
|
||||
* @throws \Imagine\Exception\NotSupportedException
|
||||
*
|
||||
* @return \Imagine\Image\Palette\CMYK|\Imagine\Image\Palette\Grayscale|\Imagine\Image\Palette\RGB
|
||||
*/
|
||||
private function createPalette(\Imagick $imagick)
|
||||
{
|
||||
switch ($imagick->getImageColorspace()) {
|
||||
case \Imagick::COLORSPACE_RGB:
|
||||
case \Imagick::COLORSPACE_SRGB:
|
||||
return new RGB();
|
||||
case \Imagick::COLORSPACE_CMYK:
|
||||
return new CMYK();
|
||||
case \Imagick::COLORSPACE_GRAY:
|
||||
return new Grayscale();
|
||||
default:
|
||||
throw new NotSupportedException('Only RGB and CMYK colorspace are currently supported');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ImageMagick version.
|
||||
*
|
||||
* @param \Imagick $imagick
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getVersion(\Imagick $imagick)
|
||||
{
|
||||
$v = $imagick->getVersion();
|
||||
list($version) = sscanf($v['versionString'], 'ImageMagick %s %04d-%02d-%02d %s %s');
|
||||
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
308
vendor/imagine/imagine/src/Imagick/Layers.php
vendored
Normal file
308
vendor/imagine/imagine/src/Imagick/Layers.php
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Imagick;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Factory\ClassFactoryInterface;
|
||||
use Imagine\Image\AbstractLayers;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
|
||||
class Layers extends AbstractLayers
|
||||
{
|
||||
/**
|
||||
* @var \Imagine\Imagick\Image
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @var \Imagick
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* @var \Imagine\Imagick\Image[]
|
||||
*/
|
||||
private $layers = array();
|
||||
|
||||
/**
|
||||
* @var \Imagine\Image\Palette\PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
public function __construct(Image $image, PaletteInterface $palette, \Imagick $resource, $initialOffset = 0)
|
||||
{
|
||||
$this->image = $image;
|
||||
$this->resource = $resource;
|
||||
$this->palette = $palette;
|
||||
$this->offset = (int) $initialOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::merge()
|
||||
*/
|
||||
public function merge()
|
||||
{
|
||||
foreach ($this->layers as $offset => $image) {
|
||||
try {
|
||||
$this->resource->setIteratorIndex($offset);
|
||||
$this->resource->setImage($image->getImagick());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to substitute layer', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::animate()
|
||||
*/
|
||||
public function animate($format, $delay, $loops)
|
||||
{
|
||||
if ('gif' !== strtolower($format)) {
|
||||
throw new InvalidArgumentException('Animated picture is currently only supported on gif');
|
||||
}
|
||||
|
||||
if (!is_int($loops) || $loops < 0) {
|
||||
throw new InvalidArgumentException('Loops must be a positive integer.');
|
||||
}
|
||||
|
||||
if (null !== $delay && (!is_int($delay) || $delay < 0)) {
|
||||
throw new InvalidArgumentException('Delay must be either null or a positive integer.');
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($this as $offset => $layer) {
|
||||
$this->resource->setIteratorIndex($offset);
|
||||
$this->resource->setFormat($format);
|
||||
|
||||
if (null !== $delay) {
|
||||
$layer->getImagick()->setImageDelay($delay / 10);
|
||||
$layer->getImagick()->setImageTicksPerSecond(100);
|
||||
}
|
||||
$layer->getImagick()->setImageIterations($loops);
|
||||
|
||||
$this->resource->setImage($layer->getImagick());
|
||||
}
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to animate layers', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Imagine\Image\LayersInterface::coalesce()
|
||||
*/
|
||||
public function coalesce()
|
||||
{
|
||||
try {
|
||||
$coalescedResource = $this->resource->coalesceImages();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to coalesce layers', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$count = $coalescedResource->getNumberImages();
|
||||
for ($offset = 0; $offset < $count; $offset++) {
|
||||
try {
|
||||
$coalescedResource->setIteratorIndex($offset);
|
||||
$this->layers[$offset] = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $coalescedResource->getImage(), $this->palette, new MetadataBag());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to retrieve layer', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::current()
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->extractAt($this->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to extract layer at given offset.
|
||||
*
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
*
|
||||
* @return \Imagine\Imagick\Image
|
||||
*/
|
||||
private function extractAt($offset)
|
||||
{
|
||||
if (!isset($this->layers[$offset])) {
|
||||
try {
|
||||
$this->resource->setIteratorIndex($offset);
|
||||
$this->layers[$offset] = $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK, $this->resource->getImage(), $this->palette, new MetadataBag());
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException(sprintf('Failed to extract layer %d', $offset), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->layers[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::key()
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Iterator::valid()
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->offset < count($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
try {
|
||||
return $this->resource->getNumberImages();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Failed to count the number of layers', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetExists()
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return is_int($offset) && $offset >= 0 && $offset < count($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetGet()
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->extractAt($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetSet()
|
||||
*/
|
||||
public function offsetSet($offset, $image)
|
||||
{
|
||||
if (!$image instanceof Image) {
|
||||
throw new InvalidArgumentException('Only an Imagick Image can be used as layer');
|
||||
}
|
||||
|
||||
if (null === $offset) {
|
||||
$offset = count($this) - 1;
|
||||
} else {
|
||||
if (!is_int($offset)) {
|
||||
throw new InvalidArgumentException('Invalid offset for layer, it must be an integer');
|
||||
}
|
||||
|
||||
if (count($this) < $offset || 0 > $offset) {
|
||||
throw new OutOfBoundsException(sprintf('Invalid offset for layer, it must be a value between 0 and %d, %d given', count($this), $offset));
|
||||
}
|
||||
|
||||
if (isset($this[$offset])) {
|
||||
unset($this[$offset]);
|
||||
$offset = $offset - 1;
|
||||
}
|
||||
}
|
||||
|
||||
$frame = $image->getImagick();
|
||||
|
||||
try {
|
||||
if (count($this) > 0) {
|
||||
$this->resource->setIteratorIndex($offset);
|
||||
}
|
||||
$this->resource->addImage($frame);
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Unable to set the layer', $e->getCode(), $e);
|
||||
}
|
||||
|
||||
$this->layers = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \ArrayAccess::offsetUnset()
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
try {
|
||||
$this->extractAt($offset);
|
||||
} catch (RuntimeException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->resource->setIteratorIndex($offset);
|
||||
$this->resource->removeImage();
|
||||
} catch (\ImagickException $e) {
|
||||
throw new RuntimeException('Unable to remove layer', $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
93
vendor/imagine/imagine/src/Utils/ErrorHandling.php
vendored
Normal file
93
vendor/imagine/imagine/src/Utils/ErrorHandling.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Utils;
|
||||
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class ErrorHandling
|
||||
{
|
||||
/**
|
||||
* Call a callback ignoring $flags warnings.
|
||||
*
|
||||
* @param int $flags The flags to be ignored (eg E_WARNING | E_NOTICE)
|
||||
* @param callable $callback The callable to be called
|
||||
*
|
||||
* @throws \Exception Throws an Exception if $callback throws an Exception
|
||||
* @throws \Throwable Throws an Throwable if $callback throws an Throwable
|
||||
*
|
||||
* @return mixed Returns the result of $callback
|
||||
*/
|
||||
public static function ignoring($flags, $callback)
|
||||
{
|
||||
set_error_handler(
|
||||
function () {
|
||||
},
|
||||
$flags
|
||||
);
|
||||
try {
|
||||
$result = $callback();
|
||||
$exception = null;
|
||||
} catch (Exception $x) {
|
||||
$exception = $x;
|
||||
} catch (Throwable $x) {
|
||||
$exception = $x;
|
||||
}
|
||||
restore_error_handler();
|
||||
if ($exception !== null) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a callback and throws a RuntimeException if a $flags warning is thrown.
|
||||
*
|
||||
* @param int $flags The flags to be intercepted (eg E_WARNING | E_NOTICE)
|
||||
* @param callable $callback The callable to be called
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws \Imagine\Exception\RuntimeException
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*
|
||||
* @return mixed Returns the result of $callback
|
||||
*/
|
||||
public static function throwingRuntimeException($flags, $callback)
|
||||
{
|
||||
set_error_handler(
|
||||
function ($errno, $errstr, $errfile, $errline) {
|
||||
if (error_reporting() !== 0) {
|
||||
throw new RuntimeException($errstr, $errno, new ErrorException($errstr, 0, $errno, $errfile, $errline));
|
||||
}
|
||||
},
|
||||
$flags
|
||||
);
|
||||
try {
|
||||
$result = $callback();
|
||||
$exception = null;
|
||||
} catch (Exception $x) {
|
||||
$exception = $x;
|
||||
} catch (Throwable $x) {
|
||||
$exception = $x;
|
||||
}
|
||||
restore_error_handler();
|
||||
if ($exception !== null) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
177
vendor/imagine/imagine/src/Utils/Matrix.php
vendored
Normal file
177
vendor/imagine/imagine/src/Utils/Matrix.php
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Imagine package.
|
||||
*
|
||||
* (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Imagine\Utils;
|
||||
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
|
||||
class Matrix
|
||||
{
|
||||
/**
|
||||
* The array of elements.
|
||||
*
|
||||
* @var int[]|float[]
|
||||
*/
|
||||
protected $elements = array();
|
||||
|
||||
/**
|
||||
* The matrix width.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $width;
|
||||
|
||||
/**
|
||||
* The matrix height.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $height;
|
||||
|
||||
/**
|
||||
* The given $elements get arranged as follows: The elements will be set from left to right in a row until the
|
||||
* row is full. Then, the next line begins alike and so on.
|
||||
*
|
||||
* @param int $width the matrix width
|
||||
* @param int $height he matrix height
|
||||
* @param int[]|float[] $elements the matrix elements
|
||||
*
|
||||
* @throws \Imagine\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($width, $height, $elements = array())
|
||||
{
|
||||
$this->width = (int) round($width);
|
||||
if ($this->width < 1) {
|
||||
throw new InvalidArgumentException('width has to be > 0');
|
||||
}
|
||||
$this->height = (int) round($height);
|
||||
if ($this->height < 1) {
|
||||
throw new InvalidArgumentException('height has to be > 0');
|
||||
}
|
||||
$expectedElements = $width * $height;
|
||||
$providedElements = count($elements);
|
||||
if ($providedElements > $expectedElements) {
|
||||
throw new InvalidArgumentException('there are more provided elements than space in the matrix');
|
||||
}
|
||||
$this->elements = array_values($elements);
|
||||
if ($providedElements < $expectedElements) {
|
||||
$this->elements = array_merge(
|
||||
$this->elements,
|
||||
array_fill($providedElements, $expectedElements - $providedElements, 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matrix width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matrix height.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a cell.
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param int|float $value
|
||||
*/
|
||||
public function setElementAt($x, $y, $value)
|
||||
{
|
||||
$this->elements[$this->calculatePosition($x, $y)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a cell.
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
public function getElementAt($x, $y)
|
||||
{
|
||||
return $this->elements[$this->calculatePosition($x, $y)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the matrix values, as a monodimensional array.
|
||||
*
|
||||
* @return int[]|float[]
|
||||
*/
|
||||
public function getValueList()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the matrix values, as a bidimensional array (every array item contains the values of a row).
|
||||
*
|
||||
* @return int[]|float[]
|
||||
*/
|
||||
public function getMatrix()
|
||||
{
|
||||
return array_chunk($this->elements, $this->getWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Matrix instance, representing the normalized value of this matrix.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function normalize()
|
||||
{
|
||||
$values = $this->getValueList();
|
||||
$divisor = array_sum($values);
|
||||
if ($divisor == 0 || $divisor == 1) {
|
||||
return clone $this;
|
||||
}
|
||||
$normalizedElements = array();
|
||||
foreach ($values as $value) {
|
||||
$normalizedElements[] = $value / $divisor;
|
||||
}
|
||||
|
||||
return new static($this->getWidth(), $this->getHeight(), $normalizedElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the offset position of a cell.
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*
|
||||
* @throws \Imagine\Exception\OutOfBoundsException
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function calculatePosition($x, $y)
|
||||
{
|
||||
if (0 > $x || 0 > $y || $this->width <= $x || $this->height <= $y) {
|
||||
throw new OutOfBoundsException(sprintf('There is no position (%s, %s) in this matrix', $x, $y));
|
||||
}
|
||||
|
||||
return $y * $this->height + $x;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user