peter nack: Bild mit dynamischen Text generieren

Beitrag lesen

Hallo allerseits,

ich habe das jetzt so weit hinbekommen, dass es meinen Anspruechen genuegt.
Vielleicht kann ja der eine oder andere hier auch etwas damit anfangen.

Die Funktion arbeitet mit drei PNG-Grafiken, wobei zwei davon den Raendern entsprechen (link und rechts). Die mittlere Grafik wird mit Text befuellt (und sollte die maximale Textlaenge abdecken). Die Hoehe der Grafiken ist egal und wird bei der Kalkulation automatisch beruecksichtigt.

Des weiteren muss arial.ttf im selben Ordner wie das Script liegen (auszer es wird speziell als Parameter mit angegeben).

  
<?php  
  
  
// Call the Generator  
GenerateButton(  
	'bg_left.png',  
	'bg_center.png',  
	'bg_right.png',  
	'Hello World'  
);  
  
  
  
/**  
 * Generates a dynamic Button with Text.  
 *  
 * @example GenerateButton( 'left.png', 'center.png', 'right.png', 'Hello World', 'test.png', 'arial.ttf', 10, 0 );  
 *  
 * @param String $fileImgLeft Link of the left Part  
 * @param String $fileImgCenter link to the middle Part. Gets filled with Text.  
 * @param String $fileImgRight link of the right Part  
 * @param String $strText The Text to write  
 * @param String $filename Link for saving the Image. If null -> Browser-Output  
 * @param String $fontFile Link to the Font to use  
 * @param Integer $fontSize Size of the Font  
 * @param Integer $fontAngle The Angle used for writing the Text  
 *  
 * @return  
 */  
function GenerateButton( $fileImgLeft, $fileImgCenter, $fileImgRight, $strText, $filename=null, $fontFile='arial.ttf', $fontSize=10, $fontAngle=0 )  
{  
  
	/*  
	 * GET IMAGE RESOURCES AND CALCULATE DIMENSIONS  
	 ************************************************************/  
  
	// Get all Image-Resources  
	$imgLeft = imagecreatefrompng( $fileImgLeft );  
	$imgCenter = imagecreatefrompng( $fileImgCenter );  
	$imgRight = imagecreatefrompng( $fileImgRight );  
  
	// Calculate the Height and Width for the Image-Resources (0:width, 1:height)  
	$arrSizeLeft = getimagesize( $fileImgLeft );  
	$arrSizeCenter = getimagesize( $fileImgCenter );  
	$arrSizeRight = getimagesize( $fileImgRight );  
  
	// Calculate the needed Space for the dynamic Text  
	$arrTextbox = CalculateTextBox( $fontSize, $fontAngle, $fontFile, $strText );  
  
  
	/*  
	 * CREATE NEW IMAGE  
	 ************************************************************/  
  
	$newWidth = $arrSizeLeft[0] + $arrTextbox['width'] + $arrSizeRight[0];  
	$newHeight = max( $arrSizeLeft[1], $arrTextbox['height'], $arrSizeRight[1] );  
	$imgTarget = imagecreate( $newWidth, $newHeight );  
  
  
	/*  
	 * DEFINE COLORS  
	 ************************************************************/  
	$clrRed = imagecolorallocate( $imgTarget, 0xFF, 0x00, 0x00);  
	$clrBlack = imagecolorallocate( $imgTarget, 0x00, 0x00, 0x00);  
  
  
	/*  
	 * WRITE TEXT TO IMAGE  
	 ************************************************************/  
  
	imagefttext(  
		// the image resource  
		$imgCenter,  
		// the font size to use in points  
		$fontSize,  
		// the angle in degrees  
		$fontAngle,  
		// the x-coordinate  
		$arrTextbox['left'],  
		// the y-coordinate. TODO: donna whats the real algorithm here?  
		$arrTextbox['top'] + ($arrSizeCenter[1] / 3),  
		// the index of the desired color for the text  
		$clrBlack,  
		// the path to the TrueType font  
		$fontFile,  
		// text to be inserted into image  
		$strText  
	);  
  
  
	/*  
	 * COPY NEW IMAGE  
	 ************************************************************/  
  
	// Copy the left Part into the new Image  
	imagecopy( 	  
	  
		// destination image resource  
		$imgTarget,  
		  
		// source image resource  
		$imgLeft,  
		  
		// x-coordinate of destination point		  
		0,  
		  
		// y-coordinate of destination point  
		0,	  
		  
		// x-coordinate of source point		  
		0,  
		  
		// y-coordinate of source point  
		0, 		  
		  
		// width of source  
		$arrSizeLeft[0],  
		  
		// height of source  
		$arrSizeLeft[1]			  
	);  
  
	// Copy the center Part into the new Image  
	imagecopy( 	  
	  
		// destination image resource  
		$imgTarget, 	  
		  
		// source image resource  
		$imgCenter,  
		  
		// x-coordinate of destination point  
		$arrSizeLeft[0],	  
		  
		// y-coordinate of destination point  
		0,  
		  
		// x-coordinate of source point  
		0,  
		  
		// y-coordinate of source point  
		0, 			  
		  
		// width of source  
		$arrTextbox['width'],  
		  
		// height of source  
		$arrSizeCenter[1]		  
	);  
  
	// Copy the right Part into the new Image  
	imagecopy( 	  
	  
		// destination image resource  
		$imgTarget,  
		  
		// source image resource  
		$imgRight,  
		  
		// x-coordinate of destination point  
		$arrSizeLeft[0] + $arrTextbox['width'],  
		  
		// y-coordinate of destination point  
		0,			  
		  
		// x-coordinate of source point  
		0, 		  
		  
		// y-coordinate of source point  
		0, 		  
		  
		// width of source  
		$arrSizeRight[0], 	  
		  
		// height of source  
		$arrSizeRight[1]		  
	);  
  
  
  
	/*  
	 * OUTPUT IMAGE  
	 ************************************************************/  
	if( !isset( $filename ) )  
		header('Content-type: image/png');  
  
	// Output created Image  
	imagepng( $imgTarget, $filename );  
  
	// Destroy Image  
	imagedestroy( $imgTarget );  
	imagedestroy( $imgLeft );  
	imagedestroy( $imgRight );  
	imagedestroy( $imgCenter );  
}  
  
  
  
  
/**  
 * Calculates the required Space for a Textbox inside an Image.  
 *  
 * @author blackbart at simail dot it  
 * @see http://php.net/manual/en/function.imagettfbbox.php  
 *  
 * @param Integer $font_size The Size of the Font  
 * @param Integer $font_angle The Angle of the Text  
 * @param String $font_file Link to the Font  
 * @param String $text The desired Text  
 *  
 * @return Array (left|top|width|height)  
 */  
  
