Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 2 of 2
  1. #1
    New to the CF scene
    Join Date
    Sep 2010
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    PHP/GD Library: autosize font

    I'm creating a web application which uses GD library to write text to an image. How it works is theirs a form which asks the end-user four questions. The user inputs there data, clicks submit and the action processes the image. Thus, giving you a customized image.

    I've have two problems, they are as follows:

    1. When an user types two or more character strings, it causes each string to line break. I need to keep the text on one line.
    2. If the user types a long string of characters(14+ specifically), i need the text string to auto size down and not exceed the bounding box.


    The two files I am using are below. If you would like to see a demo of the app visit http://s203396048.onlinehome.us/paw_create/index.php

    Thanks in advance to whomever can help me with this issue.

    index.php
    Code:
    <?php
    // Include MySQL class
    require_once('inc/mysql.class.php');
    // Include database connection
    require_once('inc/global.inc.php');
    // Include functions
    require_once('inc/functions.inc.php');
    // Start the session
    session_start();
    
    // Edit the query to point to the right table
    $query = "SELECT * FROM jj_image";
    $result = mysql_query($query);
    $i = 0;
    while ($row = mysql_fetch_assoc($result))
    {
    	$colors[$i] = $row['color'];
    	$i++;
    }
    ?>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="en-US">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Paw Create</title>
    
    <link href="assets/css/styles.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript" src="assets/js/jquery.validate.js"></script>
    <script type="text/javascript" src="assets/js/main.js"></script>
    </head>
    
    <body>
    
    <div id="container">
    
      <div id="left-box">
          <?php
          $aData = array('text' => $_POST['text'],'color' => $_POST['color'],'image' => $_POST['image']);
    	  $color = $_POST['color'];
          $text = $_POST['text'];
          $image = $_POST['image'];
          $qs = http_build_query($aData);
          $renderedImage = '<img src="processImage.php?' . $qs . '" />';
          $defaultImage = "<img src='images/default.jpg'/>";
          if(empty($_POST)) {
              print($defaultImage);	  
          }
          if(isset($_POST['preview'])) {
              print($renderedImage);
          }
          if(isset($_POST['reset'])) {
            print($defaultImage);
          }
          else {
          }
          ?>
      </div>
      
      <div id="right-box">  
        <div id="imageMakerForm">
        <p>Welcome to the macypaws.com Paw Creator. This three step process allows you create your own unique custom paw wich you can proudly display where ever you like.</p><br/>
    
        <form action="<?php echo $PHP_SELF; ?>" method="post" name="imageMakerFormPost" id="imageMakerFormPost">
        
          <label for="image">Choose a paw color</label>
          <ul id="colors">
          <?php
          foreach($colors as $color)
          { 
            echo "<li id=\"$color\" class=\"square\" ><a href=\"#\" onclick=\"addImageColor('$color')\">$color</a></li>";
          } 
          ?>
          </ul>
          
          <input type="hidden" id="image" value="<?php print $image; ?>" name="image">
          <br /><br />
          
          <label for="">Choose the text color</label>
          <ul id="colors2">
          <?php
          foreach($colors as $color)
          { 
            echo "<li id=\"$color\" class=\"square2\" ><a href=\"#\" onclick=\"addTextColor('$color')\">$color</a></li>";
          }
    	  ?>
          </ul>
          <input type="hidden" id="color" value="<?php print $color; ?>" name="color">
          <?php
    	  $error = isset($_GET['color']) ? $_GET['color'] : NULL;
    	  if ('color' == $error) {echo '<p>Please select a text color!</p>';}
    	  ?>
          <br/><br/>
      
          <label for="text">What's your pet name?</label>
          <input type="text" value="<?php print $text; ?>" id="text"  class="required" name="text" />
          <br/>
    
          <input type="submit" name="preview" value="preview" id="previewImageMaker" class="button" style="float:right;" />
          <input type="submit" name="reset" value="reset" class="button" style="float:right;" onclick="clear_form_elements(this.form)"/>
    
        </form>
      </div><!-- imageMakerForm -->
    
    </div><!-- end right-box -->
    </div>
    
    </body>
    </html>
    processImage.php
    PHP Code:
    <? 

      header
    ("Content-type: image/png"); 
      
      
    define('GDBB_TOP'5);
      
    define('GDBB_LEFT'0);
      
    define('GDBB_BOTTOM'1);
      
    define('GDBB_RIGHT'2);
      
      class 
    DrawFont {
      
          function 
    DrawFont($details) {
          
    // Get size in pixels, must convert to points for GD2.
          // Because GD2 assumes 96 pixels per inch and we use more "standard" 72.
          
    $this->textSizeMax $details['size'];
          
    $this->font $details['font'];
          
    $this->text $details['text'];
          
    $this->image $details['image']; 
          
    $this->color $details['color'];
          
    $this->textAlign "C";
      
          
    $this->imageHSize $details['imageHSize'];
          
    $this->imageVSize $details['imageVSize'];
      
          
    $this->marginL $details['marginL'];
          
    $this->marginR $details['marginR'];
      
          
    $this->marginT $details['marginT'];
          
    $this->marginB $details['marginB'];
      
          
    $this->ComputeTextDimensions($this->font$this->text);
      
          }
      
      
          
    /**
           * Compute the dimensions of the text.
           */
          
    function ComputeTextDimensions($fontFile$text)
          {
              
    $this->textAreaWidth $this->imageHSize $this->marginL $this->marginR;
              
    $this->textAreaHeight $this->imageVSize $this->marginT $this->marginB;
      
              
    // Handle text on several lines
              
    $this->lines explode(' '$text);
              
    $this->lineNb count($this->lines);
      
              if (
    $this->lineNb == 1)
              {
      
                  
    $this->textSize[0] = $this->textSizeMax;
      
                  
    $bb ImageTTFBBox($this->textSize[0], 0$fontFile$text);
                  
    $this->textWidth[0] = $bb[GDBB_RIGHT] - $bb[GDBB_LEFT];
                  
    $this->maxTextWidth $this->textWidth[0];
                  
    $this->textHeight[0] = $bb[GDBB_BOTTOM] - $bb[GDBB_TOP];
      
      
                  
    $this->textSize[0] = $this->textSizeMax;
                    while (
    $this->textWidth[0] > $this->textAreaWidth && $this->textSize[0] > 1) {
      
                      
    $this->textSize[0]--;
      
                      
    $bb ImageTTFBBox($this->textWidth[$i], 0$fontFile$text);
                      
    $this->textWidth[0] = $bb[GDBB_RIGHT] - $bb[GDBB_LEFT];
                      
    $this->maxTextWidth $this->textWidth[0];
                      
    $this->textHeight[0] = $bb[GDBB_BOTTOM] - $bb[GDBB_TOP];    
                    }
              }
              else
              {
                  for (
    $i 0$i $this->lineNb$i++)
                  {
                      
    $this->textSize[$i] = $this->textSizeMax;
      
                      
    $bb ImageTTFBBox($this->textSize[$i], 0$fontFile$this->lines[$i]);
                      
    $this->textWidth[$i] = $bb[GDBB_RIGHT] - $bb[GDBB_LEFT];
                      
    $this->maxTextWidth max($this->maxTextWidth$this->textWidth[$i]);
                      
    $this->textHeight[$i] = $bb[GDBB_BOTTOM] - $bb[GDBB_TOP];
      
                    while (
    $this->textWidth[$i] > $this->textAreaWidth && $this->textSize[$i] > 1) {
      
                        
    $this->textSize[$i]--;
      
                        
    $bb ImageTTFBBox($this->textSize[$i], 0$fontFile$this->lines[$i]);
                        
    $this->textWidth[$i] = $bb[GDBB_RIGHT] - $bb[GDBB_LEFT];
                        
    $this->maxTextWidth max($this->maxTextWidth$this->textWidth[$i]);
                        
    $this->textHeight[$i] = $bb[GDBB_BOTTOM] - $bb[GDBB_TOP];      
                      }
                  }
              }
      
              
    /*
              // Is the given text area width too small for asked text?
              if ($this->maxTextWidth > $this->textAreaWidth)
              {
                  // Yes! Increase button size
                  $this->textAreaWidth = $this->maxTextWidth;
                  $this->imageHSize = $this->textAreaWidth + $this->marginL + $this->marginR;
      
      
              }
              */
      
              // Now compute the text positions given the new (?) text area width
              
    if ($this->lineNb == 1)
              {
                  
    $this->ComputeTextPosition(0$this->textSize[0], $fontFile$textfalse);
              }
              else
              {
                  for (
    $i 0$i $this->lineNb$i++)
                  {
                      
    $this->ComputeTextPosition($i$this->textSize[$i], $fontFile$this->lines[$i], false);
                  }
              }
          }
      
          
    /**
           * Compute xText and yText (text position) for the given text.
           */
          
    function ComputeTextPosition($index$textSize$fontFile$text$centerAscDesc)
          {
              switch (
    $this->textAlign)
              {
              case 
    'L':
                  
    $this->xText[$index] = $this->marginL;
                  break;
              case 
    'R':
                  
    $this->xText[$index] = $this->marginL 
                          
    $this->textAreaWidth $this->textWidth[$index];
                  break;
              case 
    'C':
              default:
                  
    $this->xText[$index] = $this->marginL 
                          (
    $this->textAreaWidth $this->textWidth[$index]) / 2;
                  break;
              }
      
              if (
    $centerAscDesc)
              {
                  
    // Must compute the difference between baseline and bottom of BB.
                  // I have to use a temporary image, as ImageTTFBBox doesn't use coordinates
                  // providing offset from the baseline.
                  
    $tmpBaseline 5;
                  
    // Image size isn't important here, GD2 still computes correct BB
                  
    $tmpImage ImageCreate(55);
                  
    $bbt ImageTTFText($tmpImage$this->textSizeMax00$tmpBaseline,
                          
    $this->color$fontFile$text);
                  
    // Bottom to Baseline
                  
    $baselinePos $bbt[GDBB_BOTTOM] - $tmpBaseline;
                  
    ImageDestroy($tmpImage);
                  
    $this->yText[$index] = $this->marginT $this->textAreaHeight -
                          (
    $this->textAreaHeight $this->textHeight) / $baselinePos 0.5;
              }
              else
              {
                  
    // Actually, we want to center the x-height, ie. to keep the baseline at same pos.
                  // whatever the text is really, ie. independantly of ascenders and descenders.
                  // This provide better looking buttons, as they are more consistent.
                  
    $bbt ImageTTFBBox($textSize0$fontFile"moxun");
                  
    $tmpHeight $bbt[GDBB_BOTTOM] - $bbt[GDBB_TOP];
                  
    $this->yText[$index] = $this->marginT $this->textAreaHeight -
                          (
    $this->textAreaHeight $tmpHeight) / 4.5 0.5;
              }
          }
      
          
    /**
           * Add the text to the button.
           */
          
    function DrawText()
          {
      
              
    $this->maxTextHeight 0;
      
              
    // find maxTextHeight
              
    for ($i 0$i $this->lineNb$i++)
              {
                if (
    $this->textHeight[$i] > $this->maxTextHeight) {
                  
    $this->maxTextHeight $this->textHeight[$i];
                }
              }
      
              for (
    $i 0$i $this->lineNb$i++)
              {
                  
    // Increase slightly line height
                  
    $yText $this->yText[$i] + $this->maxTextHeight 1.1 
                          (
    $i - ($this->lineNb 1) / 2);
      
                  
    ImageTTFText($this->image$this->textSize[$i], 0,
                          
    $this->xText[$i], $yText$this->color$this->font$this->lines[$i]);
      
      
              }
          }
      
      }
      
      
      
    // Script starts here
      
    $image_file=$_GET['image'];//image file
      
    $im imagecreatefromjpeg($image_file);//create the image from the image file
      
    $color $_GET['color'];
      if (
    $color == 'pink') {
        
    $color ImageColorAllocate($im20129115);
      }
      if (
    $color == 'lightPink') {
        
    $color ImageColorAllocate($im236121167);
      }
      if (
    $color == 'purple') {
        
    $color ImageColorAllocate($im7839150);
      }
      if (
    $color == 'lavendar') {
        
    $color ImageColorAllocate($im161115191);
      }
      if (
    $color == 'green') {
        
    $color ImageColorAllocate($im9415851);
      }
      if (
    $color == 'blue') {
        
    $color ImageColorAllocate($im24240024);
      }
      if (
    $color == 'orange') {
        
    $color ImageColorAllocate($im9415851);
      }
      if (
    $color == 'white') {
        
    $color ImageColorAllocate($im255255255);
      }
      if (
    $color == 'grey') {
        
    $color ImageColorAllocate($im128128128);
      }
      if (
    $color == 'black') {
        
    $color ImageColorAllocate($im000);
      }
      
      
    $details = array("image" => $im
                       
    "font" => "macyFont.ttf"
                       
    "text" => $_GET['text'],
                       
    "color" => $color,
                       
    "size" => 40,
                       
    "imageHSize" => 482,
                       
    "imageVSize" =>  500,
                       
    "marginL" => 10,
                       
    "marginR" => 10,
                       
    "marginT" => 5,
                       
    "marginB" => 5);
      
      
    $dofontobj =& new DrawFont($details);
      
    $dofontobj->DrawText();
      
      
    imagepng($im); 
      
    imagedestroy($im); 
      unset(
    $px);
     
    ?>

  • #2
    New to the CF scene
    Join Date
    Sep 2010
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts
    From the first post, I've found a solution to problem #1 (multiple words causing line breaks).

    In processImage.php on line 82 change:
    Code:
    $this->lines = explode(' ', $text);
    to
    Code:
    $this->lines = explode('|', $text);
    Due to my lack of experience with GD, I'm not sure if this is the correct way of stopping line breaks but it works. Hopefully this helps someone using this same code. However, I still face the issue of increasing and decreasing the text within the bounding box.

    In processImage.php on line 52 the
    Code:
    $this->textSizeMax;
    is set to 40 in the details array which tells me the font will not exceed 40 but it will not downsize if the text string exceeds the bounding box. The first "if" statement for the "computeTextDimensions" function has
    Code:
    $this->textSize[0]--;
    . One would assume this is telling the font to decrease if the "textWidth" is greater then "textAreaWidth" & "textSize" is greater then 1 but it doesn't.

    I know, It's a tough one. If I find the solution, I'll be sure to post it. Thanks in advance to who ever can help.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •