1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
<?php
/**
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author James Heinrich <info@silisoftware.com>
* @author Michael J. Rubinsky <mrubinsk@horde.org>
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
* @package Image
*/
/**
* Image effect for adding a drop shadow.
*
* This algorithm is from the phpThumb project available at
* http://phpthumb.sourceforge.net and all credit for this script should go to
* James Heinrich <info@silisoftware.com>. Modifications made to the code to
* fit it within the Horde framework and to adjust for our coding standards.
*
* @author James Heinrich <info@silisoftware.com>
* @author Michael J. Rubinsky <mrubinsk@horde.org>
* @category Horde
* @copyright 2007-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
* @package Image
*/
class Horde_Image_Effect_Gd_DropShadow extends Horde_Image_Effect
{
/**
* Valid parameters:
*
* @TODO
*
* @var array
*/
protected $_params = array(
'distance' => 5,
'width' => 2,
'hexcolor' => '000000',
'angle' => 215,
'fade' => 10
);
/**
* Applies the effect.
*/
public function apply()
{
$distance = $this->_params['distance'];
$width = $this->_params['width'];
$hexcolor = $this->_params['hexcolor'];
$angle = $this->_params['angle'];
$fade = $this->_params['fade'];
$width_shadow = cos(deg2rad($angle)) * ($distance + $width);
$height_shadow = sin(deg2rad($angle)) * ($distance + $width);
$gdimg = $this->_image->_im;
$imgX = $this->_image->call('imageSX', array($gdimg));
$imgY = $this->_image->call('imageSY', array($gdimg));
$offset['x'] = cos(deg2rad($angle)) * ($distance + $width - 1);
$offset['y'] = sin(deg2rad($angle)) * ($distance + $width - 1);
$tempImageWidth = $imgX + abs($offset['x']);
$tempImageHeight = $imgY + abs($offset['y']);
$temp = $this->_image->create($tempImageWidth, $tempImageHeight);
$this->_image->call('imageAlphaBlending', array($temp, false));
$this->_image->call('imageSaveAlpha', array($temp, true));
$transparent1 = $this->_image->call(
'imageColorAllocateAlpha',
array($temp, 0, 0, 0, 127)
);
$this->_image->call('imageFill', array($temp, 0, 0, $transparent1));
for ($x = 0; $x < $imgX; $x++) {
for ($y = 0; $y < $imgY; $y++) {
$colorat = $this->_image->call(
'imageColorAt',
array($gdimg, $x, $y)
);
$PixelMap[$x][$y] = $this->_image->call(
'imageColorsForIndex',
array($gdimg, $colorat)
);
}
}
/* Creates the shadow */
$r = hexdec(substr($hexcolor, 0, 2));
$g = hexdec(substr($hexcolor, 2, 2));
$b = hexdec(substr($hexcolor, 4, 2));
/* Essentially masks the original image and creates the shadow */
for ($x = 0; $x < $tempImageWidth; $x++) {
for ($y = 0; $y < $tempImageHeight; $y++) {
if ((!isset($PixelMap[$x][$y]['alpha']) ||
$PixelMap[$x][$y]['alpha'] > 0) &&
isset($PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha']) &&
$PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha'] < 127) {
$thisColor = $this->_image->call(
'imageColorAllocateAlpha',
array(
$temp,
$r, $g, $b,
$PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha']
)
);
$this->_image->call(
'imageSetPixel',
array($temp, $x, $y, $thisColor)
);
}
}
}
/* Overlays the original image */
$this->_image->call('imageAlphaBlending', array($temp, true));
for ($x = 0; $x < $imgX; $x++) {
for ($y = 0; $y < $imgY; $y++) {
if ($PixelMap[$x][$y]['alpha'] < 127) {
$thisColor = $this->_image->call(
'imageColorAllocateAlpha',
array(
$temp,
$PixelMap[$x][$y]['red'],
$PixelMap[$x][$y]['green'],
$PixelMap[$x][$y]['blue'],
$PixelMap[$x][$y]['alpha']
)
);
$this->_image->call(
'imageSetPixel',
array($temp, $x, $y, $thisColor)
);
}
}
}
$this->_image->call('imageSaveAlpha', array($gdimg, true));
$this->_image->call('imageAlphaBlending', array($gdimg, false));
// Merge the shadow and the original into the original.
$this->_image->call(
'imageCopyResampled',
array(
$gdimg, $temp,
0, 0, 0, 0,
$imgX, $imgY,
$this->_image->call('imageSX', array($temp)),
$this->_image->call('imageSY', array($temp))
)
);
$this->_image->call('imageDestroy', array($temp));
}
}
|