Problem facing while Dynamic Image Creation to replace Font Embedding

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • neovantage
    New Member
    • Aug 2008
    • 245

    #1

    Problem facing while Dynamic Image Creation to replace Font Embedding

    Hey all,

    I am using a PHP script which creates headings at run time in a sense at page execution. I am stuck a with a very little problem which i am sure i will have the solution from experts.

    The problem is when it creates transparent PNG format image then and it pixel ate the image. e.g.

    If i am using a gradient in background then it vary in color range. Now when i used that php script it generates image successfully but it pixel ate the image.

    So my question how can i fix that. i am attaching the code which i am using for that and a *.jpg of screen shot for better understanding of my problem.

    generate-headings.php Page
    Code:
    $font_file  = 'fonts/arial.ttf' ;
    	$font_size  = 20 ;
    	$font_color = '#ffffff' ;
    	$background_color = '#ffffff' ;
    	$transparent_background  = true ;
    	$cache_images = true ;
    	$cache_folder = 'cache' ;
    	
    	$mime_type = 'image/png' ;
    	$extension = '.png' ;
    	$send_buffer_size = 4096 ;
    	
    	$text = $_GET['text'];
    	
    	if(get_magic_quotes_gpc()){
        	$text = stripslashes($text) ;
    	}
    	$text = javascript_to_html($text) ;
    	
    	// 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.') ;
    	}
    	
    	// 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']) ;   
    	ImageTTFText($image,$font_size,0,-$box[0],abs($box[5]-$box[3])-$box[1],$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 ;
    	
    	/*$im = imagecreatetruecolor(300, 18);
    	$white = imagecolorallocate($im, 255, 255, 255);
    	$black = imagecolorallocate($im, 0, 0, 0);
    	imagefilledrectangle($im, 0, 0, imagesx($im), imagesy($im), gd_bkg());
    	$text = $_GET[hd];
    	$font = "fonts/Abduction.ttf";
    	imagettftext($im,14,0,0,13,$black,$font,$text);
    	imagepng($im);
    	imagedestroy($im);
    	
    	$background_rgb = hex_to_rgb($background_color) ;
    	$background_color = @ImageColorAllocate($image,$background_rgb['red'],*/
    	
    	
    	//=============================== FUNCTIONS =================
    	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 ;
    	}
    	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 ;
    	}
    	function get_dip($font,$size){
    		$test_chars = 'abcdefghijklmnopqrstuvwxyz' .
    					  'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
    					  '1234567890' .
    					  '!@#$%^&*()\'"\\/;.,`~<>[]{}-+_-=' ;
    		$box = @ImageTTFBBox($size,0,$font,$test_chars) ;
    		return $box[3] ;
    	}
    Javascript File which used to replace text with images

    Code:
    function com_stewartspeak_replacement() {
    /*
    	Dynamic Heading Generator
        By Stewart Rosenberger
        http://www.stewartspeak.com/headings/
    
    	This script searches through a web page for specific or general elements
    	and replaces them with dynamically generated images, in conjunction with
    	a server-side script.
    */
    
    
    replaceSelector("h2","generate-headings.php",true);
    var testURL = "http://bytes.com/images/test.png" ;
    
    var doNotPrintImages = false;
    var printerCSS = "includes/replacement-print.css";
    
    var hideFlicker = false;
    var hideFlickerCSS = "includes/replacement-screen.css";
    var hideFlickerTimeout = 1000;
    
    
    
    
    /* ---------------------------------------------------------------------------
        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're familiar with Javascript. And grab a soda or something.
    */
    
    var items;
    var imageLoaded = false;
    var documentLoaded = false;
    
    function replaceSelector(selector,url,wordwrap){
    	if(typeof items == "undefined")
    		items = new Array();
    
    	items[items.length] = {selector: selector, url: url, wordwrap: wordwrap};
    }
    
    if(hideFlicker)
    {		
    	document.write('<link id="hide-flicker" rel="stylesheet" media="screen" href="' + hideFlickerCSS + '" />');		
    	window.flickerCheck = function()
    	{
    		if(!imageLoaded)
    			setStyleSheetState('hide-flicker',false);
    	};
    	setTimeout('window.flickerCheck();',hideFlickerTimeout)
    }
    
    if(doNotPrintImages)
    	document.write('<link id="print-text" rel="stylesheet" media="print" href="' + printerCSS + '" />');
    
    var test = new Image();
    test.onload = function() { imageLoaded = true; if(documentLoaded) replacement(); };
    test.src = testURL + "?date=" + (new Date()).getTime();
    alert(test.src);
    addLoadHandler(function(){ documentLoaded = true; if(imageLoaded) replacement(); });
    
    
    function documentLoad()
    {
    	documentLoaded = true;
    	if(imageLoaded)
    		replacement();
    }
    
    function replacement()
    {
    	for(var i=0;i<items.length;i++)
    	{
    		var elements = getElementsBySelector(items[i].selector);
    		if(elements.length > 0) for(var j=0;j<elements.length;j++)
    		{
    			if(!elements[j])
    				continue ;
    		
    			var text = extractText(elements[j]);
        		while(elements[j].hasChildNodes())
    				elements[j].removeChild(elements[j].firstChild);
    
    			var tokens = items[i].wordwrap ? text.split(' ') : [text] ;
    			for(var k=0;k<tokens.length;k++)
    			{
    				var url = items[i].url + "?text="+escape(tokens[k]+' ')+"&selector="+escape(items[i].selector);
    				var image = document.createElement("img");
    				image.className = "replacement";
    				image.alt = tokens[k] ;
    				image.src = url;
    				elements[j].appendChild(image);
    			}
    
    			if(doNotPrintImages)
    			{
    				var span = document.createElement("span");
    				span.style.display = 'none';
    				span.className = "print-text";
    				span.appendChild(document.createTextNode(text));
    				elements[j].appendChild(span);
    			}
    		}
    	}
    
    	if(hideFlicker)
    		setStyleSheetState('hide-flicker',false);
    }
    
    function addLoadHandler(handler)
    {
    	if(window.addEventListener)
    	{
    		window.addEventListener("load",handler,false);
    	}
    	else if(window.attachEvent)
    	{
    		window.attachEvent("onload",handler);
    	}
    	else if(window.onload)
    	{
    		var oldHandler = window.onload;
    		window.onload = function piggyback()
    		{
    			oldHandler();
    			handler();
    		};
    	}
    	else
    	{
    		window.onload = handler;
    	}
    }
    
    function setStyleSheetState(id,enabled) 
    {
    	var sheet = document.getElementById(id);
    	if(sheet)
    		sheet.disabled = (!enabled);
    }
    
    function extractText(element)
    {
    	if(typeof element == "string")
    		return element;
    	else if(typeof element == "undefined")
    		return element;
    	else if(element.innerText)
    		return element.innerText;
    
    	var text = "";
    	var kids = element.childNodes;
    	for(var i=0;i<kids.length;i++)
    	{
    		if(kids[i].nodeType == 1)
    		text += extractText(kids[i]);
    		else if(kids[i].nodeType == 3)
    		text += kids[i].nodeValue;
    	}
    
    	return text;
    }
    
    /*
    	Finds elements on page that match a given CSS selector rule. Some
    	complicated rules are not compatible.
    	Based on Simon Willison's excellent "getElementsBySelector" function.
    	Original code (with comments and description):
    		http://simon.incutio.com/archive/2003/03/25/getElementsBySelector
    */
    function getElementsBySelector(selector)
    {
    	var tokens = selector.split(' ');
    	var currentContext = new Array(document);
    	for(var i=0;i<tokens.length;i++)
    	{
    		token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
    		if(token.indexOf('#') > -1)
    		{
    			var bits = token.split('#');
    			var tagName = bits[0];
    			var id = bits[1];
    			var element = document.getElementById(id);
    			if(tagName && element.nodeName.toLowerCase() != tagName)
    				return new Array();
    			currentContext = new Array(element);
    			continue;
    		}
    
    		if(token.indexOf('.') > -1)
    		{
    			var bits = token.split('.');
    			var tagName = bits[0];
    			var className = bits[1];
    			if(!tagName)
    				tagName = '*';
    
    			var found = new Array;
    			var foundCount = 0;
    			for(var h=0;h<currentContext.length;h++)
    			{
    				var elements;
    				if(tagName == '*')
    					elements = currentContext[h].all ? currentContext[h].all : currentContext[h].getElementsByTagName('*');
    				else
    					elements = currentContext[h].getElementsByTagName(tagName);
    
    				for(var j=0;j<elements.length;j++)
    					found[foundCount++] = elements[j];
    			}
    
    			currentContext = new Array;
    			var currentContextIndex = 0;
    			for(var k=0;k<found.length;k++)
    			{
    				if(found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b')))
    					currentContext[currentContextIndex++] = found[k];
    			}
    
    			continue;
    	    }
    
    		if(token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/))
    		{
    			var tagName = RegExp.$1;
    			var attrName = RegExp.$2;
    			var attrOperator = RegExp.$3;
    			var attrValue = RegExp.$4;
    			if(!tagName)
    				tagName = '*';
    
    			var found = new Array;
    			var foundCount = 0;
    			for(var h=0;h<currentContext.length;h++)
    			{
    				var elements;
    	        	if(tagName == '*')
    					elements = currentContext[h].all ? currentContext[h].all : currentContext[h].getElementsByTagName('*');
    				else
    					elements = currentContext[h].getElementsByTagName(tagName);
    
    				for(var j=0;j<elements.length;j++)
    					found[foundCount++] = elements[j];
    			}
    
    			currentContext = new Array;
    			var currentContextIndex = 0;
    			var checkFunction;
    			switch(attrOperator)
    			{
    				case '=':
    					checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
    					break;
    				case '~':
    					checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
    					break;
    				case '|':
    					checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
    					break;
    				case '^':
    					checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
    					break;
    				case '$':
    					checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
    					break;
    				case '*':
    					checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
    					break;
    				default :
    					checkFunction = function(e) { return e.getAttribute(attrName); };
    			}
    
    			currentContext = new Array;
    			var currentContextIndex = 0;
    			for(var k=0;k<found.length;k++)
    			{
    				if(checkFunction(found[k]))
    					currentContext[currentContextIndex++] = found[k];
    			}
    
    			continue;
    		}
    
    		tagName = token;
    		var found = new Array;
    		var foundCount = 0;
    		for(var h=0;h<currentContext.length;h++)
    		{
    			var elements = currentContext[h].getElementsByTagName(tagName);
    			for(var j=0;j<elements.length; j++)
    				found[foundCount++] = elements[j];
    		}
    
    		currentContext = found;
    	}
    
    	return currentContext;
    }
    
    
    }// end of scope, execute code
    if(document.createElement && document.getElementsByTagName && !navigator.userAgent.match(/opera\/?6/i))
    	com_stewartspeak_replacement();
    Attached Files
    Last edited by neovantage; Apr 2 '09, 06:47 AM. Reason: Title was not clearing my problem that is why i edit the title
  • hsriat
    Recognized Expert Top Contributor
    • Jan 2008
    • 1653

    #2
    I could not see any "pixel ate" happening. Even it does happen, I believe it would be a error in your algorithm.

    PS: I am inferring "pixel ate" as what happens to the videos being shown on the national TV channels when there's some inappropriate content/scene.

    Comment

    Working...