public function upload($attribute) { $class = \yii\helpers\StringHelper::basename(get_class($this->owner)) . 'Cutter'; if ($uploadImage = UploadedFile::getInstance($this->owner, $attribute)) { if (!$this->owner->isNewRecord) { $this->delete($attribute); } $cropping = $_POST[$class][$attribute . '-cropping']; $croppingFileName = md5($uploadImage->name . $this->quality . Json::encode($cropping)); $croppingFileExt = strrchr($uploadImage->name, '.'); $croppingFileDir = substr($croppingFileName, 0, 2); $croppingFileBasePath = Yii::getAlias($this->basePath) . $this->baseDir; if (!is_dir($croppingFileBasePath)) { mkdir($croppingFileBasePath, 0755, true); } $croppingFilePath = Yii::getAlias($this->basePath) . $this->baseDir . DIRECTORY_SEPARATOR . $croppingFileDir; if (!is_dir($croppingFilePath)) { mkdir($croppingFilePath, 0755, true); } $fileSavePath = $croppingFilePath . DIRECTORY_SEPARATOR . $croppingFileName . $croppingFileExt; $point = new Point($cropping['dataX'], $cropping['dataY']); $box = new Box($cropping['dataWidth'], $cropping['dataHeight']); $palette = new \Imagine\Image\Palette\RGB(); $color = $palette->color('fff', 0); Image::frame($uploadImage->tempName, 0, 'fff', 0)->rotate($cropping['dataRotate'], $color)->crop($point, $box)->save($fileSavePath, ['quality' => $this->quality]); $this->owner->{$attribute} = $this->baseDir . DIRECTORY_SEPARATOR . $croppingFileDir . DIRECTORY_SEPARATOR . $croppingFileName . $croppingFileExt; } elseif (isset($_POST[$class][$attribute . '-remove']) && $_POST[$class][$attribute . '-remove']) { $this->delete($attribute); } elseif (!empty($_POST[$class][$attribute])) { $this->owner->{$attribute} = $_POST[$class][$attribute]; } elseif (isset($this->owner->oldAttributes[$attribute])) { $this->owner->{$attribute} = $this->owner->oldAttributes[$attribute]; } }
/** * Обработаем создание нового изображения для дальнейшего скачивания пользователем. */ private function handleSaveImage() { $items = $_POST['items']; $category = $_POST['cat']; $image = $_POST['img']; $fileName = Image::getName($category, $image); $Palette = new RGB(); $Imagine = new Imagine(); $Image = $Imagine->open(IMG_1920x1080 . $fileName); foreach ($items as $item) { $text = $item['text']; $fontSize = $item['fontSize']; $x = $item['relativeX']; $y = $item['relativeY']; $sizedFontSize = $fontSize * 1920 / 500; $sizedX = $this->coeffX * $x; $sizedY = $this->coeffY * $y; $Font = $Imagine->font(FONT_DIR . 'Arial.ttf', $sizedFontSize, $Palette->color($item['color'])); $Position = new Point($sizedX, $sizedY); $angle = rad2deg($item['angle']); $Image->draw()->text($text, $Font, $Position, $angle); } $id = uniqid(); $filePath = IMG_DOWNLOAD . $id . Image::EXTENSION; $Image->save($filePath); header('Content-Type: application/json; charset=utf8'); echo json_encode(['id' => $id], JSON_UNESCAPED_UNICODE); exit; }
/** * @param ImageInterface $image * @return ImageInterface */ public function generateThumb(ImageInterface $image, $width, $height) { $background = isset($this->options["background"]) ? $this->options["background"] : null; $fitSize = isset($this->options["fitSize"]) ? $this->options["fitSize"] : true; $sizeBox = new Box($width, $height); $thumbMode = ImageInterface::THUMBNAIL_INSET; $thumb = $image->thumbnail($sizeBox, $thumbMode); // fill the area if ($fitSize) { $palette = new RGB(); if (!$background || $background == "transparent") { $backgroundColor = $palette->color("fff", 1); } else { $backgroundColor = $palette->color($background); } // source http://harikt.com/blog/2012/12/17/resize-image-keeping-aspect-ratio-in-imagine/ $realThumb = Image::create($sizeBox, $backgroundColor); $sizeR = $thumb->getSize(); $widthR = $sizeR->getWidth(); $heightR = $sizeR->getHeight(); $startX = $startY = 0; if ($widthR < $width) { $startX = ($width - $widthR) / 2; } if ($heightR < $height) { $startY = ($height - $heightR) / 2; } $realThumb->paste($thumb, new Point($startX, $startY)); } else { $realThumb = $thumb; } return $realThumb; }
/** * {@inheritdoc} */ public function resize($imagePath, array $size, $mode, $force = false) { $cacheKey = $this->getCacheKey($size, $mode); $filename = basename($imagePath); if (false === $force && $this->imageCache->contains($filename, $cacheKey)) { return $this->imageCache->getRelativePath($filename, $cacheKey); } $cacheAbsolutePath = $this->imageCache->getAbsolutePath($filename, $cacheKey); $imagine = new Imagine(); $imagineImage = $imagine->open($this->filesystem->getRootDir() . $imagePath); $imageSize = array($imagineImage->getSize()->getWidth(), $imagineImage->getSize()->getHeight()); $boxSize = $this->resizeHelper->getBoxSize($imageSize, $size); $box = $this->getBox($boxSize[0], $boxSize[1]); if (ImageResizerInterface::INSET === $mode) { $imageSizeInBox = $this->resizeHelper->getImageSizeInBox($imageSize, $boxSize); $imagineImage->resize($this->getBox($imageSizeInBox[0], $imageSizeInBox[1])); $palette = new RGB(); $box = $imagine->create($box, $palette->color($this->color, $this->alpha)); $imagineImage = $box->paste($imagineImage, $this->getPointInBox($imageSizeInBox, $boxSize)); } else { $imagineImage = $imagineImage->thumbnail($box); } $this->filesystem->mkdir(dirname($cacheAbsolutePath)); $imagineImage->save($cacheAbsolutePath, ImageOptionHelper::getOption($filename)); return $this->imageCache->getRelativePath($filename, $cacheKey); }
public function draw() { $grid = $this->getGrid(); $palette = new RGB(); $canvas = $this->drawer->create(new Box($this->width, $this->height), $palette->color($this->background)); // Calculations $start_x = $this->padding; $start_y = $this->padding; $rows = count($grid); $columns = count($grid[0]); $working_width = $this->width - $this->padding * 2; $working_height = $this->height - $this->padding * 2; $block_width = $working_width / $columns; $block_height = $working_height / $rows; $spacing = $this->spacing; $center_x = $block_width / 2; $center_y = $block_height / 2; // Color to be used to draw the squares $color = $canvas->palette()->color($this->foregroundColor()); for ($y = 0; $y < $rows; $y++) { for ($x = 0; $x < $columns; $x++) { // If the location in the grid array is true, we will draw a square in that position. if ($grid[$y][$x] === 'o') { $canvas->draw()->ellipse(new Point($block_width * $x + $start_x + $center_x, $block_width * $y + $start_y + $center_y), new Box($block_width - $spacing, $block_height - $spacing), $color, true); } elseif ($grid[$y][$x] === 'x') { $canvas->draw()->polygon([new Point($block_width * $x + $start_x + $spacing, $block_height * $y + $start_y + $spacing), new Point($block_width * ($x + 1) + $start_x - $spacing, $block_height * $y + $start_y + $spacing), new Point($block_width * ($x + 1) + $start_x - $spacing, $block_height * ($y + 1) + $start_y - $spacing), new Point($block_width * $x + $start_x + $spacing, $block_height * ($y + 1) + $start_y - $spacing)], $color, true); } $color = $this->varryColor($color, $canvas); } } return $canvas; }
/** * {@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); } }
protected function getColor($color) { static $palette; if (!$palette) { $palette = new RGB(); } return $palette->color($color); }
public function create($width, $height, $background = null) { $palette = new RGB(); $color = is_null($background) ? $palette->color('#fff', 0) : $palette->color($background, 100); $size = new Box($width, $height); $newImage = new self(); $newImage->setImage($this->manager->create($size, $color)); return $newImage; }
public function testMerge() { $palette = new RGB(); $image = $this->getImagine()->create(new Box(20, 20), $palette->color('#FFFFFF')); foreach ($image->layers() as $layer) { $layer->draw()->polygon(array(new Point(0, 0), new Point(0, 20), new Point(20, 20), new Point(20, 0)), $palette->color('#FF0000'), true); } $image->layers()->merge(); $this->assertEquals('#ff0000', (string) $image->getColorAt(new Point(5, 5))); }
public function testShouldDetermineFontSize() { if (!$this->isFontTestSupported()) { $this->markTestSkipped('This install does not support font tests'); } $palette = new RGB(); $path = 'tests/Imagine/Fixtures/font/Arial.ttf'; $black = $palette->color('000'); $factory = $this->getImagine(); $this->assertEquals($this->getEstimatedFontBox(), $factory->font($path, 36, $black)->box('string')); }
/** * {@inheritdoc} */ public function generate($toFile = null) { $fontSize = max(min($this->dimension->getWidth() / strlen($this->text) * 1.15, $this->dimension->getHeight() * 0.5), 5); $palette = new RGB(); $image = $this->imagine->create(new Box($this->dimension->getWidth(), $this->dimension->getHeight()), $palette->color($this->backgroundColor->getColor())); $font = ImagineFactory::createFontInstance($this->instanceType, __DIR__ . '/resource/mplus.ttf', $fontSize, $palette->color($this->stringColor->getColor())); $textProperties = $font->box($this->text); $image->draw()->text($this->text, $font, new Point(($this->dimension->getWidth() - $textProperties->getWidth()) / 2, ($this->dimension->getHeight() - $textProperties->getHeight()) / 2)); if ($toFile !== null) { $image->save($toFile); } return new Result($image, $toFile); }
public function testLoadGrayscale() { $loader = new GrayscaleFilterLoader(); $palette = new RGB(); $imagine = new Imagine(); // Generate blue image $image = $imagine->create(new Box(20, 20), $palette->color(array(20, 90, 240))); //Apply Grayscale filter $result = $loader->load($image); //Test result $pixel = $result->getColorAt(new Point(10, 10)); $this->assertEquals('#565656', (string) $pixel); }
public function draw() { // Gets the grid data array // eta grid value nicche Layout object theke $grid = $this->getGrid(); $palette = new RGB(); $canvas = $this->drawer->create(new Box($this->width, $this->height), $palette->color($this->background)); // Calculations $start_x = $this->padding; $start_y = $this->padding; // counts the number of roews $rows = count($grid); // counts the number of columns in each row $columns = count($grid[0]); // Calculates the area useable (leaving out space for padding) $working_width = $this->width - $this->padding * 2; $working_height = $this->height - $this->padding * 2; // Calculates the size of each grid block within the usable area $block_width = $working_width / $columns; $block_height = $working_height / $rows; // Calculate Spacing $spacing = $this->spacing / 2; // Creates a color to be used to draw the squares $color = $canvas->palette()->color($this->foregroundColor()); // Loops thorugh the rows for ($y = 0; $y < $rows; $y++) { for ($x = 0; $x < $columns; $x++) { // If the location in the grid array is true, we will draw a square in that position. if ($grid[$y][$x] !== false) { // Draws the square $points = []; $block = $grid[$y][$x]; if ($block[0][0] === 1) { $points[] = new Point($block_width * $x + $start_x + $spacing, $block_height * $y + $start_y + $spacing); } if ($block[0][1] === 1) { $points[] = new Point($block_width * ($x + 1) + $start_x - $spacing, $block_height * $y + $start_y + $spacing); } if ($block[1][1] === 1) { $points[] = new Point($block_width * ($x + 1) + $start_x - $spacing, $block_height * ($y + 1) + $start_y - $spacing); } if ($block[1][0] === 1) { $points[] = new Point($block_width * $x + $start_x + $spacing, $block_height * ($y + 1) + $start_y - $spacing); } $canvas->draw()->polygon($points, $color, true); } $color = $this->varryColor($color, $canvas); } } return $canvas; }
/** * {@inheritDoc} */ public function load(ImageInterface $image, array $options = array()) { $palette = new RGB(); $background = $palette->color(isset($options['color']) ? $options['color'] : '#fff', $options['alpha'] ? $options['alpha'] : 0); $topLeft = new Point(0, 0); $size = $image->getSize(); if (isset($options['size'])) { list($width, $height) = $options['size']; $size = new Box($width, $height); $topLeft = new Point(($width - $image->getSize()->getWidth()) / 2, ($height - $image->getSize()->getHeight()) / 2); } $canvas = $this->imagine->create($size, $background); return $canvas->paste($image, $topLeft); }
/** * Add photo * * @param string $photo * @return PrintContent */ public function addPhoto($photo) { $imagine = new Imagine(); if (@is_file($photo)) { $image = $imagine->open($photo); } else { $image = $imagine->load($photo); } // Fix transparent png $palette = new RGB(); $white = $palette->color('FFF'); $image = $imagine->create(new Box($image->getSize()->getWidth(), $image->getSize()->getHeight()), $white)->paste($image, new Point(0, 0)); return $this->addContent(self::TYPE_PHOTO, $image->get('jpg')); }
/** * Set properties for text drawing on the image. * * @param $fontFile string path to the font file on server * @param $size int font size to use * @param $color string font color to use in hex format * * @return null */ public function setFontProperties($fontFile, $size, $color) { if (empty($this->_palette)) { $this->_palette = new \Imagine\Image\Palette\RGB(); } $this->_font = $this->_instance->font($fontFile, $size, $this->_palette->color($color)); }
public function testBlur() { $palette = new RGB(); $imagine = $this->getImagine(); $image = $imagine->create(new Box(20, 20), $palette->color('#fff')); $image->draw()->line(new Point(10, 0), new Point(10, 20), $palette->color('#000'), 1); $image->effects()->blur(); $pixel = $image->getColorAt(new Point(9, 10)); $this->assertNotEquals(255, $pixel->getRed()); $this->assertNotEquals(255, $pixel->getGreen()); $this->assertNotEquals(255, $pixel->getBlue()); }
public function getTransformed() { if (!empty($this->height) && !empty($this->width)) { $sourcebox = $this->source->getSize(); $widthbox = $sourcebox->widen($this->width); $heightbox = $sourcebox->heighten($this->height); if ($widthbox->getHeight() > $this->height) { $resized = $this->source->resize($heightbox); $targetbox = $heightbox; } else { $resized = $this->source->resize($widthbox); $targetbox = $widthbox; } $wantedsize = new Box($this->width, $this->height); $palette = new RGB(); $canvasImage = $this->imagine->create($wantedsize, $palette->color("FFFFFF")); $xstart = floor(($wantedsize->getWidth() - $targetbox->getWidth()) / 2); $ystart = floor(($wantedsize->getHeight() - $targetbox->getHeight()) / 2); $startpoint = new Point($xstart, $ystart); return $canvasImage->paste($resized, $startpoint); } else { throw new \ImagickException("Missing parameters!"); } }
public function testCreateAlphaPrecision() { $imagine = $this->getImagine(); $palette = new RGB(); $image = $imagine->create(new Box(1, 1), $palette->color("#f00", 17)); $actualColor = $image->getColorAt(new Point(0, 0)); $this->assertEquals(17, $actualColor->getAlpha()); }
/** * Process image and write the result in the image cache. * * If the image already exists in cache, the cache file is immediately returned, without any processing * If the original (full resolution) image is required, create either a symbolic link with the * original image in the cache dir, or copy it in the cache dir. * * This method updates the cache_file_path and file_url attributes of the event * * @param ImageEvent $event * @param string $eventName * @param EventDispatcherInterface $dispatcher * * @throws \Thelia\Exception\ImageException * @throws \InvalidArgumentException */ public function processImage(ImageEvent $event, $eventName, EventDispatcherInterface $dispatcher) { $subdir = $event->getCacheSubdirectory(); $source_file = $event->getSourceFilepath(); if (null == $subdir || null == $source_file) { throw new \InvalidArgumentException("Cache sub-directory and source file path cannot be null"); } // Find cached file path $cacheFilePath = $this->getCacheFilePath($subdir, $source_file, $event->isOriginalImage(), $event->getOptionsHash()); $originalImagePathInCache = $this->getCacheFilePath($subdir, $source_file, true); if (!file_exists($cacheFilePath)) { if (!file_exists($source_file)) { throw new ImageException(sprintf("Source image file %s does not exists.", $source_file)); } // Create a cached version of the original image in the web space, if not exists if (!file_exists($originalImagePathInCache)) { $mode = ConfigQuery::read('original_image_delivery_mode', 'symlink'); if ($mode == 'symlink') { if (false === symlink($source_file, $originalImagePathInCache)) { throw new ImageException(sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir)); } } else { // mode = 'copy' if (false === @copy($source_file, $originalImagePathInCache)) { throw new ImageException(sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir)); } } } // Process image only if we have some transformations to do. if (!$event->isOriginalImage()) { // We have to process the image. $imagine = $this->createImagineInstance(); $image = $imagine->open($source_file); if ($image) { // Allow image pre-processing (watermarging, or other stuff...) $event->setImageObject($image); $dispatcher->dispatch(TheliaEvents::IMAGE_PREPROCESSING, $event); $image = $event->getImageObject(); $background_color = $event->getBackgroundColor(); $palette = new RGB(); if ($background_color != null) { $bg_color = $palette->color($background_color); } else { // Define a fully transparent white background color $bg_color = $palette->color('fff', 0); } // Apply resize $image = $this->applyResize($imagine, $image, $event->getWidth(), $event->getHeight(), $event->getResizeMode(), $bg_color, $event->getAllowZoom()); // Rotate if required $rotation = intval($event->getRotation()); if ($rotation != 0) { $image->rotate($rotation, $bg_color); } // Flip // Process each effects foreach ($event->getEffects() as $effect) { $effect = trim(strtolower($effect)); $params = explode(':', $effect); switch ($params[0]) { case 'greyscale': case 'grayscale': $image->effects()->grayscale(); break; case 'negative': $image->effects()->negative(); break; case 'horizontal_flip': case 'hflip': $image->flipHorizontally(); break; case 'vertical_flip': case 'vflip': $image->flipVertically(); break; case 'gamma': // Syntax: gamma:value. Exemple: gamma:0.7 if (isset($params[1])) { $gamma = floatval($params[1]); $image->effects()->gamma($gamma); } break; case 'colorize': // Syntax: colorize:couleur. Exemple: colorize:#ff00cc if (isset($params[1])) { $the_color = $palette->color($params[1]); $image->effects()->colorize($the_color); } break; } } $quality = $event->getQuality(); if (is_null($quality)) { $quality = ConfigQuery::read('default_images_quality_percent', 75); } // Allow image post-processing (watermarging, or other stuff...) $event->setImageObject($image); $dispatcher->dispatch(TheliaEvents::IMAGE_POSTPROCESSING, $event); $image = $event->getImageObject(); $image->save($cacheFilePath, array('quality' => $quality)); } else { throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file))); } } } // Compute the image URL $processed_image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath)); // compute the full resolution image path in cache $original_image_url = $this->getCacheFileURL($subdir, basename($originalImagePathInCache)); // Update the event with file path and file URL $event->setCacheFilepath($cacheFilePath); $event->setCacheOriginalFilepath($originalImagePathInCache); $event->setFileUrl(URL::getInstance()->absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE)); $event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE)); }
public function testImageCreatedAlpha() { $palette = new RGB(); $image = $this->getImagine()->create(new Box(1, 1), $palette->color("#7f7f7f", 10)); $actualColor = $image->getColorAt(new Point(0, 0)); $this->assertEquals("#7f7f7f", (string) $actualColor); $this->assertEquals(10, $actualColor->getAlpha()); }
/** * Create thumbnail * * @param $image \Imagine\Imagick\Image * @param $options * @param string $filter * @return ImageInterface * @throws InvalidArgumentException */ private function thumbnail($image, $options, $filter = ImageInterface::FILTER_UNDEFINED) { $width = $options['box'][0]; $height = $options['box'][1]; $size = $box = new Box($width, $height); $mode = $options['mode']; if ($mode !== ImageInterface::THUMBNAIL_INSET && $mode !== ImageInterface::THUMBNAIL_OUTBOUND) { throw new InvalidArgumentException('Invalid mode specified'); } $imageSize = $image->getSize(); $ratios = array($size->getWidth() / $imageSize->getWidth(), $size->getHeight() / $imageSize->getHeight()); $image->strip(); // if target width is larger than image width // AND target height is longer than image height if (!$size->contains($imageSize)) { if ($mode === ImageInterface::THUMBNAIL_INSET) { $ratio = min($ratios); } else { $ratio = max($ratios); } if ($mode === ImageInterface::THUMBNAIL_OUTBOUND) { if (!$imageSize->contains($size)) { $size = new Box(min($imageSize->getWidth(), $size->getWidth()), min($imageSize->getHeight(), $size->getHeight())); } else { $imageSize = $image->getSize()->scale($ratio); $image->resize($imageSize, $filter); } if ($ratios[0] > $ratios[1]) { $cropPoint = new Point(0, 0); } else { $cropPoint = new Point(max(0, round(($imageSize->getWidth() - $size->getWidth()) / 2)), max(0, round(($imageSize->getHeight() - $size->getHeight()) / 2))); } $image->crop($cropPoint, $size); } else { if (!$imageSize->contains($size)) { $imageSize = $imageSize->scale($ratio); $image->resize($imageSize, $filter); } else { $imageSize = $image->getSize()->scale($ratio); $image->resize($imageSize, $filter); } } } // create empty image to preserve aspect ratio of thumbnail $palette = new RGB(); $color = $palette->color('#000', 0); //transparent png with imagick $thumb = Image::getImagine()->create($box, $color); // calculate points $size = $image->getSize(); $startX = 0; $startY = 0; if ($size->getWidth() < $width) { $startX = ceil($width - $size->getWidth()) / 2; } if ($size->getHeight() < $height) { $startY = ceil($height - $size->getHeight()) / 2; } $thumb->paste($image, new Point($startX, $startY)); return $thumb; }
/** * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2. * @param string|resource|ImageInterface $image either ImageInterface, resource or a string containing file path * @param int $margin the frame size to add around the image * @param string $color the frame color * @param int $alpha the alpha value of the frame. * @return ImageInterface */ public static function frame($image, $margin = 20, $color = '666', $alpha = 100) { $img = static::getImagine()->open(Yii::getAlias($image)); $size = $img->getSize(); $pasteTo = new Point($margin, $margin); $palette = new RGB(); $color = $palette->color($color, $alpha); $box = new Box($size->getWidth() + ceil($margin * 2), $size->getHeight() + ceil($margin * 2)); $finalImage = static::getImagine()->create($box, $color); $finalImage->paste($img, $pasteTo); return $finalImage; }
public function testCreateTransparentGradient() { $factory = $this->getImagine(); $palette = new RGB(); $size = new Box(100, 50); $image = $factory->create($size, $palette->color('f00')); $image->paste($factory->create($size, $palette->color('ff0'))->applyMask($factory->create($size)->fill(new Horizontal($image->getSize()->getWidth(), $palette->color('fff'), $palette->color('000')))), new Point(0, 0)); $size = $image->getSize(); unset($image); $this->assertEquals(100, $size->getWidth()); $this->assertEquals(50, $size->getHeight()); }
/** * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2. * @param string $filename the full path to the image file * @param integer $margin the frame size to add around the image * @param string $color the frame color * @param integer $alpha the alpha value of the frame. * @return ImageInterface */ public static function frame($filename, $margin = 20, $color = '666', $alpha = 100) { $img = static::getImagine()->open($filename); $size = $img->getSize(); $pasteTo = new Point($margin, $margin); $padColor = new RGB(); $box = new Box($size->getWidth() + ceil($margin * 2), $size->getHeight() + ceil($margin * 2)); $image = static::getImagine()->create($box, $padColor->color($color, $alpha)); $image->paste($img, $pasteTo); return $image; }
/** * Adds the text to the image. */ public function renderText() { $palette = new RGB(); $color = $palette->color('#005', 100); $font = new Font(dirname(__FILE__) . '/../assets/trebuchet_bi.ttf', 24, $color); $blocks = explode('__', $this->text); $wordWidths = array(); foreach ($blocks as $key => $block) { $blocks[$key] = preg_split('#[^a-z0-9,:\'\\.-]#i', trim($block)); foreach ($blocks[$key] as $word) { $wordWidths[] = $font->box($word)->getWidth(); } } $lineHeight = 45; $maxRatio = 0; $result = array(); $space = $font->box('-')->getWidth(); $stepWidth = 25; for ($maxWidth = floor(max($wordWidths) / $stepWidth) * $stepWidth; $maxWidth <= 375; $maxWidth += $stepWidth) { $wordIndex = 0; $lines = array(); $maxLineWidth = 0; foreach ($blocks as $block) { $lines[] = ''; $lineWidth = 0; foreach ($block as $word) { if ($lineWidth + $wordWidths[$wordIndex] > $maxWidth && $lines[count($lines) - 1] != '') { $lines[] = ''; $lineWidth = 0; } $lines[count($lines) - 1] .= $word . ' '; $lineWidth += $wordWidths[$wordIndex] + $space; if ($lineWidth - $space > $maxLineWidth) { $maxLineWidth = $lineWidth - $space; } ++$wordIndex; } } $min = min(count($lines) * $lineHeight, $maxLineWidth); $max = max(count($lines) * $lineHeight, $maxLineWidth); $ratio = $min / $max; if ($ratio > $maxRatio) { $result = $lines; $maxRatio = $ratio; } } $y = $this->image->getSize()->getHeight() / 2 - $lineHeight * (count($result) / 2) + 4; foreach ($result as $line) { $box = $font->box(trim($line)); $this->image->draw()->text(trim($line), $font, new Point($this->image->getSize()->getWidth() / 2 - $box->getWidth() / 2, $y)); $y += $lineHeight; } }
/** * Use Imagine to resize an image and return it's new path * * @param string $originalImage * @param array $arguments * @param array $imageOptions * * @return void * * @throws ErrorException */ public function doFilter($originalImage, $arguments, $imageOptions) { // Need at least a height or a width if (empty($arguments['height']) && empty($arguments['width'])) { throw new ErrorException('You must set at least the height (h) or the width (w)'); } switch (strtolower($imageOptions['imageProcessor'])) { case 'gd': $Imagine = new \Imagine\Gd\Imagine(); break; case 'imagick': $Imagine = new \Imagine\Imagick\Imagine(); break; case 'gmagick': $Imagine = new \Imagine\Gmagick\Imagine(); break; default: throw new ErrorException('Unsupported imageProcessor config value: ' . $imageOptions['imageProcessor']); } $image = $Imagine->open($originalImage); $size = $image->getSize(); $originalWidth = $size->getWidth(); $originalHeight = $size->getHeight(); $width = $originalWidth; $height = $originalHeight; if (!empty($arguments['height'])) { if ($originalHeight > $arguments['height'] || $arguments['stretch']) { $height = $arguments['height']; } } if (!empty($arguments['width'])) { if ($originalWidth > $arguments['width'] || $arguments['stretch']) { $width = $arguments['width']; } } /** * Prevent from someone from creating huge images */ if ($width > $imageOptions['maxAllowedResizeWidth']) { $width = $imageOptions['maxAllowedResizeWidth']; } if ($height > $imageOptions['maxAllowedResizeHeight']) { $height = $imageOptions['maxAllowedResizeHeight']; } $mode = $arguments['exact'] ? ImageInterface::THUMBNAIL_OUTBOUND : ImageInterface::THUMBNAIL_INSET; $newSize = new Box($width, $height); $newImage = $image->thumbnail($newSize, $mode); if ($arguments['fill']) { $adjustedSize = $newImage->getSize(); $canvasWidth = isset($arguments['width']) ? $arguments['width'] : $adjustedSize->getWidth(); $canvasHeight = isset($arguments['height']) ? $arguments['height'] : $adjustedSize->getHeight(); /** * Prevent from someone from creating huge images */ if ($canvasWidth > $imageOptions['maxAllowedResizeWidth']) { $canvasWidth = $imageOptions['maxAllowedResizeWidth']; } if ($canvasHeight > $imageOptions['maxAllowedResizeHeight']) { $canvasHeight = $imageOptions['maxAllowedResizeHeight']; } $palette = new RGB(); $canvas = $Imagine->create(new Box($canvasWidth, $canvasHeight), $palette->color($arguments['fillColour'])); // Put image in the middle of the canvas $newImage = $canvas->paste($newImage, new Point((int) (($canvasWidth - $adjustedSize->getWidth()) / 2), (int) (($canvasHeight - $adjustedSize->getHeight()) / 2))); } $newImage->save($originalImage, array('jpeg_quality' => $arguments['quality'])); }
/** * * @param int $fontSize * @param int $angle * @param string $fontFace * @param string $string * @param int $width * @return array */ protected static function wrap(ImagineInterface $imagine, $fontSize, $angle, $fontFace, $string, $width) { static $palette; if (null === $palette) { $palette = new RGB(); } // str 'Op' used to calculate linespace $font = $imagine->font($fontFace, $fontSize, $palette->color("000000", 0)); $testbox = $font->box("0p", $angle); $height = $testbox->getHeight(); $testbox = $font->box("M", $angle); // 1 em $dy = $testbox->getHeight(); $toth = 0; $ret = []; foreach (explode("\n", $string) as $lig) { if ($lig == '') { $ret[] = ['w' => 0, 'h' => $dy, 't' => '']; $toth += $dy; } else { $twords = []; $iword = -1; $lastc = ''; $length = strlen($lig); for ($i = 0; $i < $length; $i++) { $c = $lig[$i]; if ($iword == -1 || ctype_space($c) && !ctype_space($lastc)) { $twords[++$iword] = [$part = 0 => '', 1 => '']; } if (!ctype_space($c) && $part == 0) { $part++; } $twords[$iword][$part] .= $lastc = $c; } if ($iword >= 0 && $twords[0][1] != '') { $buff = ''; $lastw = $lasth = 0; foreach ($twords as $i => $wrd) { $test = $buff . $wrd[0] . $wrd[1]; $testbox = $font->box($test, $angle); $w = $testbox->getWidth(); $h = $testbox->getHeight(); if ($i > 0 && $testbox->getWidth() > $width) { $ret[] = ['w' => $lastw, 'h' => $lasth, 't' => $buff]; $toth += $lasth; $buff = $wrd[1]; } else { $buff = $test; } $lastw = $w; $lasth = $h; } if ($buff != '') { $ret[] = ['w' => $lastw, 'h' => $lasth, 't' => $buff]; $toth += $lasth; } } } } return ['toth' => $toth, 'l' => $ret, 'h' => $height, 'dy' => $dy]; }
/** * Text to image * * @param string $text * @param array $options * @return \Imagine\Gd\Image|\Imagine\Image\ImageInterface */ public function textToImage($text, array $options = array()) { $options = array_merge(['align' => self::ALIGN_LEFT, 'size' => 20, 'font' => null, 'vertical' => false, 'padding_top' => null, 'padding_bottom' => null, 'padding_left' => null, 'padding_right' => null, 'line_height' => null], $options); $imagine = new Imagine(); $palette = new RGB(); $white = $palette->color('FFF'); $black = $palette->color('000'); $fontFile = $options['font'] ? $options['font'] : $this->getFont(); $font = new Font($fontFile, $options['size'], $black); $textBox = $font->box('我'); $textWidth = $textBox->getWidth(); $textHeight = $textBox->getHeight(); $paddingTop = $options['padding_top'] ? $options['padding_top'] : $textHeight / 2; $paddingBottom = $options['padding_bottom'] ? $options['padding_bottom'] : $textHeight / 2; $paddingLeft = $options['padding_bottom'] ? $options['padding_bottom'] : $textWidth / 2; $paddingRight = $options['padding_bottom'] ? $options['padding_bottom'] : $textWidth / 2; if ($options['vertical']) { $textBox = $font->box($text); $canvasWidth = $textBox->getWidth() + $paddingLeft + $paddingRight; $canvasHeight = $textBox->getHeight() + $paddingTop + $paddingBottom; $textCanvas = $imagine->create(new Box($canvasWidth, $canvasHeight), $white); $textCanvas->draw()->text($text, $font, new Point($paddingLeft, $paddingTop)); $textCanvas->rotate(90); $newHeight = $textCanvas->getSize()->getHeight(); $canvas = $imagine->create(new Box(self::CONTENT_MAX_WIDTH, $newHeight)); $canvas->paste($textCanvas, new Point((self::CONTENT_MAX_WIDTH - $textCanvas->getSize()->getWidth()) / 2, 0)); } else { $maxWidth = self::CONTENT_MAX_WIDTH - $paddingLeft - $paddingRight; $lines = $this->stringToMultipleLines($text, $font, $maxWidth); $lineCount = count($lines); $lineHeight = $options['line_height'] ? $options['line_height'] : $textHeight / 2; $canvasHeight = $paddingTop + $paddingBottom + $textHeight * $lineCount + $lineHeight * ($lineCount - 1); $canvas = $imagine->create(new Box(self::CONTENT_MAX_WIDTH, $canvasHeight)); $y = $paddingTop; foreach ($lines as $index => $line) { try { $width = $font->box($line)->getWidth(); } catch (\Imagine\Exception\InvalidArgumentException $e) { $width = $textBox->getWidth(); } switch ($options['align']) { case self::ALIGN_RIGHT: $x = $maxWidth - $width - $paddingLeft; break; case self::ALIGN_CENTER: $x = (self::CONTENT_MAX_WIDTH - $width) / 2; break; default: $x = $paddingLeft; break; } $x = $x < 0 ? 0 : $x; $point = new Point($x, $y); $canvas->draw()->text($line, $font, $point); if ($index + 1 < $lineCount) { $y += $textHeight + $lineHeight; } } } return $canvas; }
/** * Command image resize * * @param string $text * @param string $backgroundColor * @param string $color * @param int $width * @param int $height * * @return void */ protected function image404($text, $backgroundColor, $color, $width, $height) { $text = (string) $text; $backgroundColor = (string) $backgroundColor; $color = (string) $color; $width = (int) $width; $height = (int) $height; if (strlen($backgroundColor) != 6 || !preg_match('![0-9abcdef]!i', $backgroundColor)) { $backgroundColor = 'F8F8F8'; } if (strlen($color) != 6 || !preg_match('![0-9abcdef]!i', $color)) { $color = '777777'; } if ($width <= 0) { $width = 100; } if ($height <= 0) { $height = 100; } $palette = new RGB(); $size = new Box($width, $height); $this->image = $this->getImagineService()->create($size, $palette->color('#' . $backgroundColor, 0)); if ($text) { $this->drawCenteredText($text, $color); } }