Skip to content

Instantly share code, notes, and snippets.

@kcassam
Created September 28, 2018 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kcassam/766052cd7f6431e49fb13577eca60436 to your computer and use it in GitHub Desktop.
Save kcassam/766052cd7f6431e49fb13577eca60436 to your computer and use it in GitHub Desktop.
<?php
namespace Headoo\CoreBundle\Helper;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
/**
* Class TxtToImage
* About: TxtToImage transformer with GD 2
* @package St\AppBundle\Service
*/
class TxtToImageHelper
{
// best 100
const QUALITY = 100;
// range 0 (best) to 9 (worst)
const COMPRESSION_QUALITY = 0;
const FONTS_PATH = '/var/www/headoo/web/fonts';
const OUTPUT_PATH = '/var/www/headoo/app/cache/image';
public function __construct()
{
}
/**
* @param $width
* @param $height
* @param $extension
* @param $fontSize
* @param $fontFamily
* @param $fontColor
* @param $posX
* @param $posY
* @param $textWidth
* @param $textHeight
* @param null $backgroundColor
* @param null $backgroundImage
* @param bool|false $imageMosaic
* @param bool|false $alphaBlending
* @param $text
* @throws \Exception
* @return string
*/
public function transformTextToImage(
$width,
$height,
$extension,
$fontSize,
$fontFamily,
$fontColor,
$posX,
$posY,
$textWidth,
$textHeight,
$backgroundColor = null,
$backgroundImage = null,
$imageMosaic = false,
$alphaBlending = false,
$text
) {
// beware !!! fonts_path like this => '/var/www/sources/developpeur-php-symfony2.com/web/fonts'
$fontPath = static::FONTS_PATH;
$outputPath = static::OUTPUT_PATH;
if(!is_dir($outputPath))
{
mkdir('output');
}
if(!is_writeable($outputPath))
{
throw new \Exception('Write path is not writable');
}
if (extension_loaded('gd') && function_exists('gd_info')) {
// create image
$im = imagecreatetruecolor($width, $height);
if (strpos($extension, ".") !== false) {
throw new \Exception('Please remove dot from extension parameter !');
}
switch ($extension) {
case "png":
$methodCreate = 'imagecreatefrompng';
$methodExport = 'imagepng';
$contentType = 'image/png';
break;
case "gif":
$methodCreate = 'imagecreatefromgif';
$methodExport = 'imagegif';
$contentType = 'image/gif';
break;
default:
$methodCreate = 'imagecreatefromjpeg';
$methodExport = 'imagejpeg';
$contentType = 'image/jpeg';
}
$quality = static::QUALITY;
// transform hex to rgb
$fontColor = $this->hex2rgb($im, $fontColor);
// check if font exist
if(!file_exists($fontPath.'/'.$fontFamily))
{
throw new ResourceNotFoundException('the font is not available or readable !');
}
if ($backgroundImage && file_exists($backgroundImage)) {
if($imageMosaic)
{
$pattern = $methodCreate($backgroundImage);
$patternWidth = imagesx($pattern);
$patternHeight = imagesy($pattern);
if($patternWidth >= $width)
{
throw new \Exception('Beware that $width must be greater than width background image for mosaic !');
}
if($patternHeight >= $height)
{
throw new \Exception('Beware that $height must be greater than height background image for mosaic !');
}
if ($extension == 'png' || $extension == 'gif') {
if ($extension == 'png') {
$quality = static::COMPRESSION_QUALITY;
}
$transparent = imagecolorallocatealpha($pattern, 0, 0, 0, 127);
imagefill($pattern, 0, 0, $transparent);
imagesavealpha($pattern, true);
}
// pattern repeat for mosaic
if ($patternWidth < $width || $patternHeight < $height) {
for ($patternX = 0; $patternX < $width; $patternX += $patternWidth) {
for ($patternY = 0; $patternY < $height; $patternY += $patternHeight) {
imagecopy($im, $pattern, $patternX, $patternY, 0, 0, $patternWidth, $patternHeight);
}
}
} else {
imagecopy($im, $pattern, 0, 0, 0, 0, $patternWidth, $patternHeight);
}
}else{
// no mosaic
$imgSource = $methodCreate($backgroundImage);
imagecopy($im, $imgSource, 0, 0, 0, 0, $width, $height);
}
}else{
// just background color, no image for output
$backgroundColor = $this->hex2rgb($im, $backgroundColor);
imagefill($im, 0, 0, $backgroundColor);
}
if ($extension !== 'gif') {
$black = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $black);
}
// alpha blending and save alpha for output
if ($extension == 'png' || $extension == 'gif') {
if ($extension == 'png') {
$quality = static::COMPRESSION_QUALITY;
}
imagealphablending($im, $alphaBlending);
imagesavealpha($im, true);
}
// explode text to multi lines
$text_a = explode(' ', $text);
$text_new = '';
foreach ($text_a as $word) {
$box = imagettfbbox($fontSize, 0, $fontPath . '/' . $fontFamily, $text_new . ' ' . $word);
if ($box[2] > $textWidth) {
$text_new .= "\n" . $word;
} else {
$text_new .= " " . $word;
}
}
$maxX = $width - $textWidth;
$maxY = $height - $textHeight;
if ($posX > $maxX) {
throw new \Exception('textWidth can\'t be greater than ' . $maxX);
}
if ($posY > $maxY) {
throw new \Exception('textHeight can\'t be greater than ' . $maxY);
}
// add text layer to image
imagettftext($im, $fontSize, 0, $posX, $posY + $fontSize, $fontColor, $fontPath . '/' . $fontFamily, trim($text_new));
// header('Content-Type: ' . $contentType); /* todo remove*/
// output result image
if ($im) {
$fileName = $outputPath . '/' . md5($backgroundImage . date('Y-m-d H:i:s') . $fontFamily . $width . $height) . '.' . $extension;
// $fileName = null;/* todo remove*/
$methodExport($im, $fileName, $quality);
imagedestroy($im);
}
} else {
throw new ResourceNotFoundException('GD library is not installed !');
}
return $fileName;
}
/**
* @param $im
* @param $hex
* @return int
*/
protected function hex2rgb($im, $hex)
{
$hex = str_replace("#", "", $hex);
if (strlen($hex) == 3) {
$r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1));
$g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1));
$b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1));
} else {
$r = hexdec(substr($hex, 0, 2));
$g = hexdec(substr($hex, 2, 2));
$b = hexdec(substr($hex, 4, 2));
}
return imagecolorallocate($im, $r, $g, $b);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment