Navigation Menu

Creating a Favicon for Your Site

Maybe you've seen your site error log, full of "File does not exist" errors, almost all for a file that you never mention anywhere — favicon.ico. This is a tiny icon that gets displayed in your browser or bookmarks. For example, if you go to Yahoo, you will see this image: Yahoo favicon. Most browsers automatically look for it.

Perhaps the easiest way to make a favicon is to use a site like, try it and see how it works for you.

Here's one method to make a favicon. I used this to generate the FavIcon for this page. Copy the PHP script, below, save it on your server as DynamicHeadingGenerator.php and copy this URL to your HTML file (it displays on several lines, but it's all one line; copy and paste instead of retyping): <LINK rel="shortcut icon" href="">

Replace with your domain name

Instead of text=LC change LC to your site initials

Change the color= and background= if you want (must be 6 hexadecimal digits)

You can try different fonts, changing "GoodfishBd.otf" to "AndikaBasicR.ttf", "KenyanCoffeeBd.otf", "CreditValleyBd.otf", "Caudex-Bold.ttf" or "minyanouvellebdit.ttf", all free for web use from

Of course Google Fonts is another great place for finding fonts, free to use in web pages or download to your computer.

You will have to experiment with the "size=" to make it close to 16px. In Firefox, 16x18 or 17x17 work, even shows up as a favicon (next to the address). Officially, the icon should be 16x16 pixels, so use an image program to resize it, as discussed in the instructions below.

How do you make a favicon matching your site background image? There are specialized programs available, but I think installing a special graphics package is more than you need, and why spend any money? You can use image editing software that you already have. My favorite image viewer is IrfanView, and it has some simple image editing capabilities (very easy to adjust the color balance and brightness of pictures, or bring background objects out of shadows).

If you know GIMP, it is an excellent imge editor, that many people consider almost as powerful as PhotoShop but it is free. It's much more than you need for making a favicon, but if you have it you can of course use it

Load your site's background image into your image editor. First thing to do: Make a copy! File, Save As, junk.jpg

Crop the image so it is (approximately) square. You want something that will resize well to the 16 x 16 pixels of the favicon.ico. Ideally, pick a multiple of 16 (or of 64) pixels. In IrfanView, you drag the mouse over the area you want to crop; the size of your selection is shown.

If it is a detailed image, crop it so you have a square that is representative of your site's color.

Drag the mouse to make a box for positioning your text, that covers the image. You can adjust the box by holding the mouse down on the box edges. Note that you are not creating a visible box, just a selected area for the program to know where to put your text.

In the Edit menu, pick "Insert text into selection". In the Text box, type either one or two letters for your logo. Remember you need to keep it very simple.

Click "Choose Font", and pick a non-serif font (since you will be converting to only 16x16 pixels). Use bold, no italics. Use the text color that contrasts most with the image.

You will have to experiment to get the text size correct, so it almost fills the image. For the 128x128 cropped version of the background for the default style of this site, I used 60pt.

When you have your one or two letters filling your image, resize it to the proper size for a favicon: Image, Resize/Resample, uncheck "Preserve aspect ratio", and specify Width: 16, Height: 16, in Pixels.

To save, use Save as Type: "ICO - Windows Icon". File name: favicon . Then upload your favicon.ico file to your web server.

Now when you load your web site, you should see your favicon in your browser.

Dynamic Heading Generator

You can make an image for use as a heading. See the background of the left (or on a narrow screen, the lower) section, the section that contains the site menu.

You can also put the image in your page.
fancy font Dynamic Heading Generator

fancy font Abraham Lincoln image

Nice, isn't it?

Copy this code, save it as DynamicHeadingGenerator.php and upload to your server.

Dynamic Heading Generator
modified from Stewart Rosenberger

This script generates PNG images of text, written in the font/size that you specify. These PNG images are passed back to the browser. Optionally, they can be cached for later use. If a cached image is found, a new image will not be generated, and the existing copy will be sent to the browser.

Additional command line parameter processing added by George Lerner,
font: the file name (including path) of the font to use
size: the size in px
color: the foreground color
background: the background color (if transparent not '0', background color is used for a 1 pixel border)
transparent: if '0' then the background color fills the image

Sample command lines (notice the use of %20, the encoding for a space character, to pad the beginning and end of the image):

Additional documentation on PHP's image handling capabilities can be found at


// don't use '/fonts/', use 'fonts/'
// $font_file  = 'fonts/ABBERANC.TTF' ;
// $font_file  = 'fonts/vinque.ttf' ;		// uncials
// $font_file  = 'fonts/BetsyFlanagan.ttf' ;	// keyboard
// $font_file  = 'fonts/BetsyFlanagan2.ttf' ;	// keyboard Fn keys
// $font_file  = 'fonts/coolvetica.ttf' ;	// cool Arial
// $font_file  = 'fonts/creditva.ttf' ;	// slightly narrow elegant
// $font_file  = 'fonts/EFFLB___.TTF' ;	// Effloresce very legible stylish serif
$font_file  = 'fonts/GoodfishBd.otf' ;		// elegant Roman serif

$font_size  = 50 ;
$font_color = '#39872f' ;
$background_color = '#ffffff' ;
$transparent_background = true ;
$cache_images = true ;
$cache_folder = 'cache' ;

/* ---------------------------------------------------------------------------
   For basic usage, you should not need to edit anything below this comment.
   If you need to further customize this script's abilities, make sure you
   are familiar with PHP and its image handling capabilities.
  --------------------------------------------------------------------------- */

