Im making a small site for a friend, and we wanted to use a special font. I have implemented a function I have called txt2img. With this, one can get some text converted to a Only local images are allowed.-tag which points to a created img like this:

$text = "String from different places here";
txt2img($text, array(
  'font' => 'fontfile.ttf',
  'size' => '50',
  'color' => array(255,0,0) // makes a red colored text
  ...
); 

I was wondering if this is something I should contribute (I'll be happy to do so).

But I could use some guidence on integrating it with Drupal. It needs to locate font files, and be able to write to a directory which the user must have access to. Currently, I have made a "txt2img" with "cache" and "fonts" as subfolders. In "fonts" resides the .ttf fonts I want to use, the .png images are written to "cache". I suppose most users wouldn't want to bother to much with permissions, so a central location would be nice for the cache. Therefore I wanted to use the "files" directory in the site root. However, I wasn't able to read files from there. Is it possible to use it for this?

What naming should I use? I suppose most theme designers would want the function name to be small, that's why I called it txt2img() in the first place.

Where should I store the script-file(s)? I suppose a module wouldn't be very helpful for this. I solution may be to simply have the theme editors who want to use it bundle it up with their theme. That would ensure use of function names ++ corresponds.

Also, I need to get some information. What's the best way to get the following:
* Path to theme-directory (for "fonts" folder)
* Url path to the "cache"-folder (either in theme or files or...) for use in Only local images are allowed.-tag.

Thanks.

Comments

Adagio’s picture

For those interested, here is the function as it is (cleaning up and polishing now):


function txt2img($text, $user_conf = null) {
	$textimage_cache = false; // set to false if you don't want caching, maybe during development.
	
	$txt2img_directory = dirname(__FILE__).'/../../mirakla/txt2img';
	// should also include theme.
	$cache_filename = $user_conf['id'].md5($text).'.png';
	$cache_directory = $txt2img_directory.'/cache';
	$cache_directory_url = "http://www.sitename.no/mirakler/themes/mirakla/txt2img/cache";
	$cache_full_filename = $cache_directory.'/'.$cache_filename;
	
	
	// if cached, output and finish up. Don't put alot in here, needs to perform.
	// only do this if we need to create image.
	if (!$textimage_cache or !file_exists($cache_full_filename)) {
		// No cache used, we create the image.
		
		if (!is_dir($cache_directory) or !is_writable($cache_directory))
			die($cache_directory.' does not exist or is not writable');
		
		// default config, let other overwrite
		$conf = array (
			'font' => 'littlelord.ttf', // ttf fonts, may be put in the same directory as textimage
			'size' => 20, // a little dependent on server software (todo)
			'color' => array(0,0,0), // colors are accepted in this format array ($red, $green, $blue)
			'background_color' => array(255,255,255), // note: this is also made transparent
			'width' => null, // will be sat dynamically when not specified (pixelvalue)
			'height' => null,
			'padding' => 10,
		);
		if (isset($user_conf)) {
			foreach ($user_conf as $key => $value) {
				// overwrite
				$conf[$key] = $value;
			}
		}
		$conf['font'] = $txt2img_directory.'/fonts/'.$conf['font'];
		
		$text_dim = imagettfbbox($conf['size'], 0, $conf['font'], $text);
		
		$text_dim['width'] = $text_dim[2] - $text_dim[0];
		$text_dim['height'] = $text_dim[1] - $text_dim[5];
		
		if (!isset($conf['width'])) $conf['width'] = $text_dim['width'] + ($conf['padding'] * 2);
		if (!isset($conf['height'])) $conf['height'] = $text_dim['height'] + ($conf['padding'] * 2);
		
		$img = imagecreate($conf['width'], $conf['height']);
		
		// colors
		foreach (array (
			// place the keys that define a color here.
			// Keep background color first. First allocated becomes background color
			'background_color', 'color'
			) as $key) {
			$conf[$key] = imagecolorallocate($img, $conf[$key][0], $conf[$key][1], $conf[$key][2]);
		}
		
		// create text
		imagettftext(
			$img, 
			$conf['size'], 
			0, // angle
			10, // baseline x
			$conf['height'] - $conf['padding'], // baseline y
			$conf['color'],
			$conf['font'],
			$text
		);
		
		// set background color as transparent (maybe create switch on this)
		imagecolortransparent($img, $conf['background_color']);
		
		// save
		imagepng($img, $cache_full_filename);
	}
	// return html for image.
	list($width, $height, $type, $attr) = getimagesize($cache_full_filename);
	// $base_url from settings.php
	$html = '<img src="/'.$cache_directory_url.'/'.$cache_filename.'" alt="'.htmlentities($text).'" '.$attr.' />';
	
	return $html;
}

garm’s picture

thanks for sharing even tho using sifr to replace the html text with the font of your choice through the use of flash is a better solution, so you might want to look into that

Adagio’s picture

SIFR will definetly do the job. I'm gonna use that instead.

It's a little shame to have wasted time, coding. I'll paste the script here, in case anybody would like to use it:


/*
Usage: edit the first part of this file ("important things and locations") to fit your needs:
create this folder structure:
txt2img
- cache
- fonts

Put the ttf-fonts you want access to in the fonts folder, and make the cache folder writable.

in code, using:
echo txt2img("some text", array(
	"size" => 30,
	"color" => array(255,0,0),
));

will output: <img src="/path/to/cached_image.png" width="100" height="40" alt="some text" />

You may create "styles":
$colors = array(
	"black" => array(0,0,0),
	"white" => array(255,255,255),
	"red" => array(255,0,0),
	"green" => array(0,255,0),
	"blue" => array(0,0,255),
	"grey" => array(124,124,124),
	"yellow" => array(255,255,0),
	"pleasant" => array(124,124,255) // might not be all that pleasant, haven't tested :)
);
$styles = array (
	"heading" => array(
		"id" => "heading", // must repeat now :(
		"size" => 50,
		"color" => $colors["pleasant"]
	),
	"ingres" => array(
		"id" => "body",
		"size" => 15,
		"color" => $colors["yellow"],
		"background_color" => $colors["pleasant"]
	)
);
and then call something like:
echo txt2img("This is the heading!", $styles["heading"]);
echo "<br />";
echo txt2img($db_record->ingres, $styles["ingres"];

See comments in file for more info.
*/

function txt2img($text, $user_conf = null) {
	$textimage_cache = false; // set to false if you don't want caching, maybe during development.
	
	// important things and locations
	$txt2img_directory = dirname(__FILE__).'/../../mirakla/txt2img';
	$theme_name = 'mirakla';
	$cache_filename = $user_conf['id'].md5($text).'.png';
	$cache_directory = $txt2img_directory.'/cache/'.$theme_name;
	$cache_directory_url = $_GLOBALS['base_url'].'/themes'.$theme_name.'/txt2img/cache';
	$cache_full_filename = $cache_directory.'/'.$cache_filename;
	$text = strip_tags($text); // we don't want tags in the image.
	
	if (!$textimage_cache or !file_exists($cache_full_filename)) {
		// No cache we want to use, lets create the image.
		
		if (!is_dir($cache_directory)) or !is_writable($cache_directory))
			return 'Site not properly configured for this theme, '.$cache_directory.' needs to be writable.';
		
		// default config
		$conf = array (
			'font' => 'littlelord.ttf', // ttf fonts, may be put in the fonts directory
			'size' => 20, // I think this is in pixels. Note! Have to look into it.
			'color' => array(0,0,0), // Colors are accepted in this format: array ($red, $green, $blue)
			'background_color' => array(255,255,255), // Note! This is also made transparent
			'width' => null, // Will be sat dynamically when not specified (pixelvalue)
			'height' => null,
			'padding' => 10, // Adds this on each side, except when width or height is defined.
		);
		// Let user_conf overwrite default
		$conf = array_merge($conf, $user_conf, $array());
		
		// Have $conf['font'] contain the full path and filename
		$conf['font'] = $txt2img_directory.'/fonts/'.$conf['font'];
		if (!file_exists($conf['font']))
			return 'Couldn\'t find font: '.$conf['font'].;
		
		$text_dim = imagettfbbox($conf['size'], 0, $conf['font'], $text);
		
		// Make text dimensions readable
		$text_dim['width'] = $text_dim[2] - $text_dim[0];
		$text_dim['height'] = $text_dim[1] - $text_dim[5];
		
		// set the width and height we go for in conf.
		if (!isset($conf['width'])) $conf['width'] = $text_dim['width'] + ($conf['padding'] * 2);
		if (!isset($conf['height'])) $conf['height'] = $text_dim['height'] + ($conf['padding'] * 2);
		
		$img = imagecreate($conf['width'], $conf['height']) or return 'Couldn\'t create image';
		
		// Have $conf['color'...] be "real" colors. Needs $img to be created
		foreach (array (
			// place the keys that define a color here.
			// Keep background color first. First allocated becomes background color
			'background_color', 'color'
			) as $key) {
			$conf[$key] = imagecolorallocate($img, $conf[$key][0], $conf[$key][1], $conf[$key][2]) or return('Couldn\'t allocate color');
		}
		
		// create text
		imagettftext(
			$img, 
			$conf['size'], // In pixels I believe
			0, // angle, might brake the image if you change it
			10, // baseline x. todo: add this to width, question is aligning...
			$conf['height'] - $conf['padding'], // baseline y
			$conf['color'], // font-color
			$conf['font'], // path and filename of ttf-font
			$text // the text to display. Note! Perhaps split into array and do one line at the time
		);
		
		// set background color as transparent (maybe create switch on this)
		imagecolortransparent($img, $conf['background_color']);
		
		// save
		imagepng($img, $cache_full_filename) or return 'Couln\'t save image';
	}
	// return html for image.
	list($width, $height, $type, $attr) = getimagesize($cache_full_filename);
	// $base_url from settings.php
	$html = '<img src="/'.$cache_directory_url.'/'.$cache_filename.'" alt="'.htmlentities($text).'" '.$attr.' />';
	
	return $html;
}