Created
September 28, 2018 13:59
-
-
Save kcassam/766052cd7f6431e49fb13577eca60436 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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