Рубрики
Без рубрики

Добавление текста к изображению на Java

Узнайте, как добавлять текст к изображениям на Java

Автор оригинала: baeldung.

1. Обзор

Иногда нам нужно добавить текст к изображению или набору изображений. Сделать это вручную легко с помощью инструмента редактирования изображений. Но когда мы хотим добавить один и тот же текст одним и тем же способом к значительному количеству изображений, было бы очень полезно сделать это программно.

В этом кратком уроке мы узнаем, как добавить текст к изображениям с помощью Java.

2. Добавление текста к изображению

Чтобы прочитать изображение и добавить текст, мы можем использовать разные классы. В последующих разделах мы рассмотрим несколько вариантов.

2.1. ImagePlus и процессор обработки изображений

Во-первых, давайте посмотрим как использовать классы ImagePlus и Процессор изображений , доступные в библиотеке ImageJ . Чтобы использовать эту библиотеку, нам нужно включить эту зависимость в наш проект:


    net.imagej
    ij
    1.51h

Для чтения изображения мы будем использовать метод open Image static. Результат этого метода будет сохранен в памяти с помощью объекта ImagePlus :

ImagePlus image = IJ.openImage(path);

Как только мы загрузим изображение в память, давайте добавим к нему текст с помощью класса ImageProcessor :

Font font = new Font("Arial", Font.BOLD, 18);

ImageProcessor ip = image.getProcessor();
ip.setColor(Color.GREEN);
ip.setFont(font);
ip.drawString(text, 0, 20);

С помощью этого кода мы добавляем указанный текст зеленым цветом в левом верхнем углу изображения. Обратите внимание, что мы задаем позицию, используя второй и третий аргументы метода drawString , которые представляют количество пикселей слева и сверху соответственно.

2.2. Буферизованное изображение и графика

Далее мы увидим, как мы можем достичь того же результата, используя классы BufferedImage и Graphics . Стандартная сборка Java включает в себя эти классы, поэтому нет необходимости в дополнительных библиотеках.

Так же , как мы использовали open Image из ImageJ , мы будем использовать метод read , доступный в ImageIO :

BufferedImage image = ImageIO.read(new File(path));

Как только мы загрузим изображение в память, давайте добавим к нему текст с помощью класса Graphics :

Font font = new Font("Arial", Font.BOLD, 18);

Graphics g = image.getGraphics();
g.setFont(font);
g.setColor(Color.GREEN);
g.drawString(text, 0, 20);

Как мы видим, обе альтернативы очень похожи по способу использования. В этом случае второй и третий аргументы метода drawString задаются таким же образом, как и для метода ImageProcessor .

2.3. Розыгрыш на основе атрибутивного характералитератора

Метод drawString доступен в Графика позволяет нам печатать текст с помощью AttributedCharacterIterator . Это означает , что вместо использования простой Строки мы могли бы использовать текст с некоторыми связанными свойствами. Давайте рассмотрим пример:

Font font = new Font("Arial", Font.BOLD, 18);

AttributedString attributedText = new AttributedString(text);
attributedText.addAttribute(TextAttribute.FONT, font);
attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN);

Graphics g = image.getGraphics();
g.drawString(attributedText.getIterator(), 0, 20);

Этот способ печати текста дает нам возможность напрямую связать формат со строкой |, что чище, чем изменение свойств объекта Graphics всякий раз, когда мы хотим изменить формат.

3. Выравнивание текста

Теперь, когда мы узнали, как добавить простой текст в левом верхнем углу изображения, давайте посмотрим, как мы можем добавить этот текст в определенные позиции .

3.1. Центрированный текст

Первый тип выравнивания, которым мы займемся, – это центрирование текста . Чтобы динамически установить правильную позицию, в которой мы хотим написать текст, нам нужно выяснить некоторую информацию:

  • Размер изображения
  • Размер шрифта

Эту информацию можно получить очень легко. В случае размера изображения доступ к этим данным можно получить с помощью методов getWidth и getHeight объекта BufferedImage . С другой стороны, чтобы получить данные, связанные с размером шрифта, нам нужно использовать объект FontMetrics .

Давайте рассмотрим пример, где мы вычисляем правильную позицию для нашего текста и рисуем ее:

Graphics g = image.getGraphics();

FontMetrics metrics = g.getFontMetrics(font);
int positionX = (image.getWidth() - metrics.stringWidth(text)) / 2;
int positionY = (image.getHeight() - metrics.getHeight()) / 2 + metrics.getAscent();

g.drawString(attributedText.getIterator(), positionX, positionY);

3.2. Текст выровнен в правом нижнем углу

Следующий тип выравнивания, который мы увидим, – это нижний правый . В этом случае нам нужно динамически получать правильные позиции:

int positionX = (image.getWidth() - metrics.stringWidth(text));
int positionY = (image.getHeight() - metrics.getHeight()) + metrics.getAscent();

3.3. Текст, расположенный в левом верхнем углу

Наконец, давайте посмотрим как напечатать наш текст в левом верхнем углу :

int positionX = 0;
int positionY = metrics.getAscent();

Остальные выравнивания можно вывести из трех, которые мы видели.

4. Адаптация размера текста На основе изображения

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

Во-первых, нам нужно получить ожидаемую ширину и высоту текста, используя базовый шрифт. Для этого мы будем использовать классы FontMetrics , GlyphVector , и Shape .

FontMetrics ruler = graphics.getFontMetrics(baseFont);
GlyphVector vector = baseFont.createGlyphVector(ruler.getFontRenderContext(), text);
    
Shape outline = vector.getOutline(0, 0);
    
double expectedWidth = outline.getBounds().getWidth();
double expectedHeight = outline.getBounds().getHeight();

Следующим шагом является проверка необходимости изменения размера шрифта. Для этого давайте сравним ожидаемый размер текста и размер изображения:

boolean textFits = image.getWidth() >= expectedWidth && image.getHeight() >= expectedHeight;

Наконец, если ваш текст не вписывается в изображение, мы должны уменьшить размер шрифта. Для этого мы будем использовать метод deriveFont :

double widthBasedFontSize = (baseFont.getSize2D()*image.getWidth())/expectedWidth;
double heightBasedFontSize = (baseFont.getSize2D()*image.getHeight())/expectedHeight;

double newFontSize = widthBasedFontSize < heightBasedFontSize ? widthBasedFontSize : heightBasedFontSize;
newFont = baseFont.deriveFont(baseFont.getStyle(), (float)newFontSize);

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

5. Резюме

В этой статье мы рассмотрели, как писать текст на изображении, используя различные методы.

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

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

Как всегда, полный исходный код статьи доступен на GitHub .