Example #1
0
 public function create(BoxInterface $size, ColorInterface $color = null)
 {
     $width = $size->getWidth();
     $height = $size->getHeight();
     if ($color === null) {
         $palette = self::$rgb;
         $color = '#ffffff';
         $alpha = 0;
     } else {
         $palette = $color->getPalette();
         $alpha = $color->getAlpha() / 100;
     }
     try {
         $pixel = new \GmagickPixel((string) $color);
         $pixel->setcolorvalue(\Gmagick::COLOR_OPACITY, $alpha);
         // does nothing as of Gmagick 1.1.7RC2.  Background will be fully opaque.
         $magick = new \Gmagick();
         $magick->newimage($width, $height, $pixel->getcolor(false));
         $magick->setimagecolorspace(\Gmagick::COLORSPACE_TRANSPARENT);
         $magick->setimagebackgroundcolor($pixel);
         return new RImage($magick, $palette, self::$emptyBag, array($width, $height));
     } catch (\Exception $e) {
         throw new \Imagine\Exception\RuntimeException("Gmagick: could not create empty image. {$e->getMessage()}", $e->getCode(), $e);
     }
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function create(BoxInterface $size, ColorInterface $color = null)
 {
     $width = $size->getWidth();
     $height = $size->getHeight();
     $palette = null !== $color ? $color->getPalette() : new RGB();
     $color = null !== $color ? $color : $palette->color('fff');
     try {
         $gmagick = new \Gmagick();
         // Gmagick does not support creation of CMYK GmagickPixel
         // see https://bugs.php.net/bug.php?id=64466
         if ($color instanceof CMYKColor) {
             $switchPalette = $palette;
             $palette = new RGB();
             $pixel = new \GmagickPixel($palette->color((string) $color));
         } else {
             $switchPalette = null;
             $pixel = new \GmagickPixel((string) $color);
         }
         if ($color->getPalette()->supportsAlpha() && $color->getAlpha() < 100) {
             throw new NotSupportedException('alpha transparency is not supported');
         }
         $gmagick->newimage($width, $height, $pixel->getcolor(false));
         $gmagick->setimagecolorspace(\Gmagick::COLORSPACE_TRANSPARENT);
         $gmagick->setimagebackgroundcolor($pixel);
         $image = new Image($gmagick, $palette, new MetadataBag());
         if ($switchPalette) {
             $image->usePalette($switchPalette);
         }
         return $image;
     } catch (\GmagickException $e) {
         throw new RuntimeException('Could not create empty image', $e->getCode(), $e);
     }
 }
 /**
  * (non-PHPdoc)
  * @see Imagine\Image\ImagineInterface::create()
  */
 public function create(BoxInterface $size, Color $color = null)
 {
     $width = $size->getWidth();
     $height = $size->getHeight();
     $color = null !== $color ? $color : new Color('fff');
     $gmagick = new \Gmagick();
     $pixel = new \GmagickPixel((string) $color);
     if ($color->getAlpha() > 0) {
         // TODO: implement support for transparent background
         throw new RuntimeException('alpha transparency not implemented');
     }
     $gmagick->newimage($width, $height, $pixel->getcolor(false));
     $gmagick->setimagecolorspace(\Gmagick::COLORSPACE_TRANSPARENT);
     // this is needed to propagate transparency
     $gmagick->setimagebackgroundcolor($pixel);
     return new Image($gmagick);
 }
Example #4
0
 public function transform($operation, $parameters)
 {
     if ($this->properties["mimetype"] == "image/tilepic") {
         return false;
     }
     # no transformations for Tilepic
     if (!$this->handle) {
         return false;
     }
     if (!$this->info["TRANSFORMATIONS"][$operation]) {
         # invalid transformation
         $this->postError(1655, _t("Invalid transformation %1", $operation), "WLPlugGmagick->transform()");
         return false;
     }
     # get parameters for this operation
     $sparams = $this->info["TRANSFORMATIONS"][$operation];
     $w = $parameters["width"];
     $h = $parameters["height"];
     $cw = $this->get("width");
     $ch = $this->get("height");
     if ((bool) $this->properties['no_upsampling']) {
         $w = min($cw, round($w));
         $h = min($ch, round($h));
     }
     $do_crop = 0;
     try {
         switch ($operation) {
             # -----------------------
             case 'ANNOTATE':
                 $d = new GmagickDraw();
                 if ($parameters['font']) {
                     try {
                         $d->setfont($parameters['font']);
                     } catch (Exception $e) {
                         $this->postError(1655, _t("Couldn't set font to %1. Gmagick error message: %2", $parameters['font'], $e->getMessage()), "WLPlugGmagick->transform()");
                         break;
                     }
                 }
                 $size = $parameters['size'] > 0 ? $parameters['size'] : 18;
                 $d->setfontsize($size);
                 $inset = $parameters['inset'] > 0 ? $parameters['inset'] : 0;
                 $pw = new GmagickPixel();
                 $pw->setcolor($parameters['color'] ? $parameters['color'] : "black");
                 $d->setfillcolor($pw);
                 switch ($parameters['position']) {
                     default:
                         break;
                 }
                 $this->handle->annotateimage($d, $inset, $size + $inset, 0, $parameters['text']);
                 break;
                 # -----------------------
             # -----------------------
             case 'WATERMARK':
                 if (!file_exists($parameters['image'])) {
                     break;
                 }
                 # gmagick can't handle opacity when compositing images
                 #$vn_opacity_setting = $parameters['opacity'];
                 #if (($vn_opacity_setting < 0) || ($vn_opacity_setting > 1)) {
                 #	$vn_opacity_setting = 0.5;
                 #}
                 if (($vn_watermark_width = $parameters['width']) < 10) {
                     $vn_watermark_width = $cw / 2;
                 }
                 if (($vn_watermark_height = $parameters['height']) < 10) {
                     $vn_watermark_height = $ch / 2;
                 }
                 switch ($parameters['position']) {
                     case 'north_east':
                         $vn_watermark_x = $cw - $vn_watermark_width;
                         $vn_watermark_y = 0;
                         break;
                     case 'north_west':
                         $vn_watermark_x = 0;
                         $vn_watermark_y = 0;
                         break;
                     case 'north':
                         $vn_watermark_x = ($cw - $vn_watermark_width) / 2;
                         $vn_watermark_y = 0;
                         break;
                     case 'south_east':
                         $vn_watermark_x = $cw - $vn_watermark_width;
                         $vn_watermark_y = $ch - $vn_watermark_height;
                         break;
                     case 'south':
                         $vn_watermark_x = ($cw - $vn_watermark_width) / 2;
                         $vn_watermark_y = $ch - $vn_watermark_height;
                         break;
                     case 'center':
                         $vn_watermark_x = ($cw - $vn_watermark_width) / 2;
                         $vn_watermark_y = ($ch - $vn_watermark_height) / 2;
                         break;
                     case 'south_west':
                     default:
                         $vn_watermark_x = $cw - $vn_watermark_width;
                         $vn_watermark_y = $ch - $vn_watermark_height;
                         break;
                 }
                 try {
                     $w = new Gmagick($parameters['image']);
                     $this->setResourceLimits($w);
                 } catch (Exception $e) {
                     $this->postError(1610, _t("Couldn't load watermark image at %1", $parameters['image']), "WLPlugGmagick->transform:WATERMARK()");
                     return false;
                 }
                 $w->scaleimage($vn_watermark_width, $vn_watermark_height);
                 $this->handle->compositeimage($w, 1, $vn_watermark_x, $vn_watermark_y);
                 break;
                 # -----------------------
             # -----------------------
             case 'SCALE':
                 $aa = $parameters["antialiasing"];
                 if ($aa <= 0) {
                     $aa = 0;
                 }
                 switch ($parameters["mode"]) {
                     # ----------------
                     case "width":
                         $scale_factor = $w / $cw;
                         $h = $ch * $scale_factor;
                         break;
                         # ----------------
                     # ----------------
                     case "height":
                         $scale_factor = $h / $ch;
                         $w = $cw * $scale_factor;
                         break;
                         # ----------------
                     # ----------------
                     case "bounding_box":
                         $scale_factor_w = $w / $cw;
                         $scale_factor_h = $h / $ch;
                         $w = $cw * ($scale_factor_w < $scale_factor_h ? $scale_factor_w : $scale_factor_h);
                         $h = $ch * ($scale_factor_w < $scale_factor_h ? $scale_factor_w : $scale_factor_h);
                         break;
                         # ----------------
                     # ----------------
                     case "fill_box":
                         $crop_from = $parameters["crop_from"];
                         if (!in_array($crop_from, array('center', 'north_east', 'north_west', 'south_east', 'south_west', 'random'))) {
                             $crop_from = '';
                         }
                         $scale_factor_w = $w / $cw;
                         $scale_factor_h = $h / $ch;
                         $w = $cw * ($scale_factor_w > $scale_factor_h ? $scale_factor_w : $scale_factor_h);
                         $h = $ch * ($scale_factor_w > $scale_factor_h ? $scale_factor_w : $scale_factor_h);
                         $do_fill_box_crop = true;
                         break;
                         # ----------------
                 }
                 $w = round($w);
                 $h = round($h);
                 if ($w > 0 && $h > 0) {
                     $crop_w_edge = $crop_h_edge = 0;
                     if (preg_match("/^([\\d]+)%\$/", $parameters["trim_edges"], $va_matches)) {
                         $crop_w_edge = ceil(intval($va_matches[1]) / 100 * $w);
                         $crop_h_edge = ceil(intval($va_matches[1]) / 100 * $h);
                     } else {
                         if (isset($parameters["trim_edges"]) && intval($parameters["trim_edges"]) > 0) {
                             $crop_w_edge = $crop_h_edge = intval($parameters["trim_edges"]);
                         }
                     }
                     if (!$this->handle->resizeimage($w + $crop_w_edge * 2, $h + $crop_h_edge * 2, Gmagick::FILTER_CUBIC, $aa)) {
                         $this->postError(1610, _t("Error during resize operation"), "WLPlugGmagick->transform()");
                         return false;
                     }
                     if ($do_fill_box_crop) {
                         // use face detection info to intelligently crop
                         if (is_array($this->properties['faces']) && sizeof($this->properties['faces'])) {
                             $va_info = array_shift($this->properties['faces']);
                             $crop_from_offset_x = ceil($va_info['x'] * ($scale_factor_w > $scale_factor_h ? $scale_factor_w : $scale_factor_h));
                             $crop_from_offset_x -= ceil(0.15 * $parameters["width"]);
                             // since face will be tightly cropped give it some room
                             $crop_from_offset_y = ceil($va_info['y'] * ($scale_factor_w > $scale_factor_h ? $scale_factor_w : $scale_factor_h));
                             $crop_from_offset_y -= ceil(0.15 * $parameters["height"]);
                             // since face will be tightly cropped give it some room
                             // Don't try to crop beyond image boundaries, you just end up scaling the image, often awkwardly
                             if ($crop_from_offset_x > $w - $parameters["width"]) {
                                 $crop_from_offset_x = 0;
                             }
                             if ($crop_from_offset_y > $h - $parameters["height"]) {
                                 $crop_from_offset_y = 0;
                             }
                             if ($crop_from_offset_x < 0) {
                                 $crop_from_offset_x = 0;
                             }
                             if ($crop_from_offset_y < 0) {
                                 $crop_from_offset_y = 0;
                             }
                         } else {
                             switch ($crop_from) {
                                 case 'north_west':
                                     $crop_from_offset_y = 0;
                                     $crop_from_offset_x = $w - $parameters["width"];
                                     break;
                                 case 'south_east':
                                     $crop_from_offset_x = 0;
                                     $crop_from_offset_y = $h - $parameters["height"];
                                     break;
                                 case 'south_west':
                                     $crop_from_offset_x = $w - $parameters["width"];
                                     $crop_from_offset_y = $h - $parameters["height"];
                                     break;
                                 case 'random':
                                     $crop_from_offset_x = rand(0, $w - $parameters["width"]);
                                     $crop_from_offset_y = rand(0, $h - $parameters["height"]);
                                     break;
                                 case 'north_east':
                                     $crop_from_offset_x = $crop_from_offset_y = 0;
                                     break;
                                 case 'center':
                                 default:
                                     $crop_from_offset_x = $crop_from_offset_y = 0;
                                     // Get image center
                                     $vn_center_x = caGetOption('_centerX', $parameters, 0.5);
                                     $vn_center_y = caGetOption('_centerY', $parameters, 0.5);
                                     if ($w > $parameters["width"]) {
                                         $crop_from_offset_x = ceil($w * $vn_center_x) - $parameters["width"] / 2;
                                         if ($crop_from_offset_x + $parameters["width"] > $w) {
                                             $crop_from_offset_x = $w - $parameters["width"];
                                         }
                                         if ($crop_from_offset_x < 0) {
                                             $crop_from_offset_x = 0;
                                         }
                                     } else {
                                         if ($h > $parameters["height"]) {
                                             $crop_from_offset_y = ceil($h * $vn_center_y) - $parameters["height"] / 2;
                                             if ($crop_from_offset_y + $parameters["height"] > $h) {
                                                 $crop_from_offset_y = $h - $parameters["height"];
                                             }
                                             if ($crop_from_offset_y < 0) {
                                                 $crop_from_offset_y = 0;
                                             }
                                         }
                                     }
                                     break;
                             }
                         }
                         if (!$this->handle->cropimage($parameters["width"], $parameters["height"], $crop_w_edge + $crop_from_offset_x, $crop_h_edge + $crop_from_offset_y)) {
                             $this->postError(1610, _t("Error during crop operation"), "WLPlugGmagick->transform()");
                             return false;
                         }
                         $this->properties["width"] = $parameters["width"];
                         $this->properties["height"] = $parameters["height"];
                     } else {
                         if ($crop_w_edge || $crop_h_edge) {
                             if (!$this->handle->cropimage($w, $h, $crop_w_edge, $crop_h_edge)) {
                                 $this->postError(1610, _t("Error during crop operation"), "WLPlugGmagick->transform()");
                                 return false;
                             }
                         }
                         $this->properties["width"] = $w;
                         $this->properties["height"] = $h;
                     }
                 }
                 break;
                 # -----------------------
             # -----------------------
             case "ROTATE":
                 $angle = $parameters["angle"];
                 if ($angle > -360 && $angle < 360) {
                     if (!$this->handle->rotateimage("#FFFFFF", $angle)) {
                         $this->postError(1610, _t("Error during image rotate"), "WLPlugGmagick->transform():ROTATE");
                         return false;
                     }
                 }
                 break;
                 # -----------------------
             # -----------------------
             case "DESPECKLE":
                 if (!$this->handle->despeckleimage()) {
                     $this->postError(1610, _t("Error during image despeckle"), "WLPlugGmagick->transform:DESPECKLE()");
                     return false;
                 }
                 break;
                 # -----------------------
             # -----------------------
             case "MEDIAN":
                 $radius = $parameters["radius"];
                 if ($radius < 0.1) {
                     $radius = 1;
                 }
                 if (!$this->handle->medianfilterimage($radius)) {
                     $this->postError(1610, _t("Error during image median filter"), "WLPlugGmagick->transform:MEDIAN()");
                     return false;
                 }
                 break;
                 # -----------------------
             # -----------------------
             case "SHARPEN":
                 $radius = $parameters["radius"];
                 if ($radius < 0.1) {
                     $radius = 1;
                 }
                 $sigma = $parameters["sigma"];
                 if ($sigma < 0.1) {
                     $sigma = 1;
                 }
                 if (!$this->handle->sharpenImage($radius, $sigma)) {
                     $this->postError(1610, _t("Error during image sharpen"), "WLPlugGmagick->transform:SHARPEN()");
                     return false;
                 }
                 break;
                 # -----------------------
             # -----------------------
             case "UNSHARPEN_MASK":
                 # noop
                 break;
                 # -----------------------
             # -----------------------
             case "SET":
                 while (list($k, $v) = each($parameters)) {
                     $this->set($k, $v);
                 }
                 break;
                 # -----------------------
         }
         return 1;
     } catch (Exception $e) {
         $this->postError(1610, _t("Gmagick exception"), "WLPlugGmagick->transform");
         return false;
     }
 }
Example #5
0
 /**
  * Gets specifically formatted color string from Color instance
  *
  * @param ColorInterface $color
  *
  * @return string
  */
 private function getColor(ColorInterface $color)
 {
     if (!$color->isOpaque()) {
         throw new InvalidArgumentException('Gmagick doesn\'t support transparency');
     }
     $pixel = new \GmagickPixel((string) $color);
     $pixel->setColorValue(\Gmagick::COLOR_OPACITY, number_format(abs(round($color->getAlpha() / 100, 1)), 1));
     return $pixel;
 }
Example #6
0
 /**
  * Returns a color given a pixel, depending the Palette context
  *
  * Note : this method is public for PHP 5.3 compatibility
  *
  * @param \GmagickPixel $pixel
  *
  * @return ColorInterface
  *
  * @throws InvalidArgumentException In case a unknown color is requested
  */
 public function pixelToColor(\GmagickPixel $pixel)
 {
     static $colorMapping = array(ColorInterface::COLOR_RED => \Gmagick::COLOR_RED, ColorInterface::COLOR_GREEN => \Gmagick::COLOR_GREEN, ColorInterface::COLOR_BLUE => \Gmagick::COLOR_BLUE, ColorInterface::COLOR_CYAN => \Gmagick::COLOR_CYAN, ColorInterface::COLOR_MAGENTA => \Gmagick::COLOR_MAGENTA, ColorInterface::COLOR_YELLOW => \Gmagick::COLOR_YELLOW, ColorInterface::COLOR_KEYLINE => \Gmagick::COLOR_BLACK, ColorInterface::COLOR_GRAY => \Gmagick::COLOR_RED);
     if ($this->palette->supportsAlpha()) {
         try {
             $alpha = (int) round($pixel->getcolorvalue(\Gmagick::COLOR_ALPHA) * 100);
         } catch (\GmagickPixelException $e) {
             $alpha = null;
         }
     } else {
         $alpha = null;
     }
     $palette = $this->palette();
     return $this->palette->color(array_map(function ($color) use($palette, $pixel, $colorMapping) {
         if (!isset($colorMapping[$color])) {
             throw new InvalidArgumentException(sprintf('Color %s is not mapped in Gmagick', $color));
         }
         $multiplier = 255;
         if ($palette->name() === PaletteInterface::PALETTE_CMYK) {
             $multiplier = 100;
         }
         return $pixel->getcolorvalue($colorMapping[$color]) * $multiplier;
     }, $this->palette->pixelDefinition()), $alpha);
 }
Example #7
0
 /**
  * Gets specifically formatted color string from Color instance
  *
  * @param Imagine\Image\Color $color
  *
  * @return string
  */
 private function getColor(Color $color)
 {
     $pixel = new \GmagickPixel((string) $color);
     $pixel->setColorValue(\Gmagick::COLOR_OPACITY, number_format(abs(round($color->getAlpha() / 100, 1)), 1));
     return $pixel;
 }