Laravel: Как добавить текст на картинку? (часть 2/3, текст в прямоугольнике)

от автора

в ,
Время чтения: 3 мин.

Чтобы вписать текст в прямоугольник на изображении с автоматическим подбором размера шрифта, можно использовать следующий подход с пакетом intervention/image-laravel. Идея заключается в том, чтобы постепенно уменьшать размер шрифта, пока текст не поместится в заданный прямоугольник.

Пример реализации:

use Intervention\Image\Facades\Image;

// Загрузите изображение
$image = Image::make('path/to/your/image.jpg');

// Параметры прямоугольника
$rectWidth = 300; // Ширина прямоугольника
$rectHeight = 100; // Высота прямоугольника
$rectX = 50; // Координата X верхнего левого угла прямоугольника
$rectY = 50; // Координата Y верхнего левого угла прямоугольника

// Текст, который нужно вписать
$text = 'Это текст, который нужно вписать в прямоугольник';

// Начальный размер шрифта
$fontSize = 24;

// Путь к файлу шрифта
$fontPath = 'path/to/your/font.ttf';

// Цвет текста
$textColor = '#ffffff';

// Подбор размера шрифта
while ($fontSize > 0) {
    // Создаем временное изображение для измерения текста
    $tempImage = Image::canvas($rectWidth, $rectHeight);

    // Разбиваем текст на строки, чтобы он поместился в прямоугольник
    $lines = wordwrap($text, 20, "\n"); // 20 символов на строку (можно настроить)
    $lines = explode("\n", $lines);

    // Измеряем высоту текста
    $textHeight = 0;
    foreach ($lines as $line) {
        $textHeight += $fontSize * 1.2; // Учитываем межстрочный интервал
    }

    // Если текст помещается по высоте
    if ($textHeight <= $rectHeight) {
        // Проверяем ширину текста
        $maxLineWidth = 0;
        foreach ($lines as $line) {
            $lineWidth = $tempImage->getWidthForText($line, $fontSize, $fontPath);
            if ($lineWidth > $maxLineWidth) {
                $maxLineWidth = $lineWidth;
            }
        }

        // Если текст помещается по ширине
        if ($maxLineWidth <= $rectWidth) {
            break; // Текст помещается, выходим из цикла
        }
    }

    // Уменьшаем размер шрифта
    $fontSize--;
}

// Если размер шрифта стал слишком маленьким
if ($fontSize <= 0) {
    throw new \Exception('Текст не помещается в прямоугольник');
}

// Добавляем текст на изображение
$image->text($text, $rectX + $rectWidth / 2, $rectY + $rectHeight / 2, function($font) use ($fontSize, $fontPath, $textColor) {
    $font->file($fontPath);
    $font->size($fontSize);
    $font->color($textColor);
    $font->align('center');
    $font->valign('middle');
});

// Сохраняем изображение
$image->save('path/to/save/image.jpg');

// Или выводим изображение в браузер
return $image->response();

Объяснение кода:

  1. Параметры прямоугольника:
  • Задаются ширина, высота и координаты прямоугольника, в который нужно вписать текст.
  1. Подбор размера шрифта:
  • Начинаем с максимального размера шрифта ($fontSize = 24) и постепенно уменьшаем его, пока текст не поместится в прямоугольник.
  • Используем метод wordwrap, чтобы разбить текст на строки, если он слишком длинный.
  1. Проверка размеров текста:
  • Для каждой строки текста измеряем ширину с помощью метода getWidthForText.
  • Суммируем высоту всех строк с учетом межстрочного интервала.
  1. Добавление текста:
  • Если текст помещается в прямоугольник, добавляем его на изображение с выравниванием по центру.
  1. Сохранение или вывод изображения:
  • Сохраняем изображение или выводим его в браузер.

Важные моменты:

  • Шрифт: Убедитесь, что вы используете правильный путь к файлу шрифта (.ttf).
  • Межстрочный интервал: В примере используется коэффициент 1.2 для учета межстрочного интервала. Вы можете настроить его в зависимости от ваших требований.
  • Разбиение текста: Метод wordwrap разбивает текст на строки. Вы можете настроить количество символов на строку.

Этот подход позволяет автоматически подобрать размер шрифта так, чтобы текст поместился в заданный прямоугольник.

В версии v3 пакета intervention/image API немного отличается от версии v2. В частности, в v3 нет метода getWidthForText, поэтому для измерения текста нужно использовать другие подходы. Вот как можно реализовать вписывание текста в прямоугольник с подбором размера шрифта в Intervention Image v3:


