⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.78
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Image
/
Edit File: Imagick.php
<?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 Michael J. Rubinsky <mrubinsk@horde.org> * @category Horde * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 * @package Image */ /** * Imagick driver for the Horde_Image API. * * @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 * * @property-read Imagick $imagick The underlaying Imagick object. */ class Horde_Image_Imagick extends Horde_Image_Base { /** * The underlaying Imagick object. * * @var Imagick */ protected $_imagick; /** * Flag for iterator, since calling nextImage on Imagick would result in a * fatal error if there are no more images. * * @var boolean */ private $_noMoreImages = false; /** * Capabilites of this driver. * * @var string[] */ protected $_capabilities = array( 'canvas', 'circle', 'crop', 'dashedLine', 'flip', 'grayscale', 'line', 'mirror', 'multipage', 'pdf', 'polygon', 'polyline', 'rectangle', 'resize', 'rotate', 'roundedRectangle', 'sepia', 'text', ); /** * Constructor. * * @see Horde_Image_Base::_construct */ public function __construct($params, $context = array()) { if (!Horde_Util::loadExtension('imagick')) { throw new Horde_Image_Exception( 'Required PECL Imagick extension not found.' ); } parent::__construct($params, $context); ini_set('imagick.locale_fix', 1); $this->_imagick = new Imagick(); if (!empty($params['filename'])) { $this->loadFile($params['filename']); } elseif(!empty($params['data'])) { $this->loadString($params['data']); } else { $this->_width = max(array($this->_width, 1)); $this->_height = max(array($this->_height, 1)); try { $color = new ImagickPixel($this->_background); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->newImage( $this->_width, $this->_height, $color ); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } try { $this->_imagick->setImageFormat($this->_type); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } /** * Loads the image data from a string. * * @param string $image_data The data to use for the image. * * @throws Horde_Image_Exception */ public function loadString($image_data) { parent::loadString($image_data); $this->_imagick->clear(); try { $this->_data->rewind(); $this->_imagick->readImageFile($this->_data->stream); $this->_imagick->setImageFormat($this->_type); $this->_imagick->setIteratorIndex(0); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $this->_data->close(); unset($this->_data); } /** * Loads the image data from a file. * * @param string $filename The full path and filename to the file to load * the image data from. * * @throws Horde_Image_Exception */ public function loadFile($filename) { $this->reset(); try { $this->_imagick->readImage($filename); $this->_imagick->setImageFormat($this->_type); $this->_imagick->setIteratorIndex(0); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } // // Parent function loads image data into $this->_data // parent::loadFile($filename); // $this->loadString($this->_data); } /** * Sets the output image type. * * @param string $type An image type (png, jpg, etc.) * * @return string The previous image type. */ public function setType($type) { $old = parent::setType($type); try { $this->_imagick->setImageFormat($this->_type); } catch (ImagickException $e) { // Don't care about an empty wand here. } return $old; } /** * Returns the raw data for this image. * * @param boolean $convert Ignored for Imagick driver. * @param array $options Array of options: * - stream: If true, return as a stream resource. * DEFAULT: false. * * @return mixed The raw image data as a string or stream resource. */ public function raw($convert = false, $options = array()) { try { $this->_imagick->stripImage(); if (empty($options['stream'])) { return $this->_imagick->getImageBlob(); } $s = new Horde_Stream_Temp(); $s->add($this->_imagick->getImageBlob(), true); return $s->stream; } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } /** * Resets the image data to defaults. */ public function reset() { parent::reset(); $this->_imagick->clear(); $this->_noMoreImages = false; } /** * Returns the height and width of the current image data. * * @return array An hash with 'width' containing the width, * 'height' containing the height of the image. */ public function getDimensions() { if ($this->_height == 0 && $this->_width == 0) { try { $size = $this->_imagick->getImageGeometry(); } catch (ImagickException $e) { return array('width' => 0, 'height' => 0); } $this->_height = $size['height']; $this->_width = $size['width']; } return array('width' => $this->_width, 'height' => $this->_height); } /** * Resizes the current image. * * @param integer $width The new width. * @param integer $height The new height. * @param boolean $ratio Maintain original aspect ratio. * @param boolean $keepProfile Keep the image meta data. */ public function resize($width, $height, $ratio = true, $keepProfile = false) { try { if ($keepProfile) { $this->_imagick->resizeImage($width, $height, $ratio); } else { $this->_imagick->thumbnailImage($width, $height, $ratio); } } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $this->clearGeometry(); } /** * Crops the current image. * * @param integer $x1 x for the top left corner. * @param integer $y1 y for the top left corner. * @param integer $x2 x for the bottom right corner. * @param integer $y2 y for the bottom right corner. */ public function crop($x1, $y1, $x2, $y2) { try { $result = $this->_imagick->cropImage($x2 - $x1, $y2 - $y1, $x1, $y1); $this->_imagick->setImagePage(0, 0, 0, 0); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $this->clearGeometry(); } /** * Rotates the current image. * * @param integer $angle The angle to rotate the image by, in the * clockwise direction. * @param string $background The background color to fill any triangles. */ public function rotate($angle, $background = 'white') { try { $this->_imagick->rotateImage($background, $angle); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $this->clearGeometry(); } /** * Flips the current image. */ public function flip() { try { $this->_imagick->flipImage(); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } /** * Mirrors the current image. */ public function mirror() { try { $this->_imagick->flopImage(); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } /** * Converts the current image to grayscale. */ public function grayscale() { try { $this->_imagick->setImageType(Imagick::IMGTYPE_GRAYSCALE); } catch (ImageException $e) { throw new Horde_Image_Exception($e); } } /** * Applies a sepia filter. * * @param integer $threshold Extent of sepia effect. */ public function sepia($threshold = 85) { try { $this->_imagick->sepiaToneImage($threshold); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } } /** * Draws a text string on the image in a specified location, with the * specified style information. * * @TODO: Need to differentiate between the stroke (border) and the fill * color, but this is a BC break, since we were just not providing a * border. * * @param string $text The text to draw. * @param integer $x The left x coordinate of the start of the * text string. * @param integer $y The top y coordinate of the start of the text * string. * @param string $font The font identifier you want to use for the * text. * @param string $color The color that you want the text displayed in. * @param integer $direction An integer that specifies the orientation of * the text. * @param string $fontsize Size of the font (small, medium, large, giant) */ public function text( $string, $x, $y, $font = '', $color = 'black', $direction = 0, $fontsize = 'small' ) { $fontsize = Horde_Image::getFontSize($fontsize); try { $pixel = new ImagickPixel($color); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $draw = new ImagickDraw(); $draw->setFillColor($pixel); if (!empty($font)) { $draw->setFont($font); } $draw->setFontSize($fontsize); $draw->setGravity(Imagick::GRAVITY_NORTHWEST); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->annotateImage($draw, $x, $y, $direction, $string); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a circle. * * @param integer $x The x coordinate of the centre. * @param integer $y The y coordinate of the centre. * @param integer $r The radius of the circle. * @param string $color The line color of the circle. * @param string $fill The color to fill the circle. */ public function circle($x, $y, $r, $color, $fill = 'none') { try { $draw = new ImagickDraw(); $draw->setFillColor(new ImagickPixel($fill)); $draw->setStrokeColor(new ImagickPixel($color)); $draw->circle($x, $y, $r + $x, $y); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a polygon based on a set of vertices. * * @param array $vertices An array of x and y labeled arrays * (eg. $vertices[0]['x'], $vertices[0]['y'], ...). * @param string $color The color you want to draw the polygon with. * @param string $fill The color to fill the polygon. */ public function polygon($verts, $color, $fill = 'none') { try { $draw = new ImagickDraw(); $draw->setFillColor(new ImagickPixel($fill)); $draw->setStrokeColor(new ImagickPixel($color)); $draw->polygon($verts); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a rectangle. * * @param integer $x The left x-coordinate of the rectangle. * @param integer $y The top y-coordinate of the rectangle. * @param integer $width The width of the rectangle. * @param integer $height The height of the rectangle. * @param string $color The line color of the rectangle. * @param string $fill The color to fill the rectangle. */ public function rectangle($x, $y, $width, $height, $color, $fill = 'none') { try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setFillColor(new ImagickPixel($fill)); $draw->rectangle($x, $y, $x + $width, $y + $height); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a rounded rectangle. * * @param integer $x The left x-coordinate of the rectangle. * @param integer $y The top y-coordinate of the rectangle. * @param integer $width The width of the rectangle. * @param integer $height The height of the rectangle. * @param integer $round The width of the corner rounding. * @param string $color The line color of the rectangle. * @param string $fill The color to fill the rounded rectangle with. */ public function roundedRectangle( $x, $y, $width, $height, $round, $color, $fill ) { try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setFillColor(new ImagickPixel($fill)); $draw->roundRectangle($x, $y, $x + $width, $y + $height, $round, $round); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a line. * * @param integer $x0 The x coordinate of the start. * @param integer $y0 The y coordinate of the start. * @param integer $x1 The x coordinate of the end. * @param integer $y1 The y coordinate of the end. * @param string $color The line color. * @param string $width The width of the line. */ public function line($x0, $y0, $x1, $y1, $color = 'black', $width = 1) { try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setStrokeWidth($width); $draw->line($x0, $y0, $x1, $y1); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a dashed line. * * @param integer $x0 The x co-ordinate of the start. * @param integer $y0 The y co-ordinate of the start. * @param integer $x1 The x co-ordinate of the end. * @param integer $y1 The y co-ordinate of the end. * @param string $color The line color. * @param string $width The width of the line. * @param integer $dash_length The length of a dash on the dashed line. * @param integer $dash_space The length of a space in the dashed line. */ public function dashedLine( $x0, $y0, $x1, $y1, $color = 'black', $width = 1, $dash_length = 2, $dash_space = 2 ) { try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setStrokeWidth($width); $draw->setStrokeDashArray(array($dash_length, $dash_space)); $draw->line($x0, $y0, $x1, $y1); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImageException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws a polyline (a non-closed, non-filled polygon) based on a set of * vertices. * * @param array $vertices An array of x and y labeled arrays * (eg. $vertices[0]['x'], $vertices[0]['y'], ...). * @param string $color The color you want to draw the line with. * @param string $width The width of the line. */ public function polyline($verts, $color, $width = 1) { try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setStrokeWidth($width); $draw->setFillColor(new ImagickPixel('none')); $draw->polyline($verts); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Draws an arc. * * @param integer $x The x coordinate of the centre. * @param integer $y The y coordinate of the centre. * @param integer $r The radius of the arc. * @param integer $start The start angle of the arc. * @param integer $end The end angle of the arc. * @param string $color The line color of the arc. * @param string $fill The fill color of the arc (defaults to none). */ public function arc( $x, $y, $r, $start, $end, $color = 'black', $fill = 'none' ) { $points = Horde_Image::arcPoints($r, $start, $end); $points['x1'] += $x; $points['x2'] += $x; $points['x3'] += $x; $points['y1'] += $y; $points['y2'] += $y; $points['y3'] += $y; try { $draw = new ImagickDraw(); $draw->setStrokeColor(new ImagickPixel($color)); $draw->setFillColor(new ImagickPixel($fill)); $draw->arc($x - $r, $y - $r, $x + $r, $y + $r, $start, $end); } catch (ImagickDrawException $e) { throw new Horde_Image_Exception($e); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } // If filled, draw the outline. if (!empty($fill)) { $mid = round(($start + $end) / 2); list($x1, $y1) = Horde_Image::circlePoint($start, $r * 2); list($x2, $y2) = Horde_Image::circlePoint($mid, $r * 2); list($x3, $y3) = Horde_Image::circlePoint($end, $r * 2); $verts = array( array('x' => $x + round($x3), 'y' => $y + round($y3)), array('x' => $x, 'y' => $y), array('x' => $x + round($x1), 'y' => $y + round($y1)) ); if ($mid > 90) { $verts1 = array( array('x' => $x + round($x2), 'y' => $y + round($y2)), array('x' => $x, 'y' => $y), array('x' => $x + round($x1), 'y' => $y + round($y1)) ); $verts2 = array( array('x' => $x + round($x3), 'y' => $y + round($y3)), array('x' => $x, 'y' => $y), array('x' => $x + round($x2), 'y' => $y + round($y2)) ); $this->polygon($verts1, $fill, $fill); $this->polygon($verts2, $fill, $fill); } else { $this->polygon($verts, $fill, $fill); } $this->polyline($verts, $color); } try { $this->_imagick->drawImage($draw); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $draw->destroy(); } /** * Applies any effects in the effect queue. */ public function applyEffects() { // noop for this driver. } /** */ public function __get($property) { switch ($property) { case 'imagick': return $this->_imagick; } } /** * Utility function to wrap Imagick::borderImage. * * Use when you don't want to replace all pixels in the clipping area with * the border color i.e. you want to "frame" the existing image. Preserves * transparency etc. * * @param Imagick &$image The Imagick object to border. * @param string $color The border color. * @param integer $width The image width including the border. * @param integer $height The image height including the border. * * @todo Make non-static for H6. */ public static function frameImage(&$image, $color, $width, $height) { // Need to jump through these hoops in order to preserve any // transparency. try { // @todo Use clone or $this->_cloneImagickObject(). $border = $image->clone(); $border->borderImage(new ImagickPixel($color), $width, $height); $border->compositeImage($image, Imagick::COMPOSITE_COPY, $width, $height); $image->clear(); $image->addImage($border); } catch (ImagickPixelException $e) { throw new Horde_Image_Exception($e); } catch (ImagickException $e) { throw new Horde_Image_Exception($e); } $border->destroy(); } /** * Resets the Imagick iterator to the first image in the set. */ public function rewind() { $this->_logDebug('Horde_Image_Imagick#rewind'); $this->_imagick->setFirstIterator(); $this->_noMoreImages = false; } /** * Returns the current image from the internal iterator. * * @return Horde_Image_Imagick */ public function current() { $this->_logDebug('Horde_Image_Imagick#current'); $params = array('data' => $this->raw(false, array('stream' => true))); $image = new Horde_Image_Imagick($params, $this->_context); return $image; } /** * Returns the index of the internal iterator. * * @return integer */ public function key() { $this->_logDebug('Horde_Image_Imagick#key: ' . $this->_imagick->getIteratorIndex()); return $this->_imagick->getIteratorIndex(); } /** * Advances the iterator. * * @return Horde_Image_Imagick */ public function next() { if ($this->_imagick->hasNextImage()) { $this->_imagick->nextImage(); return $this->current(); } else { $this->_noMoreImages = true; return false; } } /** * Deterimines if the current iterator item is valid. * * @return boolean */ public function valid() { $this->_logDebug('Horde_Image_Imagick#valid:' . print_r(!$this->_noMoreImages, true)); return !$this->_noMoreImages; } /** * Returns a specific image from the pages of images. * * @param integer $index The index to return. * @param boolean $flatten If true, flatten the returned image using * $bgColor as the background color. Useful * for PDF files to remove transparency before * rendering. * @param string $bgColor The background color to use when flattening the * image. * * @return Horde_Image_Imagick The requested image */ public function getImageAtIndex($index, $flatten = false, $bgColor = 'white') { if ($index > 0 && $index >= $this->getImagePageCount()) { throw new Horde_Image_Exception('Image index out of bounds.'); } $currentIndex = $this->_imagick->getIteratorIndex(); $this->_imagick->setIteratorIndex($index); $image = $this->current(); $this->_imagick->setIteratorIndex($currentIndex); if ($flatten) { $image->flattenImage($bgColor); } return $image; } /** * Flatten the provided image and remove transparency. * * @param string $bgColor The background color to use. */ public function flattenImage($bgColor = 'white') { $this->imagick->setImageBackgroundColor($bgColor); if (defined('imagick::ALPHACHANNEL_REMOVE')) { $this->imagick->setImageAlphaChannel(imagick::ALPHACHANNEL_REMOVE); } $this->loadString( $this->imagick->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN)->getImageBlob() ); } /** * Returns the number of image pages available in the image object. * * @return integer The number of images. */ public function getImagePageCount() { $pages = $this->_imagick->getNumberImages(); $this->_logDebug('Horde_Image_Imagick#getImagePageCount: ' . $pages); return $pages; } /** * Wrapper around cloning the imagick resource object. * * @param Imagick $imagick A imagick resource object to clone. If empty * will clone the imagick object associated with * this Horde_Imagice_Imagick object. * * @todo Remove in H6 when we can increase version dependency of Imagick. * * @return Imagick * @since 2.4.0 */ public function cloneImagickObject($imagick = null) { if (version_compare(phpversion('imagick'), '3.1.0') >= 0) { return empty($imagick) ? clone $this->_imagick : clone $imagick; } return empty($imagick) ? $this->_imagick->clone() : $imagick->clone(); } }
Simpan