Я хочу получить все объекты, кроме текстового объекта в виде изображения из PDF, используя iTextSharp - PullRequest
0 голосов
/ 02 января 2019

Я разрабатываю программу для преобразования PDF в PPTX по определенным причинам, используя iTextSharp. Пока что я сделал, чтобы получить все текстовые объекты и графические объекты и местоположения. Но мне трудно получить объекты Table без текстов. На самом деле было бы лучше, если бы я мог получить их в виде изображений. Мой план состоит в том, чтобы объединить все объекты, кроме текстовых, в качестве фонового изображения и разместить текстовые объекты в нужных местах. Я пытался найти подобные вопросы здесь, но безуспешно. Если кто-нибудь знает, как сделать эту конкретную работу, пожалуйста, ответьте. Спасибо.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Вы говорите

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

но вы не вдаваетесь в подробности, как вы это делаете. Я предполагаю, что вы используете соответствующую IRenderListener реализацию.

Но IRenderListener, как вы сами узнали,

только извлекает изображения и тексты.

Основными недостающими объектами являются пути и их использование.

Чтобы извлечь их, вы должны реализовать IExtRenderListener, который расширяет IRenderListener, но также получает информацию о путях. Чтобы понять методы обратного вызова, сначала обратите внимание, как инструкции, связанные с путем, работают в PDF-файлах:

  • Сначала есть инструкции для построения фактического пути; эти инструкции по существу

    • перейти в какую-то позицию,
    • добавить строку к некоторой позиции от предыдущей позиции,
    • добавить кривую Безье к некоторой позиции от предыдущей позиции, используя некоторые контрольные точки, или
    • добавить вертикальный прямоугольник в некоторой позиции, используя некоторую информацию о ширине и высоте.
  • Затем есть необязательная инструкция для пересечения текущего пути клипа с сгенерированным путем.

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

Это соответствует обратным вызовам, которые вы получаете в своей реализации IExtRenderListener:

/**
 * Called when the current path is being modified. E.g. new segment is being added,
 * new subpath is being started etc.
 *
 * @param renderInfo Contains information about the path segment being added to the current path.
 */
void ModifyPath(PathConstructionRenderInfo renderInfo);

вызывается один раз или чаще для построения фактического пути , PathConstructionRenderInfo, содержащего фактический тип инструкции в его свойстве Operation (сравните с PathConstructionRenderInfo постоянными членами MOVETO, LINETO и т. д. для определения типа операции) и требуемых координат / размеров в свойстве SegmentData. Свойство Ctm дополнительно возвращает аффинное преобразование, которое в настоящее время установлено для применения ко всем операциям рисования.

Тогда

/**
 * Called when the current path should be set as a new clipping path.
 *
 * @param rule Either {@link PathPaintingRenderInfo#EVEN_ODD_RULE} or {@link PathPaintingRenderInfo#NONZERO_WINDING_RULE}
 */
void ClipPath(int rule); 

вызывается, если текущий путь клипа должен пересекаться с созданным путем.

Наконец

/**
 * Called when the current path should be rendered.
 *
 * @param renderInfo Contains information about the current path which should be rendered.
 * @return The path which can be used as a new clipping path.
 */
Path RenderPath(PathPaintingRenderInfo renderInfo); 
Вызывается

, PathPaintingRenderInfo содержащий операцию рисования в свойстве Operation (любая комбинация PathPaintingRenderInfo констант STROKE и FILL), правило для определения, что означает "внутри пути" в его Rule свойство (NONZERO_WINDING_RULE или EVEN_ODD_RULE) и некоторые другие детали чертежа в свойствах Ctm, LineWidth, LineCapStyle, LineJoinStyle, MiterLimit и LineDashPattern.

0 голосов
/ 02 января 2019

попробуйте реализовать IRenderListener

  internal class ImageExtractor : IRenderListener
{
    private int _currentPage = 1;
    private int _imageCount = 0;
    private readonly string _outputFilePrefix;
    private readonly string _outputFolder;
    private readonly bool _overwriteExistingFiles;

    private ImageExtractor(string outputFilePrefix, string outputFolder, bool overwriteExistingFiles)
    {
        _outputFilePrefix = outputFilePrefix;
        _outputFolder = outputFolder;
        _overwriteExistingFiles = overwriteExistingFiles;
    }

    /// <summary>
    /// Extract all images from a PDF file
    /// </summary>
    /// <param name="pdfPath">Full path and file name of PDF file</param>
    /// <param name="outputFilePrefix">Basic name of exported files. If null then uses same name as PDF file.</param>
    /// <param name="outputFolder">Where to save images. If null or empty then uses same folder as PDF file.</param>
    /// <param name="overwriteExistingFiles">True to overwrite existing image files, false to skip past them</param>
    /// <returns>Count of number of images extracted.</returns>
    public static int ExtractImagesFromFile(string pdfPath, string outputFilePrefix, string outputFolder, bool overwriteExistingFiles)
    {
        // Handle setting of any default values
        outputFilePrefix = outputFilePrefix ?? System.IO.Path.GetFileNameWithoutExtension(pdfPath);
        outputFolder = String.IsNullOrEmpty(outputFolder) ? System.IO.Path.GetDirectoryName(pdfPath) : outputFolder;

        var instance = new ImageExtractor(outputFilePrefix, outputFolder, overwriteExistingFiles);

        using (var pdfReader = new PdfReader(pdfPath))
        {
            if (pdfReader.IsEncrypted())
                throw new ApplicationException(pdfPath + " is encrypted.");

            var pdfParser = new PdfReaderContentParser(pdfReader);

            while (instance._currentPage <= pdfReader.NumberOfPages)
            {
                pdfParser.ProcessContent(instance._currentPage, instance);

                instance._currentPage++;
            }
        }

        return instance._imageCount;
    }

    #region Implementation of IRenderListener

    public void BeginTextBlock() { }
    public void EndTextBlock() { }
    public void RenderText(TextRenderInfo renderInfo) { }

    public void RenderImage(ImageRenderInfo renderInfo)
    {
        if (_imageCount == 0)
        {
            var imageObject = renderInfo.GetImage();

            var imageFileName = _outputFilePrefix + _imageCount; //to get multiple file (you should add .jpg or .png ...)
            var imagePath = System.IO.Path.Combine(_outputFolder, imageFileName);



            if (_overwriteExistingFiles || !File.Exists(imagePath))
            {
                var imageRawBytes = imageObject.GetImageAsBytes();
                //create a new file ()
                File.WriteAllBytes(imagePath, imageRawBytes);

            }
        }
        _imageCount++;
    }

    #endregion // Implementation of IRenderListener

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