Векторная графика в iText PDF - PullRequest
12 голосов
/ 03 января 2009

Мы используем iText для создания PDF-файлов из Java (частично основываясь на рекомендациях на этом сайте). Тем не менее, встраивание копии нашего логотипа в формат изображения, такой как GIF, приводит к тому, что он выглядит немного странно, когда люди увеличивают и уменьшают масштаб.

В идеале мы хотели бы встроить изображение в векторный формат, такой как EPS, SVG или просто шаблон PDF. Веб-сайт утверждает, что поддержка EPS была прекращена, что встраивание PDF или PS в PDF может привести к ошибкам, и в нем даже не упоминается SVG.

Наш код использует API Graphics2D, а не iText напрямую, но мы были бы готовы выйти из режима AWT и использовать сам iText, если он достиг результата. Как это можно сделать?

Ответы [ 6 ]

8 голосов
/ 03 января 2009

Согласно документации iText поддерживает следующие форматы изображений: JPEG, GIF, PNG, TIFF, BMP, WMF и EPS. Я не знаю, может ли это помочь, но я успешно использовал iTextSharp для вставки векторного WMF изображения в файл PDF:

C #:

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class Program 
{

    public static void Main() 
    {
        Document document = new Document();
        using (Stream outputPdfStream = new FileStream("output.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
        using (Stream imageStream = new FileStream("test.wmf", FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            PdfWriter.GetInstance(document, outputPdfStream);
            Image wmf = Image.GetInstance(imageStream);
            document.Open();
            document.Add(wmf);
            document.Close();
        }
    }
}
7 голосов
/ 08 января 2014

Это то, что я получил из сообщений, найденных здесь, и официальных примеров:

/**
 * Reads an SVG Image file into an com.itextpdf.text.Image instance to embed it into a PDF
 * @param svgPath SVG filepath
 * @param writer PdfWriter instance 
 * @return Instance of com.itextpdf.text.Image holding the SVG file
 * @throws IOException
 * @throws BadElementException
 */
private static Image getSVGImage(String svgPath, PdfWriter writer) throws IOException, BadElementException {
    SVGDocument svgDoc = new SAXSVGDocumentFactory(null).createSVGDocument(null, new FileReader(svgPath));

    // Try to read embedded height and width
    float svgWidth = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width").replaceAll("[^0-9.,]",""));
    float svgHeight = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height").replaceAll("[^0-9.,]",""));

    PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, svgWidth, svgHeight);
    Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight());
    GraphicsNode chartGfx = (new GVTBuilder()).build(new BridgeContext(new UserAgentAdapter()), svgDoc);
    chartGfx.paint(g2d);
    g2d.dispose();

    return new ImgTemplate(svgTempl);
}

Экземпляр Image можно легко добавить в pdf (в моем случае в качестве подписи).

5 голосов
/ 20 сентября 2012

Я нашел пару примеров от автора iText, которые используют API Graphics2D и библиотеку Apache Batik для рисования SVG в PDF.

http://itextpdf.com/examples/iia.php?id=269

http://itextpdf.com/examples/iia.php?id=263

Для моих целей мне нужно было взять строку SVG и нарисовать ее в PDF-файле с определенным размером и местоположением, сохраняя векторный характер изображения (без растеризации).

Я хотел обойти файл SVG, который, кажется, преобладает в функциях SAXSVGDocumentFactory.createSVGDocument (). Я нашел следующий пост полезным для использования текстовой строки SVG вместо простого файла.

http://batik.2283329.n4.nabble.com/Parse-SVG-from-String-td3539080.html

Вы должны создать StringReader из вашей String и передать его методу SAXSVGDocumentFactory # createDocument (String, Reader). URI, который вы передаете в качестве первого параметра в виде строки, будет URI базового документа SVG-документа. Это должно быть важно, только если ваш SVG ссылается на какие-либо внешние файлы.

С уважением,

Даниил

Источник Java, полученный из примеров iText:

// SVG as a text string.
String svg = "<svg>...</svg>";

// Create the PDF document.
// rootPath is the present working directory path.
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(rootPath + "svg.pdf")));
document.open();

// Add paragraphs to the document...
document.add(new Paragraph("Paragraph 1"));
document.add(new Paragraph(" "));

// Boilerplate for drawing the SVG to the PDF.
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
PdfContentByte cb = writer.getDirectContent();

// Parse the SVG and draw it to the PDF.
Graphics2D g2d = new PdfGraphics2D(cb, 725, 400);
SVGDocument chart = factory.createSVGDocument(rootPath, new StringReader(svg));
GraphicsNode chartGfx = builder.build(ctx, chart);
chartGfx.paint(g2d);
g2d.dispose();

// Add paragraphs to the document...
document.add(new Paragraph("Paragraph 2"));
document.add(new Paragraph(" "));

document.close();

Обратите внимание, что это приведет к созданию SVG для PDF-файла, с которым вы работаете. SVG отображается как плавающий слой над текстом. Я все еще работаю над его перемещением / масштабированием и сохраняю его встроенным в текст, но, надеюсь, это выходит за рамки вопроса.

Надеюсь, это помогло.

Приветствия

РЕДАКТИРОВАТЬ: я смог реализовать свой SVG как встроенный объект, используя следующее. Комментированные строки предназначены для добавления быстрой рамки для проверки позиционирования.

SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
SVGDocument svgDoc = factory.createSVGDocument(rootPath, new StringReader(svg));
PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width")), Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height")));
Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight());
GraphicsNode chartGfx = builder.build(ctx, svgDoc);
chartGfx.paint(g2d);
g2d.dispose();
Image svgImg = new ImgTemplate(svgTempl);
svgImg.setAlignment(Image.ALIGN_CENTER);
//svgImg.setBorder(Image.BOX);
//svgImg.setBorderColor(new BaseColor(0xff, 0x00, 0x00));
//svgImg.setBorderWidth(1);
document.add(svgImg);
3 голосов
/ 03 января 2009

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

Document document = new Document(PageSize.LETTER);
PdfWriter writer = null;
try {
    writer = PdfWriter.getInstance(document, new FileOutputStream(your file name));
} catch (Exception e) {
    // do something with exception
}

document.open();

PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
Graphics2D g2 = tp.createGraphics(width, height, new DefaultFontMapper());

// Create your graphics here - draw on the g2 Graphics object

g2.dispose();
cb.addTemplate(tp, 0, 100); // 0, 100 = x,y positioning of graphics in PDF page
document.close();
2 голосов
/ 05 декабря 2018

Это помогло мне использовать itext 7.1.3 для рендеринга SVG-изображения с помощью SVGConverter.

PdfWriter writer = new PdfWriter(new FileOutputStream("/home/users/Documents/pdf/new.pdf"));

        PdfDocument pdfDoc = new PdfDocument(writer);

        Document doc = new Document(pdfDoc);

        URL svgUrl = new File(svg).toURI().toURL();

        doc.add(new Paragraph("new pikachu"));                      

        Image image = SvgConverter.convertToImage(svgUrl.openStream(), pdfDoc);                 
        doc.add(image);

        doc.close();
0 голосов
/ 23 апреля 2019

Новая версия iText также поддерживает файлы SVG. Пожалуйста, обратитесь к этой странице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...