Solved

Using GD to add text over image with drop shadow blur

Posted on 2010-11-10
12
6,018 Views
Last Modified: 2013-04-01
I have a 24-bit png file that I need to overlay a text with a drop shadow.
The drop shadow is a copy of the text with an offset and Gaussian blur.

I need help getting this to work.

I attached an example image and existing code.
<?php

/* 24-bit PNG source image */
$src_image = 'image.png';

/* create new image from source image */
$im_base = @imagecreatefrompng($src_image);
$width = imagesx($im_base);
$height = imagesy($im_base);

/*
$drop_shadow = imagecreatetruecolor($width, $height);

$black = imagecolorallocate($drop_shadow, 0, 0, 0);
imagecolortransparent($drop_shadow, $black);
*/

/* 
$transparent = imagecolorallocatealpha($img, 0,0,0, 127); 
*/

/* alpha blending on 
imagealphablending($drop_shadow, true);*/

/* save alphablending setting 
imagesavealpha($drop_shadow, false); */



/* drop shadow text 
$font = 'Banty.ttf';
$fontSize = 70; // points
$fontRotation = 0; //  0 degrees
$fontX = -5; // pixels
$fontY = 75; // pixels
$fontColor = imagecolorallocate($drop_shadow, 0xD6, 0xD6, 0xD6); // hex or RGB
$text = "Test";
*/

/* add text to image 
imagettftext($drop_shadow, $fontSize, $fontRotation, $fontX, $fontY, $fontColor, $font, $text);
*/

/* add blur shadow 
imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
*/

/*
imagecopymerge($im, $drop_shadow, 50, 50, 50, 50, $width, $height, 100);
imagecopyresampled($im, $drop_shadow, 0, 0, 0, 0, $width, $height, $width, $height);
*/

/* customize the text 
$font = 'Banty.ttf';
$fontSize = 70; // points
$fontRotation = 0; //  0 degrees
$fontX = 1; // pixels
$fontY = 70; // pixels
$color = imagecolorallocate($im, 0xFF, 0xFF, 0xFF); // hex or RGB
$text = "Test";
*/

/* add text to image 
@imagettftext($im_base, $fontSize, $fontRotation, $fontX, $fontY, $color, $font, $text);
*/


/* output image */
header('Content-type: image/png');
@imagepng($im_base);
/* empty the buffer */
@imagedestroy($im_base);

?>

Open in new window

image.png
0
Comment
Question by:ray-solomon
  • 6
  • 4
  • 2
12 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34112170
Maybe it is not working because large segments of the code are commented out?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34112696
Have a look at this script and see if it helps.
http://www.laprbass.com/RAY_imagepng_drop_shadow.php?sr=34&sb=34&sg=139
<?php // RAY_imagepng_drop_shadow.php

error_reporting(E_ALL);





// DEMONSTRATE HOW TO WRITE TEXT WITH A DROP SHADOW IN A PNG IMAGE





// GET SOME TEXT

$string = isset($_GET["t"]) ? $_GET["t"] : 'Hello World!';



// SETTINGS FOR THE BACKGROUND COLOR (DEFAULT WHITE)

$rgb_br = isset($_GET["br"]) ? $_GET["br"] : 255;

$rgb_bg = isset($_GET["bg"]) ? $_GET["bg"] : 255;

$rgb_bb = isset($_GET["bb"]) ? $_GET["bb"] : 255;



// SETTINGS FOR THE TEXT (DEFAULT GREENISH)

$rgb_tr = isset($_GET["tr"]) ? $_GET["tr"] :  34;

$rgb_tg = isset($_GET["tg"]) ? $_GET["tg"] : 139;

$rgb_tb = isset($_GET["tb"]) ? $_GET["tb"] :  34;



// SETTINGS FOR THE DROP SHADOW (DEFAULT BLACK)

$rgb_sr = isset($_GET["sr"]) ? $_GET["sr"] :   0;

$rgb_sg = isset($_GET["sg"]) ? $_GET["sg"] :   0;

$rgb_sb = isset($_GET["sb"]) ? $_GET["sb"] :   0;



// SETTING FOR SHADOW TRANSPARENCY / INTENSITY

$dense  = isset($_GET["d"])  ? $_GET["d"]  :  90;



// A FONT: KRISTEN

$font = 'itckrist.ttf';



// IMAGE RESOURCE DIMENSIONS

$wide   = 200;

$high   = 60;



// LOCATION OF THE TEXT

$x_off  = 25;

$y_off  = 25;



// SIZE AND ANGLE OF THE TEXT

$size   = 20;

$angle  = 0;







// CREATE THE IMAGE RESOURCE

$im     = ImageCreateTrueColor($wide, $high);



// SET COLORS: MAN PAGE http://us.php.net/manual/en/function.imagecolorallocatealpha.php

$bgcolor = ImageColorAllocateAlpha($im, $rgb_br, $rgb_bg, $rgb_bb, 0);

$shadow  = ImageColorAllocateAlpha($im, $rgb_sr, $rgb_sg, $rgb_sb, $dense);

$text    = ImageColorAllocateAlpha($im, $rgb_tr, $rgb_tg, $rgb_tb, 0);



// FILL THE BACKGROUND: MAN PAGE http://us.php.net/manual/en/function.imagefilledrectangle.php

ImageFilledRectangle($im, 0, 0, $wide, $high, $bgcolor);



// MAN PAGE http://us.php.net/manual/en/function.imagealphablending.php

ImageAlphaBlending($im, TRUE);



// MAN PAGE http://us.php.net/manual/en/function.imagesavealpha.php

ImageSaveAlpha($im, TRUE);



// SHADOW FIRST TO CREATE THE BLUR: MAN PAGE http://us.php.net/manual/en/function.imagettftext.php

ImageTTFtext($im, $size, $angle, $x_off, $y_off+5, $shadow, $font, $string);



// BLUR BY APPROXIMATIONS: MAN PAGE http://us.php.net/manual/en/function.imagefilter.php

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);



// MORE SHADOW AND SOME BLUR

ImageTTFtext($im, $size, $angle, $x_off, $y_off+3, $shadow, $font, $string);

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);



// MORE SHADOW AND LESS BLUR

ImageTTFtext($im, $size, $angle, $x_off, $y_off+1, $shadow, $font, $string);

ImageFilter($im, IMG_FILTER_GAUSSIAN_BLUR);



// THEN TEXT

imagettftext($im, $size, $angle, $x_off, $y_off,   $text,   $font, $string);



// PRODUCE A PNG IMAGE

header('Content-type: image/png');

ImagePNG($im);

ImageDestroy($im);

Open in new window

0
 
LVL 10

Author Comment

by:ray-solomon
ID: 34113190
Hi Ray, thank you for helping.

Question.

I need the text and drop shadow to go over a background image without blurring the background image. That is the issue that hung me up. Is this possible?

Currently you are using ImageFilledRectangle(), but it needs to be an existing png image instead. This is my problem.

After many code revisions, I just gave you code bits which did not work because I was tired and frustrated. At some point before I requested help, I had it almost working, but gave up because I could not get rid of the black background behind the shadow text. I just needed to get it to be transparent. I spend all day reading the php manual on every GD image function that could help and of course google as well.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34113482
Thanks for clarifying that.  Let me look at it again.  Back in a while...
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34114199
Just so you know I haven't forgotten this Q,...

I am running into difficulties preserving the transparency after using the Gaussian blur.  I may have to try a different strategy.
0
 
LVL 33

Expert Comment

by:Slick812
ID: 34114788
greetings ray-solomon, , as already noted, the Gaussian blur is a very additive alpha-blend factor and I did not like trying to work wid it, you seem to want blurred edges shadows, you might try my code below, to see if it get any effect as you need, , I did not blur the shadows, bot use the "transpaency" and drew two more shadows, offset from the main one, with more transparency, to give a blurred edge effect. . .
you seem to have some experience wid GD functions, so I did not comment heavily. . . I you have questions, be sure to ask, and tell us if this gives anything like you need for your effect.
<?php