Реализация для Intervention Image v3

use Intervention\Image\ImageManager;

// Создаем экземпляр менеджера изображений
$manager = new ImageManager(['driver' => 'gd']); // или 'imagick'

// Загружаем изображение
$image = $manager->make('path/to/your/image.jpg');

// Параметры прямоугольника
$rectWidth = 300; // Ширина прямоугольника
$rectHeight = 100; // Высота прямоугольника
$rectX = 50; // Координата X верхнего левого угла прямоугольника
$rectY = 50; // Координата Y верхнего левого угла прямоугольника

// Текст, который нужно вписать
$text = 'Это текст, который нужно вписать в прямоугольник';

// Начальный размер шрифта
$fontSize = 24;

// Путь к файлу шрифта
$fontPath = 'path/to/your/font.ttf';

// Цвет текста
$textColor = '#ffffff';

// Функция для измерения ширины текста
function getTextWidth($text, $fontSize, $fontPath) {
    $box = imagettfbbox($fontSize, 0, $fontPath, $text);
    return abs($box[2] - $box[0]); // Ширина текста
}

// Функция для измерения высоты текста
function getTextHeight($text, $fontSize, $fontPath) {
    $box = imagettfbbox($fontSize, 0, $fontPath, $text);
    return abs($box[7] - $box[1]); // Высота текста
}

// Подбор размера шрифта
while ($fontSize > 0) {
    // Разбиваем текст на строки
    $lines = explode("\n", wordwrap($text, 20, "\n")); // 20 символов на строку (можно настроить)

    // Измеряем общую высоту текста
    $textHeight = 0;
    foreach ($lines as $line) {
        $textHeight += getTextHeight($line, $fontSize, $fontPath) * 1.2; // Учитываем межстрочный интервал
    }

    // Если текст помещается по высоте
    if ($textHeight <= $rectHeight) {
        // Проверяем ширину каждой строки
        $fits = true;
        foreach ($lines as $line) {
            $lineWidth = getTextWidth($line, $fontSize, $fontPath);
            if ($lineWidth > $rectWidth) {
                $fits = false;
                break;
            }
        }

        // Если текст помещается по ширине
        if ($fits) {
            break; // Текст помещается, выходим из цикла
        }
    }

    // Уменьшаем размер шрифта
    $fontSize--;
}

// Если размер шрифта стал слишком маленьким
if ($fontSize <= 0) {
    throw new \Exception('Текст не помещается в прямоугольник');
}

// Добавляем текст на изображение
$y = $rectY + ($rectHeight - $textHeight) / 2; // Центрируем текст по вертикали
foreach ($lines as $line) {
    $lineHeight = getTextHeight($line, $fontSize, $fontPath) * 1.2;
    $image->text($line, $rectX + $rectWidth / 2, $y, function ($font) use ($fontSize, $fontPath, $textColor) {
        $font->file($fontPath);
        $font->size($fontSize);
        $font->color($textColor);
        $font->align('center');
        $font->valign('top');
    });
    $y += $lineHeight; // Переходим к следующей строке
}

// Сохраняем изображение
$image->save('path/to/save/image.jpg');

// Или выводим изображение в браузер
header('Content-Type: image/jpeg');
echo $image->encode('jpg');

Объяснение кода:

  1. Измерение текста:
  • В v3 нет встроенного метода для измерения текста, поэтому используются функции imagettfbbox (встроенная в PHP функция для работы с TrueType шрифтами).
  • getTextWidth и getTextHeight измеряют ширину и высоту текста.
  1. Подбор размера шрифта:
  • Начинаем с максимального размера шрифта ($fontSize = 24) и постепенно уменьшаем его, пока текст не поместится в прямоугольник.
  • Текст разбивается на строки с помощью wordwrap.
  1. Добавление текста:
  • Текст добавляется построчно с учетом межстрочного интервала.
  • Каждая строка центрируется по горизонтали и вертикали.
  1. Сохранение или вывод изображения:
  • Изображение сохраняется на диск или выводится в браузер.

Важные моменты:

  • Шрифт: Убедитесь, что путь к файлу шрифта (.ttf) указан правильно.
  • Межстрочный интервал: В примере используется коэффициент 1.2 для учета межстрочного интервала. Вы можете настроить его в зависимости от ваших требований.
  • Разбиение текста: Метод wordwrap разбивает текст на строки. Вы можете настроить количество символов на строку.

Этот код работает с Intervention Image v3 и позволяет автоматически подобрать размер шрифта так, чтобы текст поместился в заданный прямоугольник.


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Сколько будет 6 + 10?