Search code examples
phphtmlpngtransparencyavatar

Create round png image in PHP using transparency and center a letter in it


I'd like to create profile images for my website. The image should be rounded, a solid background color and a single big letter exactly at the center.

So far I've been able to create a square png image and a letter in it but it's not centered. Due to the fact that different letters have different width I get some letters slightly off-center.

I'm going to implement"round" png images in PHP using transparency.

This is the complete script and should work out of the box. You need Arial.tff if you want to use a custom font but it's not strictly needed.

There is a lookup table with some colors. The single letter get hashed (yeah, pretty stupid I know, but this way it's more flexible as I could pass any string I like) and a color is picked.

<?php

$text = "a";

$posx = 40;
$posy = 150;
$size = 120;
$displaytext = strtoupper($text);

$image = imagecreatetruecolor(200, 200);

// pick a background at random
$binhash = md5($text, true);
$numhash = unpack('N2', $binhash);
$index = abs($numhash[1]) % 16;

$palette = array(
array(0xde,0x5a,0xa4),
array(0xae,0xc6,0xcf),
array(0x96,0x6f,0xd6),
array(0xff,0xb3,0x47),

array(0xff,0x69,0x61),
array(0x77,0xdd,0x77),
array(0x03,0xc0,0x3c),
array(0xcf,0xcf,0xc4),

array(0xc2,0x3b,0x22),
array(0xfd,0xfd,0x96),
array(0x83,0x69,0x53),
array(0x77,0x9e,0xcb),

array(0xb1,0x9c,0xd9),
array(0xb3,0x9e,0xb5),
array(0xf4,0x9a,0xc2),
array(0xff,0xd1,0xdc)
);

$r = $palette[$index][0];
$g = $palette[$index][1];
$b = $palette[$index][2];

$image = imageCreate(200, 200);
imageColorAllocate($image, $r, $g, $b);
$color = imageColorAllocate($image, 255, 255, 255);
$font = 'arial.ttf';



$box = imagettfbbox(200, 0, "ARIAL", $displaytext);
$width = abs($box[2] - $box[0]);
$height = abs($box[5] - $box[1]);

$image = imageCreate(200, 200);
imageColorAllocate($image, $r, $g, $b);
$color = imageColorAllocate($image, 255, 255, 255);
$font = 'arial.ttf';
imagettftext($image, 200, 0, 0 + (200/2 - floor($width/2)), 200, $color, "ARIAL", $displaytext);

header("content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

How can I modify such code in order to:

  • Have round corner. Shall I create a transparent background and a solid disc at the center?
  • Have the letter centered, no matter which letter it is

Solution

  • This can help you for centering the letter

    <?php
    $im = new Imagick(); /* Create a new Imagick object */
    $draw = new ImagickDraw(); /* Create an ImagickDraw object */
    $draw->setFont('/path/to/font.ttf'); /* Set the font */
    var_dump($im->queryFontMetrics($draw, "K")); /* Dump the font metrics*/
    ?>
    

    Using fontmetrics you can calculate the width and height of a specific letter/text with specific font and you can access the properties. Hope that will help you.