Как добавить текст к изображению?

В моем проекте я использую iText для создания PDF-документа.

Предположим, что высота страницы составляет 500pt (1 единица пользователя = 1 балл) и что я пишу текст на страницу, а затем изображение.

Если содержание и изображение требуют менее 450pt, текст предшествует изображению. Если содержимое и изображение превышают 450pt, текст пересылается на следующую страницу.

Мой вопрос: как я могу получить оставшееся свободное пространство перед написанием изображения?

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

writer.setStrictImageSequence(true); 

Если вы хотите узнать текущую позицию «курсора», вы можете использовать метод getVerticalPosition() . К сожалению, этот метод не очень изящный: для него требуется булевский параметр, который добавит новую строку (если это true ) или даст вам позицию в текущей строке (если false ).

Я не понимаю, почему вы хотите получить вертикальное положение. Это потому, что вы хотите иметь заголовок, сопровождаемый изображением, и хотите, чтобы надпись и изображение находились на одной странице?

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

Обновить:

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

Существует два подхода к достижению этого, в зависимости от фактического требования.

Подход 1:

Первый подход объясняется в примере WatermarkedImages1 . В этом примере мы создаем PdfTemplate к которому мы добавляем изображение, а также некоторый текст, написанный поверх этого изображения. Затем мы можем обернуть этот PdfTemplate внутри изображения и добавить это изображение вместе с его водяным знаком с помощью одного document.add() .

Это метод, который выполняет всю магию:

 public Image getWatermarkedImage(PdfContentByte cb, Image img, String watermark) throws DocumentException { float width = img.getScaledWidth(); float height = img.getScaledHeight(); PdfTemplate template = cb.createTemplate(width, height); template.addImage(img, width, 0, 0, height, 0, 0); ColumnText.showTextAligned(template, Element.ALIGN_CENTER, new Phrase(watermark, FONT), width / 2, height / 2, 30); return Image.getInstance(template); } 

Вот как мы добавляем изображения:

 PdfContentByte cb = writer.getDirectContentUnder(); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE1), "Bruno")); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE2), "Dog")); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE3), "Fox")); Image img = Image.getInstance(IMAGE4); img.scaleToFit(400, 700); document.add(getWatermarkedImage(cb, img, "Bruno and Ingeborg")); 

Как вы можете видеть, у нас есть очень большое изображение (картина моей жены и меня). Нам нужно масштабировать это изображение так, чтобы оно соответствовало странице. Если вы хотите этого избежать, взгляните на второй подход.

Подход 2:

Второй подход объясняется в примере WatermarkedImages2 . В этом случае мы добавляем каждое изображение в PdfPCell . Этот PdfPCell масштабирует изображение так, чтобы оно соответствовало ширине страницы. Чтобы добавить водяной знак, мы используем событие ячейки:

 class WatermarkedCell implements PdfPCellEvent { String watermark; public WatermarkedCell(String watermark) { this.watermark = watermark; } public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS]; ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, new Phrase(watermark, FONT), (position.getLeft() + position.getRight()) / 2, (position.getBottom() + position.getTop()) / 2, 30); } } 

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

 PdfPCell cell; cell = new PdfPCell(Image.getInstance(IMAGE1), true); cell.setCellEvent(new WatermarkedCell("Bruno")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE2), true); cell.setCellEvent(new WatermarkedCell("Dog")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE3), true); cell.setCellEvent(new WatermarkedCell("Fox")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE4), true); cell.setCellEvent(new WatermarkedCell("Bruno and Ingeborg")); table.addCell(cell); 

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

Рассмотрение:

Очевидно, что оба подхода имеют другой результат из-за выбора дизайна. Пожалуйста, сравните полученные PDF-файлы, чтобы увидеть разницу: watermark_template.pdf и watermark_table.pdf

  • Spring Boot и несколько внешних файлов конфигурации
  • Отслеживание причины «непригодности автопроксирования» Spring
  • Невозможно десериализовать экземпляр java.util.ArrayList из токена START_OBJECT
  • Как добавить зависимости в объект, созданный самостоятельно, весной?
  • spring Exception при запуске приложения в WebSphere с java 8
  • tomcat7 - jdbc datasource - это, скорее всего, создаст утечку памяти
  • Spring: namespace vs contextConfigИнтересные параметры размещения в web.xml
  • запросить бобовые бобы весенним тестированием
  • Разверните Spring Boot для Tomcat
  • Spring Java Config vs Jboss 7
  • Использование методов PUT и DELETE в Spring MVC
  • Давайте будем гением компьютера.