【问题标题】:Is there any way to make image with text shadow in PHP with GD?有什么方法可以在带有 GD 的 PHP 中制作带有文本阴影的图像吗?
【发布时间】:2016-05-02 22:32:52
【问题描述】:

我制作了一个工具,用户可以在其中输入文本,脚本会生成该文本的图像,但是遇到文本阴影问题,我想使用文本阴影制作图像,但 GB 库 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);

}

【问题讨论】:

  • 在打印带有黄色边框的文本之前打印相同的文本,但没有黄色边框并稍微向右和向下移动。
  • 非常感谢您的评论,您能否为我分享任何代码示例,以便我明白您的意思,如果您想展示我的代码,那么我想在这里分享我的功能。跨度>
  • 是的,使用您已有的代码会更容易。
  • 我已经编辑了问题并添加了我对图像进行分级的方法。
  • @KubaWyrostek 有什么可以帮助我的吗?

标签: php image gd imagick drawimage


【解决方案1】:

将文本绘制两次。首先在文本位置的右侧和下方绘制阴影文本(没有轮廓),然后按照正常方式绘制文本。

【讨论】:

    【解决方案2】:

    您可以从这里获得参考[GitHub Repository]。代码复制如下

    /*
     * imagettftextblur v1.0.0
     *
     * Copyright (c) 2013 Andrew G. Johnson  <andrew@andrewgjohnson.com>
     * 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 <andrew@andrewgjohnson.com>
     * @copyright Copyright (c) 2013 Andrew G. Johnson <andrew@andrewgjohnson.com>
     * @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);
    

    【讨论】:

    • 我已经尝试过了,但是如果您查看它,您会发现此功能适用于图像我担心的是我需要从带有文本阴影的文本创建图像,如果您查看我在我的问题中的方法,我使用文本来创建图像&在该文本上我需要文本阴影,但上述函数将在图像上生成阴影,而不是在图像中的文本上。
    【解决方案3】:

    只需使用 Imagick::annotateImage 绘制带有阴影颜色和阴影偏移的文本,然后在所需位置再次绘制文本。下面的修改代码复制自php Imageick manual

    <?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;
    
    ?>
    

    【讨论】:

      猜你喜欢
      • 2015-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多