Question

I have a list of words in an array which I am able to write to a PNG using imagettftext.

imagettfbbox is being used to determine where the next word should go.

I would like to check if the current word I am trying to write to an image will overlap with the previous word that has already been written (I assume imagettfbbox is the way to go?)

The following is what I assume the code would look like (I cannot get my head around how to do this!):

If the current word will overlap with previous word
  Position current word further down an ever increasing spiral until it doesn't collide

At the moment my code will write all words to an image without overlap but doesn't have any angles (which is something I would like it to handle in the future - without word collision)

$handle = ImageCreate(1000, 500) or die ("Cannot Create image");

//Background Colour
$bg_color = ImageColorAllocate($handle, 0, 150, 255); 
$txt_color = ImageColorAllocate($handle, 0, 0, 0);

// First we create our bounding box for the first text
$bbox = imagettfbbox($fontsize, $angle, $font, $word);

// Set X Coord
$x = ($bbox[2] - $bbox[0]);

// Set Y Coord
$y += ($bbox[7] - $bbox[1]);

// Write word to image
ImageTTFText($image, $fontsize, $angle, $x, $y, $txt_color, $font, $word);

This code at the moment as you can see is pretty static, and will also not confine the words into the size of the image (also something I would like).

Any help would be greatly appreciated, I have been stuck on this for the past two weeks and would really like to move on!

Was it helpful?

Solution 2

It took me a while but I figured it out...

This is how I did it:

Where $i is the number of the word to be written to the image.

do{
    $startx += ($i / 2 * cos($i));
    $starty += ($i / 2 * sin($i));
}while(intersection($boundingbox, $startx, $starty, $previouscoordinates, $i));

The intersects method takes the current word to be written, its bounding box coordinates, start (x,y), and all coordinates of previous words that have been written to the image. The method checks if the current word to be written intersects with any of the previous words for this start (x,y) point.

OTHER TIPS

I haven't done this in a long time, but I once wrote an image processing class a long time ago. Here is a snippet from my function that does a similar task. My whole function actually accounted for vertical, centered, left/right aligned, bold, TTF/non-TTF, and word-wrapping (and any logical combination of those). If you require word-wrapping, you have to do calculations on the string and break it into an array of lines before even messing with the bounding boxes.

This code is inside a foreach loop that iterated the broken-up string. Here is the part that does the box calculation like you are doing. It looks similar, but my algorithm was a bit different.

// Calculate Deviation
$dx = ($box[2] - $box[0]) / 2 - ($box[2] - $box[4]) / 2; // Left-Right
$dy = ($box[3] - $box[1]) / 2 + ($box[7] - $box[1]) / 2; // Top-Bottom

// Some calculations for alignments were here

// Draw the text
$success = imagettftext($this->image, $this->settings['font'], (int)$angle, $x, $y, $color, $font_file, $string);

I can provide the full function if you are interested in the rest of what I described it did. It utilized bitmasks for flags. I don't remember if it handled angles too well to be honest, but I think it did mostly.

Hopefully that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top