$mime_type = 'image/png' ;
$extension = '.png' ;
$send_buffer_size = 4096 ;

// check for GD support
if (!function_exists('ImageCreate')) {
    fatal_error('Error: Server does not support PHP image generation') ;

// clean up text
if (empty($_GET['text'])) {
    fatal_error('Error: No text specified.') ;

$text = $_GET['text'] ;
$text = javascript_to_html($text) ;

if (!empty($_GET['font'])) {
    $font_file  = $_GET['font'];
    /* Important for security: Only use $font_file with ImageTTFBBox() */
if (!empty($_GET['size'])) {
    $font_size  = (int) $_GET['size'] ;
if (!empty($_GET['color'])) {
    $font_color = $_GET['color'];
    /* important for security: only use colors in hex_to_rgb() */
if (!empty($_GET['background'])) {
    $background_color = $_GET['background'] ;

// '0' matches empty
if ($_GET['transparent'] == '0') {
    $transparent_background = false ;

// look for cached copy, send if it exists
$hash = md5(basename($font_file) . $font_size . $font_color . $background_color . $transparent_background . $text) ;
$cache_filename = $cache_folder . '/' . $hash . $extension ;
if ($cache_images && ($file = @fopen($cache_filename,'rb')))
    header('Content-type: ' . $mime_type) ;
    while(!feof($file)) {
        print(($buffer = fread($file,$send_buffer_size))) ;
    fclose($file) ;
    exit ;

// check font availability
$font_found = is_readable($font_file) ;
if (!$font_found) {
    fatal_error('Error: The server is missing the specified font: ' . $font_file) ;

// create image
$background_rgb = hex_to_rgb($background_color) ;
$font_rgb = hex_to_rgb($font_color) ;
$dip = get_dip($font_file,$font_size) ;
$box = @ImageTTFBBox($font_size,0,$font_file,$text) ;
$image = @ImageCreate(abs($box[2]-$box[0]),abs($box[5]-$dip)) ;
if (!$image || !$box) {
    fatal_error('Error: The server could not create this heading image.') ;

// allocate colors and draw text
$background_color = ImageColorAllocate($image,$background_rgb['red'],
    $background_rgb['green'],$background_rgb['blue']) ;
$font_color = ImageColorAllocate($image,$font_rgb['red'],
    $font_rgb['green'],$font_rgb['blue']) ;
    $font_color,$font_file,$text) ;

// set transparency
if ($transparent_background) {
    ImageColorTransparent($image,$background_color) ;

header('Content-type: ' . $mime_type) ;
ImagePNG($image) ;

// save copy of image for cache
if ($cache_images) {
    @ImagePNG($image,$cache_filename) ;

ImageDestroy($image) ;
exit ;

/* try to determine the "dip" (pixels dropped below baseline) of this font for this size. */
function get_dip($font,$size) {
    $test_chars = 'abcdefghijklmnopqrstuvwxyz' .
    '1234567890' .
    '!@#$%^&*()\'"\\/;.,`~<>[]{}-+_-=' ;
    $box = @ImageTTFBBox($size,0,$font,$test_chars) ;
    return $box[3] ;

/* attempt to create an image containing the error message given. if this works, the image is sent to the browser. if not, an error is logged, and passed back to the browser as a 500 code instead. */
function fatal_error($message) {
    // send an image
    if (function_exists('ImageCreate')) {
        $width = ImageFontWidth(5) * strlen($message) + 10 ;
        $height = ImageFontHeight(5) + 10 ;
        if ($image = ImageCreate($width,$height)) {
            $background = ImageColorAllocate($image,255,255,255) ;
            $text_color = ImageColorAllocate($image,0,0,0) ;
            ImageString($image,5,5,5,$message,$text_color) ;
            header('Content-type: image/png') ;
            ImagePNG($image) ;
            ImageDestroy($image) ;
            exit ;

    // send 500 code
    header("HTTP/1.0 500 Internal Server Error") ;
    print($message) ;
    exit ;

/* decode an HTML hex-code into an array of R,G, and B values. accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff */
function hex_to_rgb($hex) {
    // remove '#'
    if (substr($hex,0,1) == '#') {
        $hex = substr($hex,1) ;

    // expand short form ('fff') color
    if (strlen($hex) == 3) {
        $hex = substr($hex,0,1) . substr($hex,0,1) .
               substr($hex,1,1) . substr($hex,1,1) .
               substr($hex,2,1) . substr($hex,2,1) ;

    if (strlen($hex) != 6) {
        fatal_error('Error: Invalid color "'.$hex.'"') ;

    // convert
    $rgb['red'] = hexdec(substr($hex,0,2)) ;
    $rgb['green'] = hexdec(substr($hex,2,2)) ;
    $rgb['blue'] = hexdec(substr($hex,4,2)) ;

    return $rgb ;

/* convert embedded, javascript unicode characters into embedded HTML entities. (e.g. '%u2018' => '&#8216;'). returns the converted string. */
function javascript_to_html($text) {
    $matches = null ;
    preg_match_all('/%u([0-9A-F]{4})/i',$text,$matches) ;
    if (!empty($matches)) for($i=0;$i<sizeof($matches[0]);$i++) {
        $text = str_replace($matches[0][$i], '&#' . hexdec($matches[1][$i]). ';',$text) ;
    return $text ;


SiteGround WordPress hosting