function CalculateTextBox( $font_size, $font_angle, $font_file, $text )  
{  
	$box   = imagettfbbox($font_size, $font_angle, $font_file, $text);  
	if( !$box )  
		return false;  
  
	$min_x = min( array($box[0], $box[2], $box[4], $box[6]) );  
	$max_x = max( array($box[0], $box[2], $box[4], $box[6]) );  
	$min_y = min( array($box[1], $box[3], $box[5], $box[7]) );  
	$max_y = max( array($box[1], $box[3], $box[5], $box[7]) );  
	$width  = ( $max_x - $min_x );  
	$height = ( $max_y - $min_y );  
	$left   = abs( $min_x ) + $width;  
	$top    = abs( $min_y ) + $height;  
  
  
	/**  
	 * to calculate the exact bounding box i write the text in a large image  
	 ************************************************************/  
	$img     = @imagecreatetruecolor( $width << 2, $height << 2 );  
	$white   =  imagecolorallocate( $img, 255, 255, 255 );  
	$black   =  imagecolorallocate( $img, 0, 0, 0 );  
	imagefilledrectangle($img, 0, 0, imagesx($img), imagesy($img), $black);  
  
  
	/**  
	 * for sure the text is completely in the image!  
	 ************************************************************/  
	imagettftext( $img, $font_size,  
	              $font_angle, $left, $top,  
	              $white, $font_file, $text);  
  
  
	/**  
	 * start scanning (0=> black => empty)  
	 ************************************************************/  
	$rleft  = $w4 = $width<<2;  
	$rright = 0;  
	$rbottom   = 0;  
	$rtop = $h4 = $height<<2;  
	for( $x = 0; $x < $w4; $x++ )  
	{  
		for( $y = 0; $y < $h4; $y++ )  
		{  
			if( imagecolorat( $img, $x, $y ) )  
			{  
		        $rleft   = min( $rleft, $x );  
		        $rright  = max( $rright, $x );  
		        $rtop    = min( $rtop, $y );  
		        $rbottom = max( $rbottom, $y );  
			}  
		}  
	}  
  
  
	/**  
	 * destroy img and serve the result  
	 ************************************************************/  
	imagedestroy( $img );  
  	return array( "left"   => $left - $rleft,  
    	          "top"    => $top  - $rtop,  
        	      "width"  => $rright - $rleft + 1,  
            	  "height" => $rbottom - $rtop + 1 );  
}  
  
?>