Есть ли способ сделать изображение с тенью текста в PHP с GD?

Я сделал инструмент, в котором пользователь будет печатать текст & скрипт создаст изображение этого текста, но, получив проблему с тенью текста, я хочу сделать изображение с тенью текста, но библиотеку ГБ shadowImage Функция только разместить тень изображения, а не для текста,

Вот изображение, которое я получил сейчас

введите описание изображения здесь

Но я так хочу

введите описание изображения здесь

Кто-нибудь знает, как я могу создать такой образ?

вот мой метод, который я использовал для его создания,

public function render()
{
$this->_image = new Imagick;

if(!$this->text)
{
$this->_image->newImage(1, 1, 'white');
return;
}

$draw = new ImagickDraw();
$color = new ImagickPixel($this->color);
$background = new ImagickPixel($this->surfaceColor);

/* Font properties */
$draw->setStrokeAntialias(true);
$draw->setTextAntialias(true);
$draw->setFontSize($this->fontSize);
$draw->setFillColor($color);
$draw->setFont(Model_Tool_Font::find($this->font_id)->getFontPath($this->bold, $this->italic));

/* Border ? */
if ($this->borderWidth)
{
$draw->setStrokeColor($this->borderColor);
$draw->setStrokeWidth($this->borderWidth * $this->fontSize * self::BORDER_WIDTH_MULTIPLIER );
}

/* Get font metrics */
$metrics = $this->_image->queryFontMetrics($draw, $this->text);
/* Sizing calculations */
$width  = $metrics['textWidth'];
$height = $metrics['textHeight'];
//respect custom proportions
if(!$this->maintainProportions  &&  $this->customHeight > 0  &&  $this->customWidth > 0)
{
//stretching is better than shrinking (possibly for quality)
//size limits should be used to constrain size

$aspect = $this->customWidth / $this->customHeight;
if($this->customHeight / $height  >  $this->customWidth / $width)
$height = $width / $aspect;
else
$width = $height * $aspect;
}

$this->_limitSize($width, $height);
/* Sizing calculations end */
//appears to result in bigger image than before sizing?
if($height > $this->fontSize)
{
//update the metrics
$draw->setFontSize($this->fontSize = $height);
$metrics = $this->_image->queryFontMetrics($draw, $this->text);
}

/* Create text */
$draw->annotation(0, $metrics['ascender'], $this->text);

/* Create image */
$this->_image->newImage($metrics['textWidth'], $metrics['textHeight'], $background);
$this->_image->drawImage($draw);

if ($this->reverseCut == 1) {
$this->_image->flopImage();
}

/* Shadow */
if ($this->shadowOffset)
{
$this->shadowOffset = abs((int)$this->shadowOffset);
$x = $y = 0;
switch($this->shadowOrient)
{
case self::ORIENT_TOP:
$x =  0;
$y = -3 - ($this->shadowOffset);
break;
case self::ORIENT_TOPRIGHT:
$x = 2 + ($this->shadowOffset);
$y = -3 - ($this->shadowOffset);
break;
case self::ORIENT_RIGHT:
$x = 2 + ($this->shadowOffset);
$y = 0;
break;
case self::ORIENT_BOTTOMRIGHT:
$x = 2 + ($this->shadowOffset);
$y = 2 + ($this->shadowOffset);
break;
case self::ORIENT_BOTTOM:
$x = 0;
$y = 2 + ($this->shadowOffset);
break;
case self::ORIENT_BOTTOMLEFT:
$x = -2 - ($this->shadowOffset);
$y = 2 + ($this->shadowOffset);
break;
case self::ORIENT_LEFT:
$x = -3 - ($this->shadowOffset);
$y = 0;
break;
case self::ORIENT_TOPLEFT:
$x = -3 - ($this->shadowOffset);
$y = -3 - ($this->shadowOffset);
break;
}

//transform logical sizes into pixels
$r = $this->fontSize * self::BORDER_WIDTH_MULTIPLIER;
$x *= $r;
$y *= $r;

$shadow = clone $this->_image;
$shadow->setImageBackgroundColor( new ImagickPixel( $this->shadowColor ) );
$shadow->shadowImage( 96, 0.5, 0, 0);
if($x || $y) {
$geo = $this->_image->getImageGeometry();
$currentImage = $this->_image->getImage();
$this->_image->newImage($geo['width'] + abs($x), $geo['height'] + abs($y), 'none');

$shift_x = $shift_y = 0;

if($x < 0) {
$shift_x = -$x;
$x = 0;
}

if($y < 0) {
$shift_y = -$y;
$y = 0;
}
$this->_image->compositeImage( $currentImage, Imagick::COMPOSITE_OVER , $shift_x, $shift_y);

}
$this->_image->compositeImage( $shadow, Imagick::COMPOSITE_DSTOVER , $x, $y);

}
$this->_image->resizeImage($width, $height, imagick::FILTER_LANCZOS, 0.9, $this->maintainProportions);

}

