/framework/Image/lib/Horde/Image/Effect/Gd/DropShadow.php

https://github.com/ewandor/horde · PHP · 110 lines · 71 code · 12 blank · 27 comment · 10 complexity · 1a1b3995f0364dd2252d768a20510e57 MD5 · raw file

  1. <?php
  2. /**
  3. * Image effect for adding a drop shadow.
  4. *
  5. * This algorithm is from the phpThumb project available at
  6. * http://phpthumb.sourceforge.net and all credit for this script should go to
  7. * James Heinrich <info@silisoftware.com>. Modifications made to the code
  8. * to fit it within the Horde framework and to adjust for our coding standards.
  9. *
  10. * @author Michael J. Rubinsky <mrubinsk@horde.org>
  11. * @package Image
  12. */
  13. class Horde_Image_Effect_Gd_DropShadow extends Horde_Image_Effect
  14. {
  15. /**
  16. * Valid parameters:
  17. *
  18. * @TODO
  19. *
  20. * @var array
  21. */
  22. protected $_params = array('distance' => 5,
  23. 'width' => 2,
  24. 'hexcolor' => '000000',
  25. 'angle' => 215,
  26. 'fade' => 10);
  27. /**
  28. * Apply the drop_shadow effect.
  29. *
  30. * @return boolean
  31. */
  32. public function apply()
  33. {
  34. $distance = $this->_params['distance'];
  35. $width = $this->_params['width'];
  36. $hexcolor = $this->_params['hexcolor'];
  37. $angle = $this->_params['angle'];
  38. $fade = $this->_params['fade'];
  39. $width_shadow = cos(deg2rad($angle)) * ($distance + $width);
  40. $height_shadow = sin(deg2rad($angle)) * ($distance + $width);
  41. $gdimg = $this->_image->_im;
  42. $imgX = $this->_image->call('imageSX', array($gdimg));
  43. $imgY = $this->_image->call('imageSY', array($gdimg));
  44. $offset['x'] = cos(deg2rad($angle)) * ($distance + $width - 1);
  45. $offset['y'] = sin(deg2rad($angle)) * ($distance + $width - 1);
  46. $tempImageWidth = $imgX + abs($offset['x']);
  47. $tempImageHeight = $imgY + abs($offset['y']);
  48. $gdimg_dropshadow_temp = $this->_image->create($tempImageWidth, $tempImageHeight);
  49. $this->_image->call('imageAlphaBlending', array($gdimg_dropshadow_temp, false));
  50. $this->_image->call('imageSaveAlpha', array($gdimg_dropshadow_temp, true));
  51. $transparent1 = $this->_image->call('imageColorAllocateAlpha', array($gdimg_dropshadow_temp, 0, 0, 0, 127));
  52. $this->_image->call('imageFill', array($gdimg_dropshadow_temp, 0, 0, $transparent1));
  53. for ($x = 0; $x < $imgX; $x++) {
  54. for ($y = 0; $y < $imgY; $y++) {
  55. $colorat = $this->_image->call('imageColorAt', array($gdimg, $x, $y));
  56. $PixelMap[$x][$y] = $this->_image->call('imageColorsForIndex', array($gdimg, $colorat));
  57. }
  58. }
  59. /* Creates the shadow */
  60. $r = hexdec(substr($hexcolor, 0, 2));
  61. $g = hexdec(substr($hexcolor, 2, 2));
  62. $b = hexdec(substr($hexcolor, 4, 2));
  63. /* Essentially masks the original image and creates the shadow */
  64. for ($x = 0; $x < $tempImageWidth; $x++) {
  65. for ($y = 0; $y < $tempImageHeight; $y++) {
  66. if (!isset($PixelMap[$x][$y]['alpha']) ||
  67. ($PixelMap[$x][$y]['alpha'] > 0)) {
  68. if (isset($PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha']) && ($PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha'] < 127)) {
  69. $thisColor = $this->_image->call('imageColorAllocateAlpha', array($gdimg_dropshadow_temp, $r, $g, $b, $PixelMap[$x + $offset['x']][$y + $offset['y']]['alpha']));
  70. $this->_image->call('imageSetPixel',
  71. array($gdimg_dropshadow_temp, $x, $y, $thisColor));
  72. }
  73. }
  74. }
  75. }
  76. /* Overlays the original image */
  77. $this->_image->call('imageAlphaBlending',
  78. array($gdimg_dropshadow_temp, true));
  79. for ($x = 0; $x < $imgX; $x++) {
  80. for ($y = 0; $y < $imgY; $y++) {
  81. if ($PixelMap[$x][$y]['alpha'] < 127) {
  82. $thisColor = $this->_image->call('imageColorAllocateAlpha', array($gdimg_dropshadow_temp, $PixelMap[$x][$y]['red'], $PixelMap[$x][$y]['green'], $PixelMap[$x][$y]['blue'], $PixelMap[$x][$y]['alpha']));
  83. $this->_image->call('imageSetPixel',
  84. array($gdimg_dropshadow_temp, $x, $y, $thisColor));
  85. }
  86. }
  87. }
  88. $this->_image->call('imageSaveAlpha',
  89. array($gdimg, true));
  90. $this->_image->call('imageAlphaBlending',
  91. array($gdimg, false));
  92. // Merge the shadow and the original into the original.
  93. $this->_image->call('imageCopyResampled',
  94. array($gdimg, $gdimg_dropshadow_temp, 0, 0, 0, 0, $imgX, $imgY, $this->_image->call('imageSX', array($gdimg_dropshadow_temp)), $this->_image->call('imageSY', array($gdimg_dropshadow_temp))));
  95. $this->_image->call('imageDestroy', array($gdimg_dropshadow_temp));
  96. return true;
  97. }
  98. }