![]() |
|
Snippets |
|
This one is a port of the Imagetext plugin for Smarty. So as I won't include the credit in this snippet please check them in the Smarty plugin itself here.
In order to make it work, this is what you need : - A 'fonts' folder in your projects' data directory, in which you copy the .ttf files you need - The following helper :
function imagetext($text,$styleName=null,$params=array()) { if(!$styleName){ $styleName='default'; } if (empty($text)) { return; } // Which style is in use $style=sfConfig::get('app_imagetext_styles'); $style=$style[$styleName]; // Param values overwrite style values foreach ($params as $key=>$value) $style[$key] = $value; // Error handling if (empty($style['font'])) { throw new sfViewException("imagetext: missing 'font' parameter"); return; } if (empty($style['size'])) { throw new sfViewException("imagetext: missing 'size' parameter"); return; } if (empty($style['bgcolor'])) { $style['bgcolor'] = 'FFFFFF'; } if (empty($style['fgcolor'])) { $style['fgcolor'] = '000000'; } ### Preferences $cacheDir=sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.'imagetext'.DIRECTORY_SEPARATOR; $cacheUrl='imagetext/'; $fontDir=sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR; $text = preg_replace("=<br( /)?>=i", "\n", $text); // Which font is in use $font = $fontDir.$style['font']; // Hash of text and all parameters for the cache function $hash = md5(implode('',$style).$text); // The url of the created image $imgFile = $cacheDir.$styleName.'_'.$hash.'.'.$style['format']; $imgUrl = $cacheUrl.$styleName.'_'.$hash.'.'.$style['format']; ### Use cached image if available if (file_exists($imgFile) && @$style['dev'] != true && @$style['dynamic'] != true) if (@$style['urlonly'] == 'true') return $imgUrl; else return @$style['prehtml'].image_tag($imgUrl,array('style'=>'border: 0 px solid #00ff00','alt'=>preg_replace("=\r\n|\r|\n|\t=", ' ', htmlspecialchars($text)))).@$style['posthtml']; ### otherwise create it // Function to get a color handler of hex values if (!function_exists('fromhex')) { function fromhex($image,$string) { sscanf($string, "%2x%2x%2x", $red, $green, $blue); return ImageColorAllocate($image,$red,$green,$blue); } } ### create a four times larger image to improve kerning // The multiplier. The bigger the better the kerning and the typeface, but the slower the creation $multi = 4; // If "pixelfont" don“t use multiplier if ($style['pixelfont'] == 1) $multi = 1; // Calculate measures of image $bbox = imagettfbbox ($style['size']*$multi, 0, $font, $text); $xcorr = 0-$bbox[6]; // northwest X $ycorr = 0-$bbox[7]; // northwest Y $box['left'] = $bbox[6]+$xcorr+$style['x']*$multi; $box['height'] = abs($bbox[5])+abs($bbox[1]); $box['width'] = abs($bbox[2])+abs($bbox[0])+$style['x']*$multi; $box['top'] = abs($bbox[5]); // Create the big image $im = imagecreate ($box['width'], $box['height']); $bgcolor = fromhex($im,$style['bgcolor']); $fgcolor = fromhex($im,$style['fgcolor']); if ($style['pixelfont'] == 1) $fgcolor = -$fgcolor; imagettftext ($im, $style['size']*$multi, 0, $box['left'], $box['top'], $fgcolor, $font, $text); // Sample down the big image $width = $style['width']+$style['addx']; $height = $style['height']+$style['addy']; // Overwrite when height oder width is given if (empty($style['width'])) $width = $box['width']/$multi+$style['addx']+$style['x']; if (empty($style['height'])) $height = $box['height']/$multi+$style['addy']+$style['y']; $ds = imagecreatetruecolor ($width, $height); $bgcolor2 = fromhex($ds,$style['bgcolor']); imageFill($ds,0,0,$bgcolor2); imagecopyresampled($ds,$im,0,$style['y'],0,0,$box['width']/$multi, $box['height']/$multi,$box['width'], $box['height']); imagetruecolortopalette($ds,0,256); imagepalettecopy($ds,$im); ImageColorTransparent($ds,$bgcolor); // write whereto? if ($style['format'] == 'gif') ImageGIF ($ds,$imgFile); else ImagePNG ($ds,$imgFile); ImageDestroy ($im); ImageDestroy ($ds); // and display if ($style['dev']) $border = 1; else $border = 0; if ($style['urlonly'] == 'true') return $imgUrl; else return $style['prehtml'].image_tag($imgUrl,array('style'=>'border: '.$border.'px solid #00ff00','alt'=>preg_replace("=\r\n|\r|\n|\t=", ' ', htmlspecialchars($text)))).$style['posthtml']; }
As you can see in this code styles can (at least 'default' MUST be) be configured in app.yml. This is an example style config :
imagetext:
styles:
default:
font: hockey.ttf
size: 18
format: png
So now you can use the helper in your templates :
<?php use_helper('imageText') ?> <? echo imagetext('This is my title') ?> <p>Some blah blah</p> <? echo imagetext('This is another headline style','anotherstyle') ?>
This helper uses GD so depending on which version you have installed, you might or might not handle PNG or GIF.
I've found a very nice and easy method to add transparent PNG image support to IE. This filter is an easy alternative from using Javascript or server-side php scripts. Original code from http://koivi.com/ie-png-transparency/
Add code below to your lib folder with filename pngAlphaFilter.class.php
<?php class pngAlphaFilter extends sfFilter { public function execute ($filterChain) { $filterChain->execute(); } public function executeBeforeRendering ($filterChain) { $response = $this->getContext()->getResponse(); $content = $response->getContent(); $newContent = $this->replacePngTags($content, '/images/'); $response->setContent($newContent); $filterChain->execute(); } /** * KOIVI PNG Alpha IMG Tag Replacer for PHP (C) 2004 Justin Koivisto * Version 2.0.12 * Last Modified: 12/30/2005 * * Modifies IMG and INPUT tags for MSIE5+ browsers to ensure that PNG-24 * transparencies are displayed correctly. Replaces original SRC attribute * with a binary transparent PNG file (spacer.png) that is located in the same * directory as the orignal image, and adds the STYLE attribute needed to for * the browser. (Matching is case-insensitive. However, the width attribute * should come before height. * * Also replaces code for PNG images specified as backgrounds via: * background-image: url(image.png); or background-image: url('image.png'); * When using PNG images in the background, there is no need to use a spacer.png * image. (Only supports inline CSS at this point.) * * @param string $x String containing the content to search and replace in. * @param string $img_path The path to the directory with the spacer image relative to * the DOCUMENT_ROOT. If none os supplied, the spacer.png image * should be in the same directory as PNG-24 image. * @param string $sizeMeth String containing the sizingMethod to be used in the * Microsoft.AlphaImageLoader call. Possible values are: * crop - Clips the image to fit the dimensions of the object. * image - Enlarges or reduces the border of the object to fit * the dimensions of the image. * scale - Default. Stretches or shrinks the image to fill the borders * of the object. * @param bool $inScript Boolean flag indicating whether or not to replace IMG tags that * appear within SCRIPT tags in the passed content. If used, may cause * javascript parse errors when the IMG tags is defined in a javascript * string. (Which is why the options was added.) * @return string */ public function replacePngTags($x,$img_path='',$sizeMeth='scale',$inScript=FALSE){ $arr2=array(); // make sure that we are only replacing for the Windows versions of Internet // Explorer 5.5+ $msie='/msie\s(5\.[5-9]|[6]\.[0-9]*).*(win)/i'; if( !isset($_SERVER['HTTP_USER_AGENT']) || !preg_match($msie,$_SERVER['HTTP_USER_AGENT']) || preg_match('/opera/i',$_SERVER['HTTP_USER_AGENT'])) return $x; if($inScript){ // first, I want to remove all scripts from the page... $saved_scripts=array(); $placeholders=array(); preg_match_all('`<script[^>]*>(.*)</script>`isU',$x,$scripts); for($i=0;$i<count($scripts[0]);$i++){ $x=str_replace($scripts[0][$i],'replacePngTags_ScriptTag-'.$i,$x); $saved_scripts[]=$scripts[0][$i]; $placeholders[]='replacePngTags_ScriptTag-'.$i; } } // find all the png images in backgrounds preg_match_all('/background-image:\s*url\(([\\"\\\']?)([^\)]+\.png)\1\);/Uis',$x,$background); for($i=0;$i<count($background[0]);$i++){ // simply replace: // "background-image: url('image.png');" // with: // "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader( // enabled=true, sizingMethod=scale, src='image.png');" // I don't think that the background-repeat styles will work with this... $x=str_replace($background[0][$i],'filter:progid:DXImageTransform.'. 'Microsoft.AlphaImageLoader(enabled=true, sizingMethod='.$sizeMeth. ', src=\''.$background[2][$i].'\');',$x); } // find all the IMG tags with ".png" in them $pattern='/<(input|img)[^>]*src=([\\"\\\']?)([^>]*\.png)\2[^>]*>/i'; preg_match_all($pattern,$x,$images); for($num_images=0;$num_images<count($images[0]);$num_images++){ // for each found image pattern $original=$images[0][$num_images]; $quote=$images[2][$num_images]; $atts=''; $width=0; $height=0; $modified=$original; // We do this so that we can put our spacer.png image in the same // directory as the image - if a path wasn't passed to the function if(empty($img_path)){ $tmp=split('[\\/]',$images[3][$num_images]); $this_img=array_pop($tmp); $img_path=join('/',$tmp); if(empty($img_path)){ // this was a relative URI, image should be in this directory $tmp=split('[\\/]',$_SERVER['SCRIPT_NAME']); array_pop($tmp); // trash the script name, we only want the directory name $img_path=join('/',$tmp).'/'; }else{ $img_path.='/'; } }else if(substr($img_path,-1)!='/'){ // in case the supplied path didn't end with a / $img_path.='/'; } // If the size is defined by styles, find them preg_match_all( '/style=([\\"\\\']).*(\s?width:\s?([0-9]+(px|%));).*'. '(\s?height:\s?([0-9]+(px|%));).*\\1/Ui', $images[0][$num_images],$arr2); if(is_array($arr2) && count($arr2[0])){ // size was defined by styles, get values $width=$arr2[3][0]; $height=$arr2[6][0]; // remove the width and height from the style $stripper=str_replace(' ','\s','/('.$arr2[2][0].'|'.$arr2[5][0].')/'); // Also remove any empty style tags $modified=preg_replace( '`style='.$arr2[1][0].$arr2[1][0].'`i', '', preg_replace($stripper,'',$modified)); }else{ // size was not defined by styles, get values from attributes preg_match_all('/width=([\\"\\\']?)([0-9%]+)\\1/i',$images[0][$num_images],$arr2); if(is_array($arr2) && count($arr2[0])){ $width=$arr2[2][0]; if(is_numeric($width)) $width.='px'; // remove width from the tag $modified=str_replace($arr2[0][0],'',$modified); } preg_match_all('/height=([\\"\\\']?)([0-9%]+)\\1/i',$images[0][$num_images],$arr2); if(is_array($arr2) && count($arr2[0])){ $height=$arr2[2][0]; if(is_numeric($height)) $height.='px'; // remove height from the tag $modified=str_replace($arr2[0][0],'',$modified); } } if($width==0 || $height==0){ // width and height not defined in HTML attributes or css style, try to get // them from the image itself // this does not work in all conditions... It is best to define width and // height in your img tag or with inline styles.. if(file_exists($_SERVER['DOCUMENT_ROOT'].$img_path.$images[3][$num_images])){ // image is on this filesystem, get width & height $size=getimagesize($_SERVER['DOCUMENT_ROOT'].$img_path.$images[3][$num_images]); $width=$size[0].'px'; $height=$size[1].'px'; }else if(file_exists($_SERVER['DOCUMENT_ROOT'].$images[3][$num_images])){ // image is on this filesystem, get width & height $size=getimagesize($_SERVER['DOCUMENT_ROOT'].$images[3][$num_images]); $width=$size[0].'px'; $height=$size[1].'px'; } } // end quote is already supplied by originial src attribute $replace_src_with=$quote.$img_path.'spacer.png'.$quote.' style="width: '.$width. '; height: '.$height.'; filter: progid:DXImageTransform.'. 'Microsoft.AlphaImageLoader(src=\''.$images[3][$num_images].'\', sizingMethod='. $sizeMeth.');"'; // now create the new tag from the old $new_tag=str_replace($quote.$images[3][$num_images].$quote,$replace_src_with, str_replace(' ',' ',$modified)); // now place the new tag into the content $x=str_replace($original,$new_tag,$x); } if($inScript){ // before the return, put the script tags back in. (I was having problems when there was // javascript that had image tags for PNGs in it when using this function... $x=str_replace($placeholders,$saved_scripts,$x); } return $x; } } ?>
add this to your apps/your_app/config/filters.yml
pngAlphaFilter: class: pngAlphaFilter
and put a spacer.png with 1 by 1 pixel with binary opacity in images/ directory. Or simply download one from the url below. http://koivi.com/ie-png-transparency/spacer.png
And now you are able to use the transparent PNG files as if IE fully supports it! The rest of templates need no change.