Масштабируйте изображение, чтобы заполнить несколько страниц с помощью iText

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

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

// Load image from external storage
Image image = Image.getInstance(path + "/img.png");
// Calculate ratio
float width = PageSize.A4.getWidth();
float heightRatio = image.getHeight() * width / image.getWidth();
Document document = new Document();
document.open();
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);
PdfPCell c = new PdfPCell(image, true);
c.setBorder(PdfPCell.NO_BORDER);
c.setPadding(0);
// Set image dimensions
c.getImage().scaleToFit(width, heightRatio);
table.addCell(c);
document.add(table);
// Write PDF file
document.close();

Какие-либо предложения?


person afe    schedule 21.12.2015    source источник
comment
В PDF каждая страница имеет свой собственный холст. Если изображение нарисовано на канве одной страницы, это может повлиять только на внешний вид этой самой страницы, на другие никак не влияет. Что вы можете сделать, так это нарисовать одно и то же изображение на нескольких страницах с соответствующим образом выбранными позициями изображения. положение изображения   -  person mkl    schedule 21.12.2015
comment
Спасибо @Бруно, понятно. Я пытаюсь решить проблему таким образом прямо сейчас. Я также нашел этот ответ ваших разработчиков . itextpdf.com/question/ (по крайней мере, я предполагаю, что это были вы;)).   -  person afe    schedule 21.12.2015
comment
Комментарий был предоставлен @mkl, но вы правы, парень на картинке — это я, а женщина рядом со мной — моя жена ;-) Решит ли этот пример вашу проблему? Это не так сложно, не так ли?   -  person Bruno Lowagie    schedule 21.12.2015
comment
Нет, @Bruno, это не так, я просто надеялся сделать это чище. В ответе ниже мое решение, основанное на том самом.   -  person afe    schedule 21.12.2015


Ответы (1)


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

// Open new PDF file
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(getSharedDirPath() + File.separator + "file.pdf"));

document.open();
PdfContentByte content = pdfWriter.getDirectContent();

// Load image from external folder
Image image = Image.getInstance(path + "/img.png");
image.scaleAbsolute(PageSize.A4);
image.setAbsolutePosition(0, 0);

float width = PageSize.A4.getWidth();
float heightRatio = image.getHeight() * width / image.getWidth();
int nPages = (int) (heightRatio / PageSize.A4.getHeight());
float difference = heightRatio % PageSize.A4.getHeight();

while (nPages >= 0) {
    document.newPage();
    content.addImage(image, width, 0, 0, heightRatio, 0, -((--nPages * PageSize.A4.getHeight()) + difference));
}

// Write PDF file
document.close();

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

person afe    schedule 21.12.2015
comment
Честно говоря, мне это решение не нравится - нет причин не делать этого. - person mkl; 21.12.2015
comment
Конечно нет. De gustibus non disputandum est. - person afe; 21.12.2015
comment
нет причин в том смысле, что нет принципиально лучшего способа сделать это - person mkl; 21.12.2015
comment
Я использую метод scaleToFit() для масштабирования изображения в одном измерении, сохраняя соотношение сторон неизменным. Например, в вашем случае я бы сделал: image.scaleToFit(PageSize.A4.getWidth(), 10000); Используя чрезвычайно большое значение в направлении y, изображение будет масштабироваться в направлении x, и высота будет адаптирована соответствующим образом, сохраняя соотношение сторон. - person Bruno Lowagie; 21.12.2015
comment
ага mkl, понял, сначала подумал, что есть способ получше. @Бруно, я попробую. Во всяком случае, я думаю, что это бесполезно, так как мне нужно вручную установить ширину и высоту в вызове addImage, не так ли? - person afe; 21.12.2015