我想在图片下添加文字(制作令人沮丧的图片)。所以我扩展了它的高度并在底部增加了额外的高度。我需要的是编写文本:
Top text
bottom longer text
一切都在 PHP GD 库中。问题是 - 我不知道如何计算字体大小的比例并将其居中。 我的功能不起作用,计算字体大小错误,文本对齐错误..
private function __generate_text_pref($type)
{
$data = array();
switch ($type) {
case 'title':
$data['percent'] = 0.9;
$data['text_width_percent'] = 0.8;
break;
case 'subtitle':
$data['percent'] = 0.92;
$data['text_width_percent'] = 0.6;
break;
default:
$data['percent'] = 0.86;
$data['text_width_percent'] = 0.8;
break;
}
list($img_width, $img_height) = getimagesize($this->settings['__temp_image']);
// find font-size for $txt_width = 80% of $img_width...
$data['font_size'] = 1;
$txt_max_width = intval($data['text_width_percent'] * $img_width);
do {
$data['font_size'] ++;
$p = imagettfbbox($data['font_size'], 0, $this->settings['font'], $this->settings['__title']);
$txt_width = $p[2] - $p[0];
// $txt_height=$p[1]-$p[7]; // just in case you need it
} while ( $txt_width <= $txt_max_width );
//$data['font_size'] = ($data['font_size'] > 24) ? 24 : $data['font_size'];
return array(
'font_size' => $data['font_size'],
'asys' => array(
'x' => (($img_width - $txt_width) / 2),
'y' => ($img_height * $data['percent'])
)
);
}
它应该具有标题和副标题的默认字体大小,并且仅在文本较长且不适合包装器的情况下将其减小到较低..
最佳答案
由于在无法实际“看到”文本的情况下确定文本是否比其边界框宽似乎非常困难,因此这就是我想出的解决方案。
我使用了一张 1000 像素宽的图片并将其调整为 600。当然,您显然已经解决了所有这些问题。
我不太擅长写答案(尽管代码已经过测试并且确实有效)所以我希望这会有所帮助。
<?php
$FormAction = $_SERVER['PHP_SELF'];
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) { // if form is submitted
// get original image
$fileName = $_FILES["ImageName"]["name"]; // The file name
$fileTempLoc = $_FILES["ImageName"]["tmp_name"]; // File in the PHP tmp folder
$type = strtolower(substr(strrchr($fileName,"."),1));
if($type == 'jpeg') { $type = 'jpg'; }
// Temporary upload image name
$original_image = $_FILES['ImageName']['tmp_name'];
// Name to save the image as - in this case the same as the original
$new_image = $_FILES['ImageName']['name'];
// Get the image dimensions
$uploaded_size = getimagesize($original_image);
$uploaded_imgw = $uploaded_size[0];
$uploaded_imgh = $uploaded_size[1];
// Maximum image width and height
$max_width = "600";
$max_height = "600";
// Thumbnail image width and height
$thumbnail_max_width = "100";
$thumbnail_max_height = "100";
// Check to see if we need to resize the image
if ($uploaded_imgw > 600 || $uploaded_imgh > 600) { // if image is larger than 600x600
// Resize image using GD2 cmd
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($original_image);
$ratio_orig = $width_orig/$height_orig;
// resize our image proportionately maintaining its original aspect
if ($thumbnail_max_width/$thumbnail_max_height > $ratio_orig) {
$width = $max_width*$ratio_orig; //576
$height = $max_height;
} else {
$height = $max_height/$ratio_orig; // 576
$width = $max_width; //600
}
// Resample / Resize the image
$orig_image_p = imagecreatetruecolor($width, $height);
if($type == "gif" || $type == "png"){
imagecolortransparent($orig_image_p, imagecolorallocate($orig_image_p, 0, 0, 0));
}
if($type == "jpg") {
$temp_image = imagecreatefromjpeg($original_image);
}
if($type == "gif") {
$temp_image = imagecreatefromgif($original_image);
}
if($type == "png") {
$temp_image = imagecreatefrompng($original_image);
}
imagecopyresampled($orig_image_p, $temp_image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
if($type == "jpg") {
imagejpeg($orig_image_p, $original_image, 80);
}
if($type == "gif") {
imagegif($orig_image_p, $original_image);
}
if($type == "png") {
imagepng($orig_image_p, $original_image, 9);
}
move_uploaded_file($original_image, '../../Images/'.$new_image);
imagedestroy($temp_image);
imagedestroy($orig_image_p);
} else { // if image is smaller than 900x900
$small_image_p = imagecreatetruecolor($uploaded_imgw, $uploaded_imgh);
if($type == "gif" || $type == "png"){
imagecolortransparent($small_image_p, imagecolorallocate($small_image_p, 0, 0, 0));
}
if($type == "jpg") {
$small_temp_image = imagecreatefromjpeg($original_image);
}
if($type == "gif") {
$small_temp_image = imagecreatefromgif($original_image);
}
if($type == "png") {
$small_temp_image = imagecreatefrompng($original_image);
}
imagecopyresampled($small_image_p, $small_temp_image, 0, 0, 0, 0, $uploaded_imgw, $uploaded_imgh, $uploaded_imgw, $uploaded_imgh);
if($type == "jpg") {
imagejpeg($small_image_p, $original_image, 80);
}
if($type == "gif") {
imagegif($small_image_p, $original_image);
}
if($type == "png") {
imagepng($small_image_p, $original_image, 9);
}
move_uploaded_file($original_image, '../../Images/'.$new_image);
imagedestroy($small_temp_image);
imagedestroy($small_image_p);
} // end if smaller than 600x600
// Get the image we will work with
$new_img_src = '../../Images/'.$new_image;
list($new_width, $new_height) = getimagesize($new_img_src);
if($type == 'jpg') {
$im = imagecreatefromjpeg($new_img_src);
}
if($type == 'png') {
$im = imagecreatefrompng($new_img_src);
}
if($type == 'gif') {
$im = imagecreatefromgif($new_img_src);
}
// Create a blank canvas for our new image
$new_image_p = imagecreatetruecolor($new_width, $new_height);
if($type == "gif" || $type == "png"){
imagecolortransparent($new_image_p, imagecolorallocate($new_image_p, 0, 0, 0));
}
if($type == 'jpg') {
$new_temp_image = imagecreatefromjpeg($new_img_src);
}
if($type == 'png') {
$new_temp_image = imagecreatefrompng($new_img_src);
}
if($type == 'gif') {
$new_temp_image = imagecreatefromgif($new_img_src);
}
imagecopyresampled($new_image_p, $new_temp_image, 0, 0, 0, 0, $new_width, $new_height, $new_width, $new_height);
// set dimensions for our canvas
$adj_width = $new_width+40;
$adj_height = $new_height+120;
$bkgrd = imagecreatetruecolor($adj_width, $adj_height);
imagefilledrectangle($bkgrd, 0, 0, $adj_width, $adj_height, 0x000000);
$sx = imagesx($bkgrd)-imagesx($bkgrd)+20;
$sy = imagesy($bkgrd)-imagesy($bkgrd)+20;
// Place our original image on the canvas centered and 20px from the top
imagecopymerge($bkgrd, $new_image_p, $sx, $sy, 0, 0, imagesx($bkgrd), imagesy($bkgrd), 100);
// Save the image to file and free memory
if($type == "jpg") {
imagejpeg($bkgrd, $new_img_src, 80);
}
if($type == "gif") {
imagegif($bkgrd, $new_img_src);
}
if($type == "png") {
imagepng($bkgrd, $new_img_src, 9);
}
imagedestroy($im);
imagedestroy($new_image_p);
imagedestroy($bkgrd);
//Now we create our text as images to be merged with our new image
// check width of bounding box
function calculateTextBox($text,$fontFile,$fontSize,$fontAngle) {
/************
simple function that calculates the *exact* bounding box (single pixel precision).
The function returns an associative array with these keys:
left, top: coordinates you will pass to imagettftext
width, height: dimension of the image you have to create
*************/
$rect = imagettfbbox($fontSize,$fontAngle,$fontFile,$text);
$minX = min(array($rect[0],$rect[2],$rect[4],$rect[6]));
$maxX = max(array($rect[0],$rect[2],$rect[4],$rect[6]));
$minY = min(array($rect[1],$rect[3],$rect[5],$rect[7]));
$maxY = max(array($rect[1],$rect[3],$rect[5],$rect[7]));
return array(
"left" => abs($minX) - 1,
"top" => abs($minY) - 1,
"width" => $maxX - $minX,
"height" => $maxY - $minY,
"box" => $rect
);
}
$text_string = $_POST['TopLine']; //"This is a very long first line to see what happens if it is too long";
$font_ttf = "arial.ttf";
$font_size = 22;
$text_angle = 0;
$text_padding = 10; // Img padding - around text
$the_box = calculateTextBox($text_string, $font_ttf, $font_size, $text_angle);
$imgWidth = $the_box["width"] + $text_padding;
$imgHeight = $the_box["height"] + $text_padding;
$image = imagecreatetruecolor($imgWidth,$imgHeight);
imagefill($image, imagecolorallocate($image, 0, 0, 0));
$color = imagecolorallocate($image, 255, 255, 255);
imagettftext($image,
$font_size,
$text_angle,
$the_box["left"] + ($imgWidth / 2) - ($the_box["width"] / 2),
$the_box["top"] + ($imgHeight / 2) - ($the_box["height"] / 2),
$color,
$font_ttf,
$text_string);
// save file
imagepng($image, '../../Images/NewTopImg.png', 9);
// destroy the image and start over
imagedestroy($image);
$text_string = $_POST['BottomLine']; //"This is a very long second line to see what happens if it is too long. Even a longer line than the first one.";
$font_ttf = "arial.ttf";
$font_size = 16;
$text_angle = 0;
$text_padding = 10; // Img padding - around text
$the_box = calculateTextBox($text_string, $font_ttf, $font_size, $text_angle);
$imgWidth = $the_box["width"] + $text_padding;
$imgHeight = $the_box["height"] + $text_padding;
$image = imagecreatetruecolor($imgWidth,$imgHeight);
imagefill($image, imagecolorallocate($image, 0, 0, 0));
$color = imagecolorallocate($image, 255, 255, 255);
imagettftext($image,
$font_size,
$text_angle,
$the_box["left"] + ($imgWidth / 2) - ($the_box["width"] / 2),
$the_box["top"] + ($imgHeight / 2) - ($the_box["height"] / 2),
$color,
$font_ttf,
$text_string);
// save file
imagepng($image, '../../Images/NewBottomImg.png', 9);
imagedestroy($image);
// Now merge the three images together
//function merge($filename_x, $filename_y, $filename_result) {
// Get dimensions for specified images
$filename_vs = '../../Images/'.$new_image;
$filename_x = '../../Images/NewTopImg.png';
$filename_y = '../../Images/NewBottomImg.png';
list($width_x, $height_x) = getimagesize($filename_x);
list($width_y, $height_y) = getimagesize($filename_y);
list($width_vs, $height_vs) = getimagesize($filename_vs);
// before we go any farther lets find out if our text is wider than our image
if($width_x > $new_width) { // if it is too wide lets resize it
// create smaller image using GD2 cmd to the smallest side
$line1_img_src = '../../Images/NewTopImg.png';
$line1_img_path = '../../Images/NewTopImg.png';
list($src_width, $src_height) = getimagesize($line1_img_src);
$min = $new_width; // set our max width to that of the original image
$ratio = $src_height/$src_width;
$line1_width = $min;
$Line1_height = round($min * $ratio);
$blank_image_line1 = imagecreatetruecolor($line1_width, $Line1_height);
imagecolortransparent($blank_image_line1, imagecolorallocate($blank_image_line1, 0, 0, 0));
$image = imagecreatefrompng($line1_img_src);
imagecopyresampled($blank_image_line1, $image, 0, 0, 0, 0, $line1_width, $Line1_height, $src_width, $src_height);
imagepng($blank_image_line1, $line1_img_path, 9);
imagedestroy($blank_image_line1);
imagedestroy($image);
// Because we resized the first line we need to get the new dimensions
$filename_x = '../../Images/NewTopImg.png';
list($width_x, $height_x) = getimagesize($filename_x);
// End resize first line
}
// Now lets check line two
if($width_y > $new_width) { // if it is too wide lets resize it
// create smaller image using GD2 cmd to the smallest side
$line2_img_src = '../../Images/NewBottomImg.png';
$line2_img_path = '../../Images/NewBottomImg.png';
list($src_width, $src_height) = getimagesize($line2_img_src);
$min = $new_width; // set our max width to that of the original image
$ratio = $src_height/$src_width;
$line2_width = $min;
$line2_height = round($min * $ratio);
$blank_image_line2 = imagecreatetruecolor($line2_width, $line2_height);
imagecolortransparent($blank_image_line2, imagecolorallocate($blank_image_line2, 0, 0, 0));
$image = imagecreatefrompng($line2_img_src);
imagecopyresampled($blank_image_line2, $image, 0, 0, 0, 0, $line2_width, $line2_height, $src_width, $src_height);
imagepng($blank_image_line2, $line2_img_path, 9);
imagedestroy($blank_image_line2);
imagedestroy($image);
// Because we resized the second line we need to get the new dimensions
$filename_y = '../../Images/NewBottomImg.png';
list($width_y, $height_y) = getimagesize($filename_y);
// End resize second line
}
// Create new image with desired dimensions
$image = imagecreatetruecolor($width_vs, $height_vs);
// Load images and then copy to destination image
if($type == "gif" || $type == "png"){
imagecolortransparent($image, imagecolorallocate($image, 0, 0, 0));
}
if($type == 'jpg') {
$image_vs = imagecreatefromjpeg($filename_vs);
}
if($type == 'png') {
$image_vs = imagecreatefrompng($filename_vs);
}
if($type == 'gif') {
$image_vs = imagecreatefromgif($filename_vs);
}
$image_x = imagecreatefrompng($filename_x);
$image_y = imagecreatefrompng($filename_y);
//set location for merged images
$vs_x = imagesx($image); // width of our completed image
$vs_y = imagesy($image);// height of our completed image
$x_x = $width_x; // width of the top line
$x_x = ($vs_x/2)-($x_x/2);
$x_y = $new_height+30; // height of the original img + 20px we dropped it from the top of the canvas + 10px more for spacing below our "picture" placed on the canvas
$y_x = $width_y; // width of the bottom line
$y_x = ($vs_x/2)-($y_x/2);
$y_y = $new_height+70; // height of the original img + 20px we dropped it from the top of the canvas + 40px more for spacing below the first line of text
imagecopy($image, $image_vs, 0, 0, 0, 0, $width_vs, $height_vs);
imagecopy($image, $image_x, $x_x, $x_y, 0, 0, $width_vs, $height_vs);
imagecopy($image, $image_y, $y_x, $y_y, 0, 0, $width_vs, $height_vs);
// set dimensions for our canvas
$adj_width = $new_width+40;
$adj_height = $new_height+120;
$bkgrd = imagecreatetruecolor($adj_width, $adj_height);
imagefilledrectangle($bkgrd, 0, 0, $adj_width, $adj_height, 0x000000);
$sx = imagesx($bkgrd)-imagesx($bkgrd)+20;
$sy = imagesy($bkgrd)-imagesy($bkgrd)+20;
// Place our original image on the canvas centered and 20px from the top
imagecopymerge($bkgrd, $new_image_p, $sx, $sy, 0, 0, imagesx($bkgrd), imagesy($bkgrd), 100);
// Save the image to file and free memory
if($type == "jpg") {
imagejpeg($image, $filename_vs, 80);
}
if($type == "gif") {
imagegif($image, $filename_vs);
}
if($type == "png") {
imagepng($image, $filename_vs, 9);
}
// Clean up
imagedestroy($image);
imagedestroy($image_x);
imagedestroy($image_y);
imagedestroy($image_vs);
//merge($filename_x, $filename_y, $filename_vs);
} // end if form submitted
?>
<table width="800" border="0" cellspacing="0" cellpadding="5" align="center">
<tr>
<td><div id="FormContainer">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div id="Heading">IMAGE UPLOAD</div></td>
</tr>
</table>
<form enctype="multipart/form-data" id="form1" name="form1" method="post" action="<?php echo $FormAction; ?>">
<table border="0" align="center" cellpadding="5" cellspacing="0">
<tr>
<td colspan="2">Only JPG, JPEG, PNG and GIF files are allowed.</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td><div align="right" class="Strong">File:</div></td>
<td><input name="ImageName" type="file" id="ImageName" size="50" /></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td nowrap="nowrap" class="ElementTitle"><div align="right">Line 1 Text:</div></td>
<td><input name="TopLine" type="text" id="TopLine" value="This is a very long first line to see what happens if it is too long" size="75" maxlength="100" /></td>
</tr>
<tr>
<td nowrap="nowrap" class="ElementTitle"><div align="right">Line 2 Text:</div></td>
<td><input name="BottomLine" type="text" id="BottomLine" value="This is a very long second line to see what happens if it is too long. Even a longer line than the first one." size="75" maxlength="100" /></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td colspan="2"><table width="150" border="0" align="center" cellpadding="5" cellspacing="0">
<tr>
<td><div align="center" style="width:80px; height:37px;">
<input name="Submit" type="submit" class="Submit" value="Upload" />
</div></td>
<td><div align="center" style="width:75px; height:37px;">
<input name="Submit22" type="reset" class="Submit" value="Reset" />
</div></td>
</tr>
</table></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table><input type="hidden" name="MM_insert" id="MM_insert" value="form1">
</form>
</div><!-- end form container -->
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
基本上你正在做的是
- 为第一行和第二行创建两个图像
- 检查这些图片是否比您现有的图片宽 如果是的话
- 调整它们的大小以适合您的原始图像宽度
- 最后将所有三张图片合并为一张。
您可以在此处更改默认文本大小...$font_size = 22
和 $font_size = 16
分别用于第一行和第二行。
不要忘记上传您的 ttf 字体文件并正确指向它。
最后,您可以在最后添加代码以在完成后删除您的两个临时文件。
我在此处修改和使用的 calculateTextBox 函数部分归功于 jodebrabec。 You can find it here
关于php - 按比例在图片上写文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32250008/