$src_image = 'images3/spaco.jpg';

$im_base = imagecreatefromjpeg($src_image);
$w = imagesx($im_base);
$h = imagesy($im_base);


$drop_shadow = imagecreatetruecolor($w, $h);

$imgColor = imagecolorallocatealpha($drop_shadow, 255,255,255, 127);// transparent

// to get the Background to be transparent you MUST cut OFF the alphablending
imagealphablending($drop_shadow, false);
imagefilledrectangle($drop_shadow, 0, 0, $w, $h, $imgColor);
// to get the text to be semi-transparent you MUST cut ON the alphablending
imagealphablending($drop_shadow, true);

$imgColor = imagecolorallocatealpha($drop_shadow, 97, 97, 97, 70);
//this first shadow text is the main shadow comoponent
imagettftext($drop_shadow, 70, 0, 12, 85, $imgColor, 'academ.ttf', 'Shadow Test');

//these two next shadow text are offset and "more transparent", giving the impression of "blurred" shadow edges
$imgColor = imagecolorallocatealpha($drop_shadow, 97, 97, 97, 100);
imagettftext($drop_shadow, 70, 0, 10, 83, $imgColor, 'academ.ttf', 'Shadow Test');
// remember these draws are additive to the first showdow draw
imagettftext($drop_shadow, 70, 0, 14, 87, $imgColor, 'academ.ttf', 'Shadow Test');


//imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
//imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
//imagefilter($drop_shadow, IMG_FILTER_GAUSSIAN_BLUR);
$imgColor = imagecolorallocatealpha($drop_shadow, 255, 255, 255, 0);// NO transparency
imagettftext($drop_shadow, 70, 0, 2, 78, $imgColor, 'academ.ttf', 'Shadow Test');


imagealphablending($im_base, true);

imagecopy($im_base, $drop_shadow, 0, 0, 0, 0, $w, $h);
imagesavealpha($im_base, true);
//header('Content-type: image/png');
@imagepng($im_base, 'images3/dshadow1.png');
@imagedestroy($im_base);
@imagedestroy($drop_shadow);

?>

// in my test page I show result with <img src="images3/dshadow1.png">

Open in new window

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 33

Expert Comment

by:Slick812
ID: 34114848
sorry, I just noticed, for smaller file size you may want to turn off the alpha save for the image-  $im_base


imagesavealpha($im_base, false);// does NOT need to be alpha transparent
@imagepng($im_base, 'images3/dshadow1.png');
0
 
LVL 10

Author Comment

by:ray-solomon
ID: 34114849
Maybe it will be easier if using a GIF instead of a PNG?
I can go either way as long as the drop shadow looks really good like the picture above.
0
 
LVL 10

Author Comment

by:ray-solomon
ID: 34114952
@Slick812 - good quick solution. However, I could have done that myself.
Is there no way to do Gaussian blur?

@Ray_Paseur - using a JPG works fine too as long as the text and drop shadow is transparent.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 34115434
This seems to produce a useful result.  

http://www.laprbass.com/RAY_imagepng_drop_shadow2.php

Best regards, ~Ray
<?php // RAY_imagepng_drop_shadow2.php

error_reporting(E_ALL);





// DEMONSTRATE HOW TO WRITE TEXT WITH A DROP SHADOW IN A PNG IMAGE





// GET SOME TEXT

$string = isset($_GET["t"]) ? $_GET["t"] : 'Hello World!';



// SETTINGS FOR THE TEXT (DEFAULT RED)

$rgb_tr = isset($_GET["tr"]) ? $_GET["tr"] : 255;

$rgb_tg = isset($_GET["tg"]) ? $_GET["tg"] :   1;

$rgb_tb = isset($_GET["tb"]) ? $_GET["tb"] :   1;



// SETTINGS FOR THE DROP SHADOW (DEFAULT = GRAY)

$rgb_sr = isset($_GET["sr"]) ? $_GET["sr"] :  64;

$rgb_sg = isset($_GET["sg"]) ? $_GET["sg"] :  64;

$rgb_sb = isset($_GET["sb"]) ? $_GET["sb"] :  64;



