/** * Draw a line around an image * * Draw a line around an image. If $offset is 0, the line is just around the image. * If $offset is positive, the line is outside the image, and the gad is filled with background color. * If $offset is -width / 2, the line is centered on the border of the image. * If $offset is -$width, the line in just inside the image. * If $offset is negative, the line is inside the image. * * @param int $width Line width * @param mixed $color Line color * @param int $offset Distance between line and image. * * @return bool|PEAR_Error TRUE on success or PEAR_Error on failure. * @access private * @author Charles Brunet <*****@*****.**> */ function _line($width = 2, $color = '000000', $offset = 0, $background = 'FFFFFF') { // Agrandir l'image si nécessaire $mag = $width + $offset; if ($mag > 0) { $w = $this->_iWidth + 2 * $mag; $h = $this->_iHeight + 2 * $mag; // Create the target image if (function_exists('imagecreatetruecolor')) { $target = imagecreatetruecolor($w, $h); } else { $target = imagecreate($w, $h); } if (!Image_Tools::isGDImageResource($target)) { return PEAR::raiseError('Cannot initialize new GD image stream'); } $background = Image_Tools_Utils::colorToRGBA($background); $background = imagecolorallocate($target, $background['r'], $background['g'], $background['b']); imagefilledrectangle($target, 0, 0, $w - 1, $h - 1, $background); imagecopy($target, $this->resultImage, $mag, $mag, 0, 0, $this->_iWidth, $this->_iHeight); $this->_iWidth = $w; $this->_iHeight = $h; imagedestroy($this->resultImage); $this->resultImage = $target; } if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_resultImage'); } $color = Image_Tools_Utils::colorToRGBA($color); $color = imagecolorallocate($this->resultImage, $color['r'], $color['g'], $color['b']); $a = $mag < 0 ? 0 - $mag : 0; for ($i = $a; $i < $a + $width; ++$i) { imagerectangle($this->resultImage, $i, $i, $this->_iWidth - $i - 1, $this->_iHeight - $i - 1, $color); } return true; }
/** * Save rendered image to a file. * * @param string $path Path to destination filename. * @param int $type optional Type of image format (use defined image type * constants), default is IMAGETYPE_PNG. * @param boolean $force Force render or not, whether the image should be * re-render or leave the one if its already rendered * * @return bool|PEAR_Error TRUE on success, PEAR_Error on failure. * @access public * @see IMAGE_TOOLS_BASE_ERR_HEADERSEND_FAILED, IMAGE_TOOLS_BASE_ERR_IMAGETYPE_UNSUPPORTED */ function save($path, $type = IMAGETYPE_PNG, $force = false) { $res = $this->getResultImage($force); if (PEAR::isError($res)) { return $res; } if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Image_Tools::$resultImage is not an image resource'); } switch ($type) { case IMAGETYPE_GIF: case 'gif': $res = imagegif($this->resultImage, $path); break; case IMAGETYPE_PNG: case 'png': $res = imagepng($this->resultImage, $path); break; case IMAGETYPE_JPEG: case 'jpeg': case 'jpg': $res = imagejpeg($this->resultImage, $path); break; case IMAGETYPE_WBMP: case 'wbmp': $res = imagewbmp($this->resultImage, $path); break; default: return PEAR::raiseError('Image type ' . $type . ' not supported by PHP', IMAGE_TOOLS_BASE_ERR_IMAGETYPE_UNSUPPORTED); break; } if (!$res) { PEAR::raiseError('Saving image ' . $path . ' failed', IMAGE_TOOLS_BASE_ERR_SAVEIMAGE_FAILED); } return true; }
/** * Draw thumbnail result to resource. * * @return bool|PEAR_Error TRUE on success or PEAR_Error on failure. * @access public */ function render() { if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Invalid image resource'); } // Estimate a rectangular portion of the source image and a size of the target image if ($this->options['method'] == IMAGE_TOOLS_THUMBNAIL_METHOD_CROP) { if ($this->options['percent']) { $W = floor($this->options['percent'] / 100 * $this->imageInfo['width']); $H = floor($this->options['percent'] / 100 * $this->imageInfo['height']); } else { $W = $this->options['width']; $H = $this->options['height']; } $width = $W; $height = $H; $Y = $this->_coord('valign', 'height', $H); $X = $this->_coord('halign', 'width', $W); } else { $W = $this->imageInfo['width']; $H = $this->imageInfo['height']; $X = 0; $Y = 0; if ($this->options['percent']) { $width = floor($this->options['percent'] / 100 * $W); $height = floor($this->options['percent'] / 100 * $H); } else { $width = $this->options['width']; $height = $this->options['height']; if ($this->options['method'] == IMAGE_TOOLS_THUMBNAIL_METHOD_SCALE_MIN) { $Ww = $W / $width; $Hh = $H / $height; if ($Ww > $Hh) { $W = floor($width * $Hh); $X = $this->_coord('halign', 'width', $W); } else { $H = floor($height * $Ww); $Y = $this->_coord('valign', 'height', $H); } } else { if ($H > $W) { $width = floor($height / $H * $W); } else { $height = floor($width / $W * $H); } } } } // Create the target image if (function_exists('imagecreatetruecolor')) { $target = imagecreatetruecolor($width, $height); } else { $target = imagecreate($width, $height); } if (!Image_Tools::isGDImageResource($target)) { return PEAR::raiseError('Cannot initialize new GD image stream'); } // enable transparency if supported if (Image_Tools_Utils::compareGDVersion('2.0.28', '>=')) { // imagealphablending() and imagesavealpha() requires GD 2.0.38 imagealphablending($target, false); imagesavealpha($target, true); } // Copy the source image to the target image if ($this->options['method'] == IMAGE_TOOLS_THUMBNAIL_METHOD_CROP) { $result = imagecopy($target, $this->resultImage, 0, 0, $X, $Y, $W, $H); } elseif (function_exists('imagecopyresampled')) { $result = imagecopyresampled($target, $this->resultImage, 0, 0, $X, $Y, $width, $height, $W, $H); } else { $result = imagecopyresized($target, $this->resultImage, 0, 0, $X, $Y, $width, $height, $W, $H); } if (!$result) { return PEAR::raiseError('Cannot resize image'); } // Free a memory from the source image and save the resulting thumbnail imagedestroy($this->resultImage); $this->resultImage = $target; return true; }
/** * Apply tools to image. * * This function scan for mask color and closes colors position, grab color * at found the position on sample image, then set the pixel color at the same * position on destination image. * * @return bool|PEAR_Error TRUE on success or PEAR_Error on failure. * @access private * @see Image_Tools_Mask::_getNearestColors() */ function render() { if (!Image_Tools::isGDImageResource($this->_maskImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_maskImage'); } if (!Image_Tools::isGDImageResource($this->_sampleImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_sampleImage'); } if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_resultImage'); } $maskWidth = imagesx($this->_maskImage); $maskHeight = imagesy($this->_maskImage); $sampleWidth = imagesx($this->_sampleImage); $sampleHeight = imagesy($this->_sampleImage); if ($this->options['antialias']) { $closesColors = $this->_getNearestColors(); } else { $closesColors = array($this->options['maskColor']); } imagealphablending($this->resultImage, true); // scan for mask color or closes colors position for ($x = 0; $x < $maskWidth; $x++) { for ($y = 0; $y < $maskHeight; $y++) { if ($x >= $sampleWidth || $y >= $sampleHeight) { continue; } // grab color at x, y and convert to hex color format $index = imagecolorat($this->_maskImage, $x, $y); $maskRGBA = imagecolorsforindex($this->_maskImage, $index); $maskColor = Image_Color::rgb2hex(array_values($maskRGBA)); // check color in closes colors collection if (in_array($maskColor, $closesColors)) { // grab color at x, y from sample image $index = imagecolorat($this->_sampleImage, $x, $y); $sampleRGBA = imagecolorsforindex($this->_sampleImage, $index); // allocate color on destination image $color = imagecolorresolvealpha($this->resultImage, $sampleRGBA['red'], $sampleRGBA['green'], $sampleRGBA['blue'], $sampleRGBA['alpha']); // set a pixel color at destination image imagesetpixel($this->resultImage, $x, $y, $color); } } } return true; }
/** * Apply swap color to image and output result. * * This function swap channel color 'R', 'G', 'B' to set format. * * @return bool|PEAR_Error TRUE on success or PEAR_Error on failure. * @access protected */ function render() { if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_resultImage'); } if (!preg_match('@RBG|BGR|BRG|GRB|GBR$@i', $this->options['format'])) { return PEAR::raiseError('Invalid swap format'); } $width = imagesx($this->resultImage); $height = imagesy($this->resultImage); $destImg = imagecreatetruecolor($width, $height); for ($x = 0; $x < $width; $x++) { for ($y = 0; $y < $height; $y++) { $index = imagecolorat($this->resultImage, $x, $y); $rgb = imagecolorsforindex($this->resultImage, $index); $rgb = Image_Tools_Swap::swapColor($this->options['format'], $rgb); $color = imagecolorallocate($destImg, $rgb['r'], $rgb['g'], $rgb['b']); imagesetpixel($destImg, $x, $y, $color); } } $this->resultImage = $destImg; return true; }
/** * Draw extraction result to resource. * * @return bool|PEAR_Error TRUE on success or PEAR_Error on failure. * @access public * @see Image_Tools_Marquee::_extractRectangle(), * Image_Tools_Marquee::_extractSingleCol(), * Image_Tools_Marquee::_extractSingleRow() */ function render() { if (!Image_Tools::isGDImageResource($this->resultImage)) { return PEAR::raiseError('Invalid image resource Image_Tools_Mask::$_resultImage'); } $x = $this->options['x']; $y = $this->options['y']; switch ($this->_marquee['type']) { case IMAGE_TOOLS_MARQUEE_TYPE_RECTANGLE: $this->_extractRectangle($this->resultImage, $x, $y); break; case IMAGE_TOOLS_MARQUEE_TYPE_SINGLECOL: $this->_extractSingleColumn($this->resultImage, $x, $y); break; case IMAGE_TOOLS_MARQUEE_TYPE_SINGLEROW: $this->_extractSingleRow($this->resultImage, $x, $y); break; } return true; }