mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 00:47:04 +03:00
Added: Incorrect image orientation
This commit is contained in:
parent
217207883f
commit
e3b62d24d8
87 changed files with 10461 additions and 21 deletions
333
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Drawer.php
Normal file
333
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Drawer.php
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
<?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\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\PointInterface;
|
||||
|
||||
/**
|
||||
* Drawer implementation using the GD library
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function arc(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $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}
|
||||
*/
|
||||
public function chord(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $thickness));
|
||||
|
||||
if ($fill) {
|
||||
$style = IMG_ARC_CHORD;
|
||||
} else {
|
||||
$style = IMG_ARC_CHORD | 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}
|
||||
*/
|
||||
public function ellipse(PointInterface $center, BoxInterface $size, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $thickness));
|
||||
|
||||
if ($fill) {
|
||||
$callback = 'imagefilledellipse';
|
||||
} else {
|
||||
$callback = 'imageellipse';
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Draw ellipse operation failed');
|
||||
}
|
||||
|
||||
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}
|
||||
*/
|
||||
public function line(PointInterface $start, PointInterface $end, ColorInterface $color, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $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}
|
||||
*/
|
||||
public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function polygon(array $coordinates, ColorInterface $color, $fill = false, $thickness = 1)
|
||||
{
|
||||
imagesetthickness($this->resource, max(1, (int) $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}
|
||||
*/
|
||||
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 = $this->wrapText($string, $font, $angle, $width);
|
||||
}
|
||||
|
||||
if (false === imagealphablending($this->resource, true)) {
|
||||
throw new RuntimeException('Font mask operation failed');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Generates a GD color from Color instance
|
||||
*
|
||||
* @param ColorInterface $color
|
||||
*
|
||||
* @return resource
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Fits a string into box with given width
|
||||
*/
|
||||
private function wrapText($string, AbstractFont $font, $angle, $width)
|
||||
{
|
||||
$result = '';
|
||||
$words = explode(' ', $string);
|
||||
foreach ($words as $word) {
|
||||
$teststring = $result . ' ' . $word;
|
||||
$testbox = imagettfbbox($font->getSize(), $angle, $font->getFile(), $teststring);
|
||||
if ($testbox[2] > $width) {
|
||||
$result .= ($result == '' ? '' : "\n") . $word;
|
||||
} else {
|
||||
$result .= ($result == '' ? '' : ' ') . $word;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
109
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Effects.php
Normal file
109
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Effects.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?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\RuntimeException;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
|
||||
/**
|
||||
* Effects implementation using the GD library
|
||||
*/
|
||||
class Effects implements EffectsInterface
|
||||
{
|
||||
private $resource;
|
||||
|
||||
public function __construct($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function negative()
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_NEGATE)) {
|
||||
throw new RuntimeException('Failed to negate the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_GRAYSCALE)) {
|
||||
throw new RuntimeException('Failed to grayscale the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function blur($sigma = 1)
|
||||
{
|
||||
if (false === imagefilter($this->resource, IMG_FILTER_GAUSSIAN_BLUR)) {
|
||||
throw new RuntimeException('Failed to blur the image');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
41
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Font.php
Normal file
41
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Font.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?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;
|
||||
use Imagine\Image\Box;
|
||||
|
||||
/**
|
||||
* Font implementation using the GD library
|
||||
*/
|
||||
final class Font extends AbstractFont
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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.');
|
||||
}
|
||||
|
||||
$angle = -1 * $angle;
|
||||
$info = imageftbbox($this->size, $angle, $this->file, $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 new Box($width, $height);
|
||||
}
|
||||
}
|
||||
735
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Image.php
Normal file
735
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Image.php
Normal file
|
|
@ -0,0 +1,735 @@
|
|||
<?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\Image\AbstractImage;
|
||||
use Imagine\Image\ImageInterface;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Fill\FillInterface;
|
||||
use Imagine\Image\Point;
|
||||
use Imagine\Image\PointInterface;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Image\ProfileInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\OutOfBoundsException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Image implementation using the GD library
|
||||
*/
|
||||
final class Image extends AbstractImage
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* @var Layers|null
|
||||
*/
|
||||
private $layers;
|
||||
|
||||
/**
|
||||
* @var PaletteInterface
|
||||
*/
|
||||
private $palette;
|
||||
|
||||
/**
|
||||
* Constructs a new Image instance
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param PaletteInterface $palette
|
||||
* @param 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Gd resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getGdResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function copy()
|
||||
{
|
||||
$size = $this->getSize();
|
||||
$copy = $this->createImage($size, 'copy');
|
||||
|
||||
if (false === imagecopy($copy, $this->resource, 0, 0, 0, 0, $size->getWidth(), $size->getHeight())) {
|
||||
throw new RuntimeException('Image copy operation failed');
|
||||
}
|
||||
|
||||
return new Image($copy, $this->palette, $this->metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
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)) {
|
||||
throw new RuntimeException('Image crop operation failed');
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function paste(ImageInterface $image, PointInterface $start)
|
||||
{
|
||||
if (!$image instanceof self) {
|
||||
throw new InvalidArgumentException(sprintf('Gd\Image can only paste() Gd\Image instances, %s given', get_class($image)));
|
||||
}
|
||||
|
||||
$size = $image->getSize();
|
||||
if (!$this->getSize()->contains($size, $start)) {
|
||||
throw new OutOfBoundsException('Cannot paste image of the given size at the specified position, as it moves outside of the current image\'s box');
|
||||
}
|
||||
|
||||
imagealphablending($this->resource, true);
|
||||
imagealphablending($image->resource, true);
|
||||
|
||||
if (false === imagecopy($this->resource, $image->resource, $start->getX(), $start->getY(), 0, 0, $size->getWidth(), $size->getHeight())) {
|
||||
throw new RuntimeException('Image paste operation failed');
|
||||
}
|
||||
|
||||
imagealphablending($this->resource, false);
|
||||
imagealphablending($image->resource, false);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
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);
|
||||
|
||||
if (false === imagecopyresampled($dest, $this->resource, 0, 0, 0, 0, $width, $height, imagesx($this->resource), imagesy($this->resource))) {
|
||||
throw new RuntimeException('Image resize operation failed');
|
||||
}
|
||||
|
||||
imagealphablending($this->resource, false);
|
||||
imagealphablending($dest, false);
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function rotate($angle, ColorInterface $background = null)
|
||||
{
|
||||
$color = $background ? $background : $this->palette->color('fff');
|
||||
$resource = imagerotate($this->resource, -1 * $angle, $this->getColor($color));
|
||||
|
||||
if (false === $resource) {
|
||||
throw new RuntimeException('Image rotate operation failed');
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
$this->resource = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
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}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
public function show($format, array $options = array())
|
||||
{
|
||||
header('Content-type: '.$this->getMimeType($format));
|
||||
|
||||
$this->saveOrOutput($format, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($format, array $options = array())
|
||||
{
|
||||
ob_start();
|
||||
$this->saveOrOutput($format, $options);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->get('png');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function flipHorizontally()
|
||||
{
|
||||
$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)) {
|
||||
throw new RuntimeException('Horizontal flip operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function flipVertically()
|
||||
{
|
||||
$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)) {
|
||||
throw new RuntimeException('Vertical flip operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
imagedestroy($this->resource);
|
||||
|
||||
$this->resource = $dest;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
final public function strip()
|
||||
{
|
||||
// GD strips profiles and comment, so there's nothing to do here
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
return new Drawer($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function effects()
|
||||
{
|
||||
return new Effects($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return new Box(imagesx($this->resource), imagesy($this->resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
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}
|
||||
*
|
||||
* @return ImageInterface
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function mask()
|
||||
{
|
||||
$mask = $this->copy();
|
||||
|
||||
if (false === imagefilter($mask->resource, IMG_FILTER_GRAYSCALE)) {
|
||||
throw new RuntimeException('Mask operation failed');
|
||||
}
|
||||
|
||||
return $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
public function layers()
|
||||
{
|
||||
if (null === $this->layers) {
|
||||
$this->layers = new Layers($this, $this->palette, $this->resource);
|
||||
}
|
||||
|
||||
return $this->layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
**/
|
||||
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}
|
||||
*/
|
||||
public function palette()
|
||||
{
|
||||
return $this->palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function profile(ProfileInterface $profile)
|
||||
{
|
||||
throw new RuntimeException('GD driver does not support color profiles');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function usePalette(PaletteInterface $palette)
|
||||
{
|
||||
if (!$palette instanceof RGB) {
|
||||
throw new RuntimeException('GD driver only supports RGB palette');
|
||||
}
|
||||
|
||||
$this->palette = $palette;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Performs save or show operation using one of GD's image... functions
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $options
|
||||
* @param string $filename
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws 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);
|
||||
|
||||
// Preserve BC until version 1.0
|
||||
if (isset($options['quality']) && !isset($options['png_compression_level'])) {
|
||||
$options['png_compression_level'] = round((100 - $options['quality']) * 9 / 100);
|
||||
}
|
||||
if (isset($options['filters']) && !isset($options['png_compression_filter'])) {
|
||||
$options['png_compression_filter'] = $options['filters'];
|
||||
}
|
||||
|
||||
$options = $this->updateSaveOptions($options);
|
||||
|
||||
if ($format === 'jpeg' && isset($options['jpeg_quality'])) {
|
||||
$args[] = $options['jpeg_quality'];
|
||||
}
|
||||
|
||||
if ($format === 'png') {
|
||||
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 (~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'];
|
||||
}
|
||||
}
|
||||
|
||||
if (($format === 'wbmp' || $format === 'xbm') && isset($options['foreground'])) {
|
||||
$args[] = $options['foreground'];
|
||||
}
|
||||
|
||||
$this->setExceptionHandler();
|
||||
|
||||
if (false === call_user_func_array($save, $args)) {
|
||||
throw new RuntimeException('Save operation failed');
|
||||
}
|
||||
|
||||
$this->resetExceptionHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Generates a GD image
|
||||
*
|
||||
* @param BoxInterface $size
|
||||
* @param string the operation initiating the creation
|
||||
*
|
||||
* @return resource
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Generates a GD color from Color instance
|
||||
*
|
||||
* @param ColorInterface $color
|
||||
*
|
||||
* @return integer A color identifier
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Normalizes a given format name
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function normalizeFormat($format)
|
||||
{
|
||||
$format = strtolower($format);
|
||||
|
||||
if ('jpg' === $format || 'pjpeg' === $format) {
|
||||
$format = 'jpeg';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Checks whether a given format is supported by GD library
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
private function supported($format = null)
|
||||
{
|
||||
$formats = array('gif', 'jpeg', 'png', 'wbmp', 'xbm');
|
||||
|
||||
if (null === $format) {
|
||||
return $formats;
|
||||
}
|
||||
|
||||
return in_array($format, $formats);
|
||||
}
|
||||
|
||||
private function setExceptionHandler()
|
||||
{
|
||||
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
|
||||
if (0 === error_reporting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new RuntimeException($errstr, $errno, new \ErrorException($errstr, 0, $errno, $errfile, $errline));
|
||||
}, E_WARNING | E_NOTICE);
|
||||
}
|
||||
|
||||
private function resetExceptionHandler()
|
||||
{
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal
|
||||
*
|
||||
* Get the mime type based on format.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return string mime-type
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function getMimeType($format)
|
||||
{
|
||||
$format = $this->normalizeFormat($format);
|
||||
|
||||
if (!$this->supported($format)) {
|
||||
throw new RuntimeException('Invalid format');
|
||||
}
|
||||
|
||||
static $mimeTypes = array(
|
||||
'jpeg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'xbm' => 'image/xbm',
|
||||
);
|
||||
|
||||
return $mimeTypes[$format];
|
||||
}
|
||||
}
|
||||
195
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Imagine.php
Normal file
195
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Imagine.php
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\Image\AbstractImagine;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\Color\ColorInterface;
|
||||
use Imagine\Image\Palette\RGB;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Image\BoxInterface;
|
||||
use Imagine\Image\Palette\Color\RGB as RGBColor;
|
||||
use Imagine\Exception\InvalidArgumentException;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Imagine implementation using the GD library
|
||||
*/
|
||||
final class Imagine extends AbstractImagine
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $info;
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->loadGdInfo();
|
||||
$this->requireGdVersion('2.0.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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() >= 95) {
|
||||
imagecolortransparent($resource, $index);
|
||||
}
|
||||
|
||||
return $this->wrap($resource, $palette, new MetadataBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function open($path)
|
||||
{
|
||||
$path = $this->checkPath($path);
|
||||
$data = @file_get_contents($path);
|
||||
|
||||
if (false === $data) {
|
||||
throw new RuntimeException(sprintf('Failed to open file %s', $path));
|
||||
}
|
||||
|
||||
$resource = @imagecreatefromstring($data);
|
||||
|
||||
if (!is_resource($resource)) {
|
||||
throw new RuntimeException(sprintf('Unable to open image %s', $path));
|
||||
}
|
||||
|
||||
return $this->wrap($resource, new RGB(), $this->getMetadataReader()->readFile($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($string)
|
||||
{
|
||||
return $this->doLoad($string, $this->getMetadataReader()->readData($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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()->readStream($resource));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function font($file, $size, ColorInterface $color)
|
||||
{
|
||||
if (!$this->info['FreeType Support']) {
|
||||
throw new RuntimeException('GD is not compiled with FreeType support');
|
||||
}
|
||||
|
||||
return new Font($file, $size, $color);
|
||||
}
|
||||
|
||||
private function wrap($resource, PaletteInterface $palette, MetadataBag $metadata)
|
||||
{
|
||||
if (!imageistruecolor($resource)) {
|
||||
list($width, $height) = array(imagesx($resource), imagesy($resource));
|
||||
|
||||
// create transparent truecolor canvas
|
||||
$truecolor = imagecreatetruecolor($width, $height);
|
||||
$transparent = imagecolorallocatealpha($truecolor, 255, 255, 255, 127);
|
||||
|
||||
imagefill($truecolor, 0, 0, $transparent);
|
||||
imagecolortransparent($truecolor, $transparent);
|
||||
|
||||
imagecopymerge($truecolor, $resource, 0, 0, 0, 0, $width, $height, 100);
|
||||
|
||||
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 new Image($resource, $palette, $metadata);
|
||||
}
|
||||
|
||||
private function loadGdInfo()
|
||||
{
|
||||
if (!function_exists('gd_info')) {
|
||||
throw new RuntimeException('Gd not installed');
|
||||
}
|
||||
|
||||
$this->info = gd_info();
|
||||
}
|
||||
|
||||
private function requireGdVersion($version)
|
||||
{
|
||||
if (version_compare(GD_VERSION, $version, '<')) {
|
||||
throw new RuntimeException(sprintf('GD2 version %s or higher is required', $version));
|
||||
}
|
||||
}
|
||||
|
||||
private function doLoad($string, MetadataBag $metadata)
|
||||
{
|
||||
$resource = @imagecreatefromstring($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);
|
||||
}
|
||||
}
|
||||
144
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Layers.php
Normal file
144
rainloop/v/0.0.0/app/libraries/Imagine/Gd/Layers.php
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<?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\Image\AbstractLayers;
|
||||
use Imagine\Exception\RuntimeException;
|
||||
use Imagine\Image\Metadata\MetadataBag;
|
||||
use Imagine\Image\Palette\PaletteInterface;
|
||||
use Imagine\Exception\NotSupportedException;
|
||||
|
||||
class Layers extends AbstractLayers
|
||||
{
|
||||
private $image;
|
||||
private $offset;
|
||||
private $resource;
|
||||
private $palette;
|
||||
|
||||
public function __construct(Image $image, PaletteInterface $palette, $resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new RuntimeException('Invalid Gd resource provided');
|
||||
}
|
||||
|
||||
$this->image = $image;
|
||||
$this->resource = $resource;
|
||||
$this->offset = 0;
|
||||
$this->palette = $palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function merge()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function coalesce()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function animate($format, $delay, $loops)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return new Image($this->resource, $this->palette, new MetadataBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
++$this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->offset < 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return 0 === $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (0 === $offset) {
|
||||
return new Image($this->resource, $this->palette, new MetadataBag());
|
||||
}
|
||||
|
||||
throw new RuntimeException('GD only supports one layer at offset 0');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new NotSupportedException('GD does not support layer set');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new NotSupportedException('GD does not support layer unset');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue