示例#1
0
 /**
  * {@inheritdoc}
  */
 public function scale(BoxInterface $size)
 {
     try {
         $this->gmagick->scaleimage($size->getWidth(), $size->getHeight());
     } catch (\GmagickException $e) {
         throw new RuntimeException('Scale operation failed', $e->getCode(), $e);
     }
     return $this;
 }
示例#2
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']);
                 } 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:
                                     if ($w > $parameters["width"]) {
                                         $crop_from_offset_x = ceil(($w - $parameters["width"]) / 2);
                                     } else {
                                         if ($h > $parameters["height"]) {
                                             $crop_from_offset_y = ceil(($h - $parameters["height"]) / 2);
                                         }
                                     }
                                     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;
     }
 }