imagettfbbox () возвращает неверные размеры при использовании пробелов внутри текста - PullRequest
0 голосов
/ 22 октября 2009

Я динамически создаю графическое меню из PHP, в результате получается только 1 изображение, которое выглядит следующим образом:

One    Two    Three    Four

Проблема, однако, в том, что мне нужно определить смещение по x и ширину каждого заголовка страницы (например, смещение влево и ширину "One" в пикселях), чтобы расположить изображение с помощью css.

Все работает нормально, за исключением заголовков страниц, которые содержат пробелы - imagettfbbox () возвращает неправильные позиции. Я использую ариальный шрифт (TTF)

Какие-нибудь предложения о том, как мне обойти эту проблему?

Редактировать: я получил его сейчас, используя следующую функцию, чтобы определить границы текста:

function calculateTextBox($font_size, $font_angle, $font_file, $text) {
    $box = imagettfbbox($font_size, $font_angle, $font_file, $text);

    $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]));

    return array(
        'left' => ($min_x >= -1) ? -abs($min_x + 1) : abs($min_x + 2),
        'top' => abs($min_y),
        'width' => $max_x - $min_x,
        'height' => $max_y - $min_y,
        'box' => $box
    );
}

Редактировать 2: К сожалению, я получаю неправильные размеры при использовании шрифтов разных размеров и файлов шрифтов ...

1 Ответ

0 голосов
/ 09 мая 2014

Один из способов сделать это - использовать функцию imagecolorat , чтобы определить цвет пикселя в определенной точке изображения, это не будет самым быстрым или даже обязательно лучшим способом сделай это, но это должно сработать.

Что-то вроде этого (поиск черных пикселей) должно сработать и вернет искомые границы, которые вы можете затем преобразовать в x / координаты, если хотите:

function get_bounds($image)
{
    $height = imagesy($image);
    $width = imagesx($image);


    $to_return = new stdClass();
    $to_return->top = null;
    $to_return->bottom = null;
    $to_return->left = null;
    $to_return->right = null;

    for ($x = 0; $x < $width; $x++)
    {
        for ($y = 0; $y < $height; $y++)
        {
            $color = imagecolorat($image, $x, $y);
            $rgb = imagecolorsforindex($image, $color);

            // If its black
            if (($rgb['red'] == 0) && ($rgb['green'] == 0) && ($rgb['blue'] == 0))
            {
                if (($y < $to_return->top) || is_null($to_return->top))
                {
                    $to_return->top = $y;
                }

                if (($y > $to_return->bottom) || is_null($to_return->bottom))
                {
                    $to_return->bottom = $y;
                }

                if (($x < $to_return->left) || is_null($to_return->left))
                {
                    $to_return->left = $x;
                }

                if (($x > $to_return->right) || is_null($to_return->right))
                {
                    $to_return->right = $x;
                }
            }
        }
    }

    return $to_return;
}
...