1

Решение

просто используйте Imagick :: annotateImage, чтобы нарисовать текст с цветом тени и смещением тени, затем снова нарисуйте текст в нужном вам месте. модифицированный код ниже скопирован из Руководство по php Imageick

<?php
/* Create some objects */
$image = new Imagick();
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'white' );

/* New image */
$image->newImage(800, 75, $pixel);/* Font properties */
$draw->setFont('Bookman-DemiItalic');
$draw->setFontSize( 30 );

$offset_x = 3;
$offset_y = 3;

/* Black shadow */
$draw->setFillColor('black');
/* Create text */
$image->annotateImage($draw, 10+$offset_x, 45+$offset_y, 0, 'The quick brown fox jumps over the lazy dog');

/* Yellow Test */
$draw->setFillColor('yellow');
/* Create text */
$image->annotateImage($draw, 10, 45, 0, 'The quick brown fox jumps over the lazy dog');

/* Give image a format */
$image->setImageFormat('png');

/* Output the image with headers */
header('Content-type: image/png');
echo $image;

?>
2

Другие решения

Вы можете получить ссылку здесь [GitHub Repository]. Код воспроизводится как ниже

/*
* imagettftextblur v1.0.0
*
* Copyright (c) 2013 Andrew G. Johnson  <[email protected]>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @author Andrew G. Johnson <[email protected]>
* @copyright Copyright (c) 2013 Andrew G. Johnson <[email protected]>
* @link http://github.com/andrewgjohnson/imagettftextblur
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @version 1.0.0
* @package imagettftextblur
*
*/

if (!function_exists('imagettftextblur'))
{
function imagettftextblur(&$image,$size,$angle,$x,$y,$color,$fontfile,$text,$blur_intensity = null)
{
$blur_intensity = !is_null($blur_intensity) && is_numeric($blur_intensity) ? (int)$blur_intensity : 0;
if ($blur_intensity > 0)
{
$text_shadow_image = imagecreatetruecolor(imagesx($image),imagesy($image));
imagefill($text_shadow_image,0,0,imagecolorallocate($text_shadow_image,0x00,0x00,0x00));
imagettftext($text_shadow_image,$size,$angle,$x,$y,imagecolorallocate($text_shadow_image,0xFF,0xFF,0xFF),$fontfile,$text);
for ($blur = 1;$blur <= $blur_intensity;$blur++)
imagefilter($text_shadow_image,IMG_FILTER_GAUSSIAN_BLUR);
for ($x_offset = 0;$x_offset < imagesx($text_shadow_image);$x_offset++)
{
for ($y_offset = 0;$y_offset < imagesy($text_shadow_image);$y_offset++)
{
$visibility = (imagecolorat($text_shadow_image,$x_offset,$y_offset) & 0xFF) / 255;
if ($visibility > 0)
imagesetpixel($image,$x_offset,$y_offset,imagecolorallocatealpha($image,($color >> 16) & 0xFF,($color >> 8) & 0xFF,$color & 0xFF,(1 - $visibility) * 127));
}
}
imagedestroy($text_shadow_image);
}
else
return imagettftext($image,$size,$angle,$x,$y,$color,$fontfile,$text);
}
}

Вот как добавить тень:

imagettftextblur($image,$size,0,$x + 3,$y + 3,$shadow_color,$font,$string,1); // 1 can be higher to increase blurriness of the shadow
imagettftextblur($image,$size,0,$x,$y,$text_color,$font,$string);
2

Нарисуйте текст дважды. Сначала нарисуйте теневой текст немного правее и ниже вашей текстовой позиции (без контура), затем нарисуйте ваш текст в соответствии с нормой.

2
По вопросам рекламы [email protected]