/** * {@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; }
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; } }