image is null */ if ($force) { $this->image = Image::getImagine() ->open($this->fullPath); } return $this->image->getSize(); } /** * Open the image and store it, set initial width and height */ public function init() { // $this->image = Image::getImagine() // ->open($this->fullPath); // $this->width = $this->image->getSize() // ->getWidth(); // $this->height = $this->image->getSize() // ->getHeight(); } /** * Resize image, keeping aspect ratio * * @param int $width * @param int $height * * @return $this */ public function resize(int $width, int $height) { $this->prefix = $width . '_x_' . $height; $this->action = self::ACTION_RESIZE; $this->actionWidth = $width; $this->actionHeight = $height; return $this; } protected function perfomResize(int $width, int $height) { $this->image = $this->image->thumbnail(new Box($width, $height)); return $this; } /** * Resize to needed width, saving the proportion * * @param int $width * * @return $this */ public function setWidth(int $width) { $this->prefix = 'w_' . $width; $this->action = self::ACTION_SET_WIDTH; $this->actionHeight = $width; return $this; } protected function performSetWidth(int $width) { $height = round($this->height * $width / $this->width); $this->image = $this->image->thumbnail(new Box($width, $height)); return $this; } /** * Resize to needed height, saving the proportion * * @param int $height * * @return $this */ public function setHeight(int $height) { $this->prefix = 'h_' . $height; $this->action = self::ACTION_SET_HEIGHT; $this->actionHeight = $height; return $this; } protected function performSetHeight(int $height) { $width = round($this->width * $height / $this->height); $this->image = $this->image->thumbnail(new Box($width, $height)); return $this; } /** * First resize image by closest side, the crop out the rests * * @param int $width * @param int $height * * @return $this */ public function cropResize(int $width, int $height) { $this->prefix = 'cr_' . $width . '_x_' . $height; $this->action = self::ACTION_CROP_RESIZE; $this->actionHeight = $height; $this->actionWidth = $width; return $this; } protected function performCropResize(int $width, int $height) { if ($this->width / $this->height > $width / $height) { $this->image = $this->performSetHeight($height)->image; $newWidth = $this->image->getSize() ->getWidth(); if ($newWidth - $width >= 0) { $this->image = $this->image->crop( new Point(round(( $newWidth - $width ) / 2), 0), new Box($width, $height) ); } } else { $this->image = $this->performSetWidth($width)->image; $newHeight = $this->image->getSize() ->getHeight(); if ($newHeight - $height >= 0) { $this->image = $this->image->crop( new Point(0, round(( $newHeight - $height ) / 2)), new Box($width, $height) ); } } return $this; } /** * Croup out needed box from the middle of image * * @param int $width * @param int $height * * @return $this */ public function crop(int $width, int $height) { $this->prefix = 'c_' . $width . '_x_' . $height; $this->action = self::ACTION_CROP; $this->actionWidth = $width; $this->actionHeight = $height; return $this; } protected function performCrop(int $width, int $height) { $this->image = $this->image->copy() ->crop( new Point(round($this->width - $width), round($this->height - $height)), new Box($width, $height) ); return $this; } /** * Fits image in needed dimensions, empty area fiils with chosen color, default is white * * @param int $width * @param int $height * @param string $color * * @return $this */ public function fillResize(int $width, int $height, string $color = '#FFFFFF') { $this->prefix = 'cf_' . $width . '_x_' . $height; $this->action = self::ACTION_FILL_RESIZE; $this->actionHeight = $height; $this->actionWidth = $width; $this->actionColor = $color; return $this; } protected function performFillResize(int $width, int $height, string $color = '#FFFFFF') { $parent = Image::getImagine() ->create(new Box($width, $height), ( new RGB() )->color($color)); if ($this->width / $this->height > $width / $height) { $this->performSetWidth($width); $newHeight = $this->image->getSize() ->getHeight(); $this->image = $parent->paste( $this->image, new Point( 0, round( ( $height - $newHeight ) / 2 ) ) ); } else { $this->performSetHeight($height); $newWidth = $this->image->getSize() ->getWidth(); $this->image = $parent->paste( $this->image, new Point( round( ( $width - $newWidth ) / 2 ), 0 ) ); } return $this; } /** * Resize image to needed size, without saving aspect ratio * * @param int $width * @param int $height * * @return $this */ public function strictResize(int $width, int $height) { $this->prefix = 'sr_' . $width . '_x_' . $height; $this->action = self::ACTION_STRICT_RESIZE; $this->actionWidth = $width; $this->actionHeight = $height; return $this; } protected function performStrictResize(int $width, int $height) { $this->image = $this->image->resize(new Box($width, $height)); return $this; } /** * Sets the output image quality in percents, default is 100% * * @param int $quality * * @return $this * @throws \yii\base\InvalidConfigException */ public function quality(int $quality) { if ($quality <= 0 || $quality > 100) { throw new InvalidConfigException('Wrong quality value'); } $this->qualityValue = $quality; $this->prefix .= '_q' . $quality; return $this; } /** * Save the image, and return path to it * * @return string */ public function render() { $name = $this->name; if (isset($this->prefix)) { $name .= '_' . $this->prefix; } $path = \Yii::getAlias('@storage/helper/') . $name . '.' . $this->extension; if (file_exists($path)) { return '/storage/helper/' . $name . '.' . $this->extension; } $this->performAction(); $this->image->save( $path, [ 'quality' => $this->qualityValue, ] ); unset($this->image); return '/storage/helper/' . $name . '.' . $this->extension; } /** * Save and return the image as html img string * * @param array $options * * @return string */ public function renderImage(array $options = []) { return Html::img($this->render(), $options); } protected function performAction() { $this->image = Image::getImagine() ->open($this->fullPath); $this->width = $this->image->getSize() ->getWidth(); $this->height = $this->image->getSize() ->getHeight(); if ($this->action === self::ACTION_CROP) { $this->performCrop($this->actionWidth, $this->actionHeight); } elseif ($this->action === self::ACTION_STRICT_RESIZE) { $this->performStrictResize($this->actionWidth, $this->actionHeight); } elseif ($this->action === self::ACTION_CROP_RESIZE) { $this->performCropResize($this->actionWidth, $this->actionHeight); } elseif ($this->action === self::ACTION_FILL_RESIZE) { $this->performFillResize($this->actionWidth, $this->actionHeight, $this->actionColor); } elseif ($this->action === self::ACTION_RESIZE) { $this->perfomResize($this->actionWidth, $this->actionHeight); } elseif ($this->action === self::ACTION_SET_HEIGHT) { $this->performSetHeight($this->actionHeight); } elseif ($this->action === self::ACTION_SET_WIDTH) { $this->performSetWidth($this->actionWidth); } } }