// SETTING FOR SHADOW TRANSPARENCY / INTENSITY

$dense  = isset($_GET["d"])  ? $_GET["d"]  :  60;



// SETTING FOR THE NUMBER OF DROP SHADOW LAYERS

$lcount = isset($_GET["n"])  ? $_GET["n"]  :  12;



// A FONT: KRISTEN

$font = 'itckrist.ttf';



// IMAGE RESOURCE DIMENSIONS

$wide   = 200;

$high   = 60;



// LOCATION OF THE TEXT

$x_off  = 25;

$y_off  = 25;



// SIZE AND ANGLE OF THE TEXT

$size   = 20;

$angle  = 0;



// GET AN IMAGE FROM THE LIBRARY

$doggie = ImageCreateFromPNG('RAY_temp_600x374.png');



// CREATE THE OVERLAY IMAGE RESOURCES

$x  = $lcount+1;

$im = array();

while ($x)

{

    $x--;

	$im[$x] = ImageCreateTrueColor($wide, $high);

	ImageAlphaBlending($im[$x], TRUE);



	// SET COLORS: MAN PAGE http://us.php.net/manual/en/function.imagecolorallocatealpha.php

	$bgcolor = ImageColorAllocateAlpha($im[$x], 0, 0, 0, 0);

	$shadow  = ImageColorAllocateAlpha($im[$x], $rgb_sr, $rgb_sg, $rgb_sb, $dense);

	$text    = ImageColorAllocateAlpha($im[$x], $rgb_tr, $rgb_tg, $rgb_tb, 0);



	ImageColorTransparent($im[$x], $bgcolor);



	// FILL THE BACKGROUND: MAN PAGE http://us.php.net/manual/en/function.imagefilledrectangle.php

	ImageFilledRectangle($im[$x], 0, 0, $wide, $high, $bgcolor);



    // SHADOW FIRST TO CREATE THE BLUR: MAN PAGE http://us.php.net/manual/en/function.imagettftext.php

    ImageTTFtext($im[$x], $size, $angle, $x_off, $y_off+$x, $shadow, $font, $string);



    // BLUR BY APPROXIMATIONS: MAN PAGE http://us.php.net/manual/en/function.imagefilter.php

    $blur_count = $x;

    if ($x)

    {

        while ($blur_count)

        {

            ImageFilter($im[$x], IMG_FILTER_GAUSSIAN_BLUR);

            $blur_count--;

        }

    }

}





// ADD THE TEXT BACK INTO ELEMENT ZERO

ImageFilledRectangle($im[0], 0, 0, $wide, $high, $bgcolor);

ImageTTFtext($im[0], $size, $angle, $x_off, $y_off,   $text,   $font, $string);



// PRODUCE A PNG IMAGE

$x = $lcount+1;

while ($x)

{

    $x--;

    if ($x > 1)

    {

        $d = (int)round($dense / (pow($x, 1.5)));

    }

    else

    {

        $d = (int)round($dense / 2);

    }

    ImageCopyMerge($doggie, $im[$x], 50, 50, 0, 0, $wide, $high, $d);

}

// FINAL TEXT

ImageCopyMerge($doggie, $im[0], 50, 50, 0, 0, $wide, $high, 100);

Header('Content-type: image/png');

ImagePNG($doggie);

Open in new window

RAY-temp-600x374.png
0
 
LVL 10

Author Closing Comment

by:ray-solomon
ID: 34116046
Brilliant. I understand.

Stacking the drop shadow text multiple times while offsetting and applying a Gaussian blur to each layer.
Then it increments the opacity for each drop shadow layer and merges each one together, then the text itself is merged on top.

Thank you.
good solution.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 34116207
Thanks for the points - it's an interesting question!  Best regards, ~Ray
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Both Easy and Powerful How easy is PHP? http://lmgtfy.com?q=how+easy+is+php (http://lmgtfy.com?q=how+easy+is+php)  Very easy.  It has been described as "a programming language even my grandmother can use." How powerful is PHP?  http://en.wikiped…
Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now