Skip to content

Commit

Permalink
TASK: Extract renderShape and renderText method and create imagine vi…
Browse files Browse the repository at this point in the history
…a Objects.yaml
  • Loading branch information
mficzel committed Jul 16, 2018
1 parent f5a5511 commit 5698ff3
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 48 deletions.
123 changes: 75 additions & 48 deletions Classes/Controller/DummyImageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@
use Neos\Flow\Package\PackageManagerInterface;
use Neos\Flow\ResourceManagement\ResourceManager;
use Neos\Flow\Mvc\Controller\ActionController;
use Neos\Imagine\ImagineFactory;

use Imagine\Image\ImagineInterface;
use Imagine\Image\ImageInterface;
use Imagine\Image\Palette\Color\ColorInterface;
use Imagine\Image\Palette;
use Imagine\Image\Box;
use Imagine\Image\Point;

class DummyImageController extends ActionController
{
/**
* @var ImagineFactory
* @var ImagineInterface
* @Flow\Inject
*/
protected $imagineFactory;
protected $imagineService;

/**
* @var ResourceManager
Expand Down Expand Up @@ -56,88 +58,113 @@ public function imageAction (int $width = 600, int $height = 400, string $backgr
}

// create imagine
$imagine = $this->imagineFactory->create();
$palette = new Palette\RGB();
$bgColor = $palette->color($backgroundColor);
$textColor = $palette->color($foregroundColor);

// create image
$imageBox = new Box($width, $height);
$image = $imagine->create($imageBox, $bgColor);
$image = $this->imagineService->create($imageBox, $bgColor);

// render shape
$this->renderShape($image, $textColor, $width, $height);

// render text
if ($text) {
$this->renderText($image, $textColor, $width, $height, $text);
}

// build result
$this->response->setHeader( 'Cache-Control', 'max-age=883000000');
$this->response->setHeader( 'Content-type', 'image/png');
return $image->get('png');
}

/**
* @param ImageInterface $image
* @param ColorInterface $color
* @param int $width
* @param int $height
*/
protected function renderShape(ImageInterface $image, ColorInterface $color, int $width, int $height): void
{
$imageAspectRatio = $width / $height;
$baseShapeWidth = 600;
$baseShapeHeight = 400;
$baseShapeAspectRatio = $baseShapeWidth / $baseShapeHeight;

$baseShape = [
new Point(15,250), // left ground
new Point(15,15), // left top
new Point(585,15), // right top
new Point(585,250), // right ground
new Point(580,250),
new Point(15, 250), // left ground
new Point(15, 15), // left top
new Point(585, 15), // right top
new Point(585, 250), // right ground
new Point(580, 250),

new Point(440,110), // small mountain
new Point(360,190), // saddle
new Point(220,50), // big mountain
new Point(440, 110), // small mountain
new Point(360, 190), // saddle
new Point(220, 50), // big mountain

new Point(20,250),
new Point(20, 250),
];

// transform shape to center of the image
$factor = ($imageAspectRatio > $baseShapeAspectRatio) ? (float)$height / (float)$baseShapeHeight : (float)$width / (float)$baseShapeWidth;
$xoffset = ($imageAspectRatio > $baseShapeAspectRatio) ? ($width - ($baseShapeWidth * $factor)) / 2.0 : 0.0;
$yoffset = ($imageAspectRatio < $baseShapeAspectRatio) ? ($height - ($baseShapeHeight * $factor)) / 2.0 : 0.0;

$transformedShape = array_map(
function(Point $point) use ($factor, $xoffset, $yoffset) {
return new Point( $point->getX() * $factor + $xoffset, $point->getY() * $factor + $yoffset);
function (Point $point) use ($factor, $xoffset, $yoffset) {
return new Point($point->getX() * $factor + $xoffset, $point->getY() * $factor + $yoffset);
},
$baseShape
);

if ($imageAspectRatio < $baseShapeAspectRatio) {
// adjust some points based on aspect ratio
if ($imageAspectRatio < $baseShapeAspectRatio) {
$transformedShape[1] = new Point($transformedShape[1]->getX(), $baseShape[1]->getY() * $factor);
$transformedShape[2] = new Point($transformedShape[2]->getX(), $baseShape[2]->getY() * $factor);
} else {
$transformedShape[0] = new Point($baseShape[0]->getX() * $factor , $transformedShape[0]->getY());
$transformedShape[0] = new Point($baseShape[0]->getX() * $factor, $transformedShape[0]->getY());
$transformedShape[1] = new Point($baseShape[0]->getX() * $factor, $transformedShape[1]->getY());
$transformedShape[2] = new Point($width - $baseShape[0]->getX() * $factor , $transformedShape[2]->getY());
$transformedShape[2] = new Point($width - $baseShape[0]->getX() * $factor, $transformedShape[2]->getY());
$transformedShape[3] = new Point($width - $baseShape[0]->getX() * $factor, $transformedShape[3]->getY());
}

// finally draw image
$image->draw()->polygon(
$transformedShape,
$textColor,
true ,
$color,
true,
1
);
}

// render text
if ($text) {
$initialFontSize = 10;
$fontFile = $this->packageManager->getPackage('Neos.Neos')->getPackagePath() . "Resources/Public/Fonts/NotoSans/NotoSans-Regular.ttf";
$initialFont = $imagine->font($fontFile, $initialFontSize, $textColor);

// scale text to fit the image
$initialFontBox = $initialFont->box($text);
$targetFontWidth = $width * .5;
$targetFontHeight = $height * .7;
$correctedFontSizeByWidth = $targetFontWidth * $initialFontSize / $initialFontBox->getWidth();
$correctedFontSizeByHeight = $targetFontHeight * $initialFontSize / $initialFontBox->getHeight();

// render actual text
$actualFont = $imagine->font($fontFile, min([$correctedFontSizeByWidth, $correctedFontSizeByHeight]), $textColor);
$actualFontBox = $actualFont->box($text);
$imageCenterPosition = new Point\Center($imageBox);
$textCenterPosition = new Point\Center($actualFontBox);
$centeredTextPosition = new Point($imageCenterPosition->getX() - $textCenterPosition->getX(), ($height * .73 - $actualFontBox->getHeight() *.5 ));
$image->draw()->text($text, $actualFont, $centeredTextPosition);
}

// build result
$this->response->setHeader( 'Cache-Control', 'max-age=883000000');
$this->response->setHeader( 'Content-type', 'image/png');
return $image->get('png');
/**
* @param ImageInterface $image
* @param ColorInterface $textColor
* @param int $width
* @param int $height
* @param string $text
*/
protected function renderText(ImageInterface $image, ColorInterface $textColor, int $width, int $height, string $text): void
{
$initialFontSize = 10;
$fontFile = $this->packageManager->getPackage('Neos.Neos')->getPackagePath() . "Resources/Public/Fonts/NotoSans/NotoSans-Regular.ttf";
$initialFont = $this->imagineService->font($fontFile, $initialFontSize, $textColor);

// scale text to fit the image
$initialFontBox = $initialFont->box($text);
$targetFontWidth = $width * .5;
$targetFontHeight = $height * .3;
$correctedFontSizeByWidth = $targetFontWidth * $initialFontSize / $initialFontBox->getWidth();
$correctedFontSizeByHeight = $targetFontHeight * $initialFontSize / $initialFontBox->getHeight();

// render actual text
$actualFont = $this->imagineService->font($fontFile, min([$correctedFontSizeByWidth, $correctedFontSizeByHeight]), $textColor);
$actualFontBox = $actualFont->box($text);
$imageCenterPosition = new Point($width / 2 , $height / 2);
$textCenterPosition = new Point\Center($actualFontBox);
$centeredTextPosition = new Point($imageCenterPosition->getX() - $textCenterPosition->getX(), ($height * .73 - $actualFontBox->getHeight() * .5));
$image->draw()->text($text, $actualFont, $centeredTextPosition);
}

}
5 changes: 5 additions & 0 deletions Configuration/Objects.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Sitegeist\Kaleidoscope\Controller\DummyImageController:
properties:
imagineService:
object:
factoryObjectName: Neos\Imagine\ImagineFactory

0 comments on commit 5698ff3

Please sign in to comment.