Get Favicon image using PHP
Some websites use a small Favicon as a logo for their website. In some cases it would be nice if you are able to get this small image (icon) and use it for your PHP output. For example when you have a link to this site or when you are showing the RSS feed from this site.
I found 2 different scripts for getting the favicon from external websites using PHP scripting. Here are the scripts.
function getFavicon($url) { $HTTPRequest = @fopen($url, 'r'); if ($HTTPRequest) { stream_set_timeout($HTTPRequest, 0.1); $html = fread($HTTPRequest, 4096); $HTTPRequestData = stream_get_meta_data($HTTPRequest); fclose($HTTPRequest); if (!$HTTPRequestData['timed_out']) { if (preg_match('/<link[^>]+rel="(?:shortcut )?icon"[^>]+?href="([^"]+?)"/si', $html, $matches)) { $linkUrl = html_entity_decode($matches[1]); if (substr($linkUrl, 0, 1) == '/') { $urlParts = parse_url($url); $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].$linkUrl; } elseif (substr($linkUrl, 0, 7) == 'http://') { $faviconURL = $linkUrl; } elseif (substr($url, -1, 1) == '/') { $faviconURL = $url.$linkUrl; } else { $faviconURL = $url.'/'.$linkUrl; } } else { $urlParts = parse_url($url); $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].'/favicon.ico'; } $HTTPRequest = @fopen($faviconURL, 'r'); if ($HTTPRequest) { stream_set_timeout($HTTPRequest, 0.1); $favicon = fread($HTTPRequest, 8192); $HTTPRequestData = stream_get_meta_data($HTTPRequest); fclose($HTTPRequest); if (!$HTTPRequestData['timed_out'] && strlen($favicon) < 8192) { return $faviconURL; } } } } return false; } And the other PHP script I found is:<?php ################################################################################ # # Favicon Class (work with favicons), ver. 1.0, June, 2006. # # (c) 2006 ControlStyle Company. All rights reserved. # Developped by Nikolay I. Yarovoy, Dmitry V. Domojilov. # # http://www.controlstyle.com # info@controlstyle.com # ################################################################################ class favicon { var $ver = '1.1'; var $site_url = ''; # url of site var $if_modified_since = 0; # cache var $is_not_modified = false; var $ico_type = 'ico'; # ico, gif or png only var $ico_url = ''; # full uri to favicon var $ico_exists = 'not checked'; # no comments var $ico_data = ''; # ico binary data var $output_data = ''; # output image binary data # main proc function favicon($site_url, $if_modified_since = 0) { $site_url = trim(str_replace('http://', '', trim($site_url)), '/'); $site_url = explode('/', $site_url); $site_url = 'http://' . $site_url[0] . '/'; $this->site_url = $site_url; $this->if_modified_since = $if_modified_since; $this->get_ico_url(); $this->is_ico_exists(); $this->get_ico_data(); } # get uri of favicon function get_ico_url() { if ($this->ico_url == '') { $this->ico_url = $this->site_url . 'favicon.ico'; # get html of page $h = @fopen($this->site_url, 'r'); if ($h) { $html = ''; while (!feof($h) and !preg_match('/<([s]*)body([^>]*)>/i', $html)) { $html .= fread($h, 200); } fclose($h); # search need <link> tag if (preg_match('/<([^>]*)link([^>]*)(rel="icon"|rel="shortcut icon")([^>]*)>/iU', $html, $out)) { $link_tag = $out[0]; if (preg_match('/href([s]*)=([s]*)"([^"]*)"/iU', $link_tag, $out)) { $this->ico_type = (!(strpos($link_tag, 'png')===false)) ? 'png' : 'ico'; $ico_href = trim($out[3]); if (strpos($ico_href, 'http://')===false) { $ico_href = rtrim($this->site_url, '/') . '/' . ltrim($ico_href, '/'); } $this->ico_url = $ico_href; } } } } return $this->ico_url; } # check that favicon is exists function is_ico_exists() { if ($this->ico_exists=='not checked') { $h = @fopen($this->ico_url, 'r'); $this->ico_exists = ($h) ? true : false; if ($h) fclose($h); } return $this->ico_exists; } # get ico data function get_ico_data() { if ($this->ico_data=='' && $this->ico_url!='' && $this->ico_exists && !$this->is_not_modified) { # get ico data $ico_z = parse_url($this->ico_url); $ico_path = $ico_z['path']; $ico_host = $ico_z['host']; $ico_ims = gmdate('D, d M Y H:i:s', $this->if_modified_since) . ' GMT'; $fp = @fsockopen($ico_host, 80); if ($fp) { $out = "GET {$ico_path} HTTP/1.1\r\n"; $out .= "Host: {$ico_host}\r\n"; $out .= "User-Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3\r\n"; $out .= "If-Modified-Since: {$ico_ims}\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); $data = ''; while (!feof($fp)) $data .= fgets($fp, 128); fclose($fp); $response = substr($data, 0, 15); $this->is_not_modified = !(strpos($response, '304')===false); if ($this->is_not_modified) { $this->ico_data = 'not modified'; } else { $data = explode("\r\n\r\n", $data); if (count($data)>0) { unset($data[0]); $this->ico_data = implode("\r\n\r\n", $data); } } $this->output_data = ''; } } return $this->ico_data; } # get output data function get_output_data() { if ($this->output_data=='') { if ($this->ico_data=='not modified') { # icon is not modified since defined time $this->output_data = 'not modified'; } elseif($this->ico_data=='') { # error(s) in getting icon data $this->output_data = $this->empty_png(); } else { # convert ico to png, gif & return if (substr($this->ico_data, 0, 3)==='GIF') $this->ico_type = 'gif'; $this->output_data = $this->ico_data; if ($this->ico_type==='ico') { $this->output_data = $this->ico2png($this->output_data); } if ($this->ico_type==='gif') { $this->output_data = $this->gif2png($this->output_data); } } } return $this->output_data; } # if error or icon is not found we output empty png image function empty_png() { $res = ''; $im = imagecreatetruecolor(16, 16); $color = imagecolorallocate($im, 255, 255, 255); imagefill($im, 1, 1, $color); # output png ob_start(); # imagesavealpha($im, true); imagepng($im); imagedestroy($im); $res = ob_get_clean(); return $res; } # Convert gif to png function, # support gif-functions by GD is needed function gif2png($gif) { $im2 = imagecreatefromstring($gif); # background alpha is disabled because IE 5.5 + have bug with alpha-channels # by default background color is white # imagealphablending($im, false); # imagefilledrectangle($im, 0, 0, 16, 16, $color); # imagealphablending($im, true); $im = imagecreatetruecolor(16, 16); $color = imagecolorallocate($im, 255, 255, 255); imagefill($im, 1, 1, $color); imagecopy($im, $im2, 0, 0, 0, 0, 16, 16); # output png ob_start(); # imagesavealpha($im, true); imagepng($im); imagedestroy($im); imagedestroy($im2); $res = ob_get_clean(); return $res; } # Convert ico to png function, # information about ico format is accessible on a site http://kainsk.tomsk.ru/g2003/sys26/oswin.htm, function ico2png($ico) { $res = ''; while(!isset($tmp)) { $tmp = ''; # get ICONDIR struct & check that it is correct ico format $icondir = unpack('sidReserved/sidType/sidCount', substr($ico, 0, 6)); if ($icondir['idReserved']!=0 || $icondir['idType']!=1 || $icondir['idCount']<1) break; $icondir['idEntries'] = array(); $entry = array(); for($i=0; $i<$icondir['idCount']; $i++) { $entry = unpack('CbWidth/CbHeight/CbColorCount/CbReserved/swPlanes/swBitCount/LdwBytesInRes/LdwImageOffset', substr($ico, 6 + $i*16, 16)); $icondir['idEntries'][] = $entry; } # select need icon & get it raw data $iconres = ''; $bpx = 1; # bits per pixel $idx = 0; # index of need icon foreach($icondir['idEntries'] as $k=>$entry) { if ($entry['bWidth']==16 && isset($entry['swBitCount']) && $entry['swBitCount']>$bpx && $entry['swBitCount']<33) { $idx = $k; $bpx = $entry['swBitCount']; } } $iconres = substr($ico, $icondir['idEntries'][$idx]['dwImageOffset'], $icondir['idEntries'][$idx]['dwBytesInRes']); unset($ico); unset($icondir); # getting bitmap info $bitmap_info = array(); $bitmap_info['header'] = unpack('LbiSize/LbiWidth/LbiHeight/SbiPlanes/SbiBitCount/LbiCompression/LbiSizeImage/LbiXPelsPerMeter/LbiYPelsPerMeter/LbiClrUsed/LbiClrImportant', substr($iconres, 0, 40)); $bitmap_info['header']['biHeight'] = $bitmap_info['header']['biHeight'] / 2; $number_color = 0; if ($bitmap_info['header']['biBitCount'] > 16) { $number_color = 0; $sizecolor = $bitmap_info['header']['biWidth']*$bitmap_info['header']['biBitCount'] * $bitmap_info['header']['biHeight'] / 8; } elseif ( $bitmap_info['header']['biBitCount'] < 16) { $number_color = (int) pow(2, $bitmap_info['header']['biBitCount']); $sizecolor = $bitmap_info['header']['biWidth']*$bitmap_info['header']['biBitCount'] * $bitmap_info['header']['biHeight'] / 8; if ($bitmap_info['header']['biBitCount']=='1') $sizecolor = $sizecolor * 2; } else return $res; $rgb_table_size = 4 * $number_color; for($i=0; $i<$number_color; $i++) { $bitmap_info['colors'][] = unpack('CrgbBlue/CrgbGreen/CrgbRed/CrgbReserved', substr($iconres, 40 + $i*4, 4)); } $current_offset = 40 + $number_color * 4; $arraycolor = array(); for($i=0; $i<$sizecolor; $i++) { $value = unpack('Cvalue', substr($iconres, $current_offset, 1)); $arraycolor[] = $value['value']; $current_offset++; } # background alpha is disabled because IE 5.5 + have bug with alpha-channels # by default background color is white # imagealphablending($im, false); # imagefilledrectangle($im, 0, 0, 16, 16, $color); # imagealphablending($im, true); $im = imagecreatetruecolor(16, 16); $color = imagecolorallocate($im, 255, 255, 255); imagefill($im, 1, 1, $color); # getting mask $alpha = ''; for($i=0; $i<16; $i++) { $z = unpack('Cx/Cy', substr($iconres, $current_offset, 2)); $z = str_pad(decbin($z['x']), 8, '0', STR_PAD_RIGHT) . str_pad(decbin($z['y']), 8, '0', STR_PAD_LEFT); $alpha .= $z; $current_offset = $current_offset + 4; } # drawing image $ico_size = 16; $off = 0; # range (0-255) # cases for different color depth switch ($bitmap_info['header']['biBitCount']) { ###################### for 32 bit icons ###################### case 32: for($y=0; $y<$ico_size; $y++) { for($x=0; $x<$ico_size; $x++) { $a = round((255-$arraycolor[$off*4+3])/2); $a = ($a<0) ? 0 : $a; $a = ($a>127) ? 127 : $a; $color = imagecolorallocatealpha($im, $arraycolor[$off*4+2], $arraycolor[$off*4+1], $arraycolor[$off*4], $a); imagesetpixel($im, $x, $ico_size-1-$y, $color); $off++; } } break; ###################### for 24 bit icons ###################### case 24: for($y=0; $y<$ico_size; $y++) { for($x=0; $x<$ico_size; $x++) { $valpha = ($alpha[$off]=='1') ? 127 : 0; $color = imagecolorallocatealpha($im, $arraycolor[$off*3+2], $arraycolor[$off*3+1], $arraycolor[$off*3], $valpha); imagesetpixel ($im, $x, $ico_size-1-$y, $color); $off++; } } break; ###################### for 08 bit icons ###################### case 8: for($y=0; $y<$ico_size; $y++) { for($x=0; $x<$ico_size; $x++) { $valpha = ($alpha[$off]=='1') ? 127 : 0; $c = $arraycolor[$off]; $c = $bitmap_info['colors'][$c]; $color = imagecolorallocatealpha($im, $c['rgbRed'], $c['rgbGreen'], $c['rgbBlue'], $valpha); imagesetpixel ($im, $x, $ico_size-1-$y, $color); $off++; } } break; ###################### for 04 bit icons ###################### # 318 = 22 (header) + 40 (bitmap_info) + 16 * 4 (colors) + 128 (pixels) + 64 (mask) case 4: for($y=0; $y<$ico_size; $y++) { for($x=0; $x<$ico_size; $x++) { $valpha = ($alpha[$off]=='1') ? 127 : 0; $c = ($arraycolor[floor($off/2)]); $c = str_pad(decbin($c), 8, '0', STR_PAD_LEFT); $m = (fmod($off+1, 2)==0) ? 1 : 0; $c = bindec(substr($c, $m*4, 4)); $c = $bitmap_info['colors'][$c]; $color = imagecolorallocatealpha($im, $c['rgbRed'], $c['rgbGreen'], $c['rgbBlue'], $valpha); imagesetpixel ($im, $x, $ico_size-1-$y, $color); $off++; } } break; ###################### for 01 bit icons ###################### # 198 = 22 (header) + 40 (bitmap_info) + 2 * 4 (colors) + 64 (pixels, but real 32 needed?) + 64 (mask) case 1: for($y=0; $y<$ico_size; $y++) { for($x=0; $x<$ico_size; $x++) { $valpha = ($alpha[$off]=='1') ? 127 : 0; $c = ($arraycolor[floor($off/8)]); # меняем байт каждые 8 пикселей $c = str_pad(decbin($c), 8, '0', STR_PAD_LEFT); $m = fmod($off+8, 8) + 1; # bit number $c = (int) substr($c, $m-1, 1); $c = $bitmap_info['colors'][$c]; $color = imagecolorallocatealpha($im, $c['rgbRed'], $c['rgbGreen'], $c['rgbBlue'], $valpha); imagesetpixel ($im, $x, $ico_size-1-$y, $color); $off++; } $off = $off + 16; } break; ############################################################## default: return ''; } # output png ob_start(); # imagesavealpha($im, true); imagepng($im); imagedestroy($im); $res = ob_get_clean(); } return $res; } } ?>
And you can use the above PHP script with the following call:<?php require_once('favicon.inc.php'); $favicon = new favicon('http://www.controlstyle.ru/', 0); $fv = $favicon->get_output_data(); if ($fv!=='') { header('Content-type: image/png'); echo $fv; } ?> What would be nice is some PHP code / script that can convert the found favicon to a GIF / JPG or PNG image so you can use it inside the HTML code.
Comments are closed.