Adding Text/Annotations into existing PDF file and View/Rendering the output in android
Asked Answered
S

1

9

I am working on a pdf editor.

I have made my changes on pdf files with OpenPDF core that is based on iText

And I am viewing the Pdf file with AndroidPdfViewer

My problems are:

  1. Adding new annotations like text or tags or icons into an existing pdf file. ( SOLVED )

  2. Show new changes right after annotations added into pdf file.( SOLVED )

  3. Convert user click into Pdf file coordinates to add new annotation based on user clicked location.

  4. Get click event on added annotations and read meta data that added into that annotation , for ex: read tag hash id that sets on icon annotation. ( SOLVED )

  5. Remove added annotation from PDF File.

Any help appreciated

UPDATE

========================================================================

Solution 1: Adding annotations

  • Here is my code snippet for adding icon annotation into existing pdf file.

public static void addWatermark(Context context, String filePath) throws FileNotFoundException, IOException {

        // get file and FileOutputStream
        if (filePath == null || filePath.isEmpty())
            throw new FileNotFoundException();

        File file = new File(filePath);

        if (!file.exists())
            throw new FileNotFoundException();

        try {

            // inout stream from file
            InputStream inputStream = new FileInputStream(file);

            // we create a reader for a certain document
            PdfReader reader = new PdfReader(inputStream);

            // get page file number count
            int pageNumbers = reader.getNumberOfPages();

            // we create a stamper that will copy the document to a new file
            PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(file));

            // adding content to each page
            int i = 0;
            PdfContentByte under;

            // get watermark icon
            Image img = Image.getInstance(PublicFunction.getByteFromDrawable(context, R.drawable.ic_chat));
            img.setAnnotation(new Annotation("tag", "gd871394bh2c3r", 0, 0, 0, 0));
            img.setAbsolutePosition(230, 190);
            img.scaleAbsolute(50, 50);

            while (i < pageNumbers) {
                i++;
                // watermark under the existing page
                under = stamp.getUnderContent(i);
                under.addImage(img);
            }

            // closing PdfStamper will generate the new PDF file
            stamp.close();

        } catch (Exception de) {
            de.printStackTrace();
        }

    }
}

Solution 2: Show new changes

  • Here is my code snippet for refreshing the view after adding annotation, I have added this into AndroidPdfViewer core classes.
public void refresh(int currPage) {

            currentPage = currPage;

            if (!hasSize) {
                waitingDocumentConfigurator = this;
                return;
            }
            PDFView.this.recycle();
            PDFView.this.callbacks.setOnLoadComplete(onLoadCompleteListener);
            PDFView.this.callbacks.setOnError(onErrorListener);
            PDFView.this.callbacks.setOnDraw(onDrawListener);
            PDFView.this.callbacks.setOnDrawAll(onDrawAllListener);
            PDFView.this.callbacks.setOnPageChange(onPageChangeListener);
            PDFView.this.callbacks.setOnPageScroll(onPageScrollListener);
            PDFView.this.callbacks.setOnRender(onRenderListener);
            PDFView.this.callbacks.setOnTap(onTapListener);
            PDFView.this.callbacks.setOnLongPress(onLongPressListener);
            PDFView.this.callbacks.setOnPageError(onPageErrorListener);
            PDFView.this.callbacks.setLinkHandler(linkHandler);

            if (pageNumbers != null) {
                PDFView.this.load(documentSource, password, pageNumbers);
            } else {
                PDFView.this.load(documentSource, password);
            }
        }

Solution 4: Click on object in pdf

I have create annotations and set it to added image object, AndroidPdfViewer has an event handler, here is the example

@Override
public void handleLinkEvent(LinkTapEvent event) {
        // do your stuff here
}

I will add other new solutions into my question, as update parts.

Scintillant answered 8/12, 2020 at 12:28 Comment(4)
"Here is my code snippet for adding text into pdf file, but this will replace with all of the Pdf file, not just inserting into it." - Look for examples using a PdfReader / PdfStamper pair to change an existing PDF.Esmerolda
@Esmerolda thanks for your response, can you provide more details or references about this issue? I have used PdfReader for reading pdf content, and PdfStamper for reading Pdf file meta data.Scintillant
"can you provide more details or references about this issue?" - I just wrote an answer providing some details on this part. I don't know about Android PDF viewers, so I cannot respond to that part of your question.Esmerolda
Yes I have achieved to append my changes into the base the PDF file with PDFStamper, now I'm struggling and testing all PdfViewers to get user integrations such as text selection or click events on added annotations. I will add my code as an update part in my question.Scintillant
E
2

Here is my code snippet for adding text into pdf file,

Your code does not add text into an existing pdf file. It creates a new PDF, adds text to it, and appends this new PDF to the existing file presumably already containing a PDF. The result is one file containing two PDFs.

Concatenating two files of the same type only seldom results in a valid file of that type. This does works for some textual formats (plain text, csv, ...) but hardly ever for binary formats, in particular not for PDFs.

Thus, your viewer gets to show a file which is invalid as a PDF, so your viewer could simply have displayed an error and quit. But PDF viewers are notorious for trying to repair the files they are given, each viewer in its own way. Thus, depending on the viewer you could also see either only the original file, only the new file, a combination of both, an empty file, or some other repair result.

So your observation,

but this will replace with all of the Pdf file, not just inserting into it

is not surprising but may well differ from viewer to viewer.


To actually change an existing file with OpenPDF (or any iText version before 6 or other library forked from such a version) you should read the existing PDF using a PdfReader, manipulate that reader in a PdfStamper, and close that stamper.

For example:

PdfReader reader = new PdfReader("original.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("original-stamped.pdf"));

PdfContentByte cb = stamper.getOverContent(1);
cb.beginText();
cb.setTextMatrix(100, 400);
cb.showText("Text at position 100,400.");
cb.endText();

stamper.close();
reader.close();

In particular take care to use different file names here. After closing the stamper and the reader you can delete the original PDF and replace it with the stamped version.

If it is not desired to have a second file, you can alternatively initialize the PdfStamper with a ByteArrayOutputStream and after closing the stamper and the reader replace the contents of the original file with those of the ByteArrayOutputStream.

Esmerolda answered 10/12, 2020 at 9:56 Comment(3)
Thanks for your help @Esmerolda I have actually resolved all my issues except last one, I'm locking for the best way to remove these items from pdf. I have although raised an issue in github here for you. do you have any idea?tnQScintillant
For the next two weeks I'll most likely be on stack overflow on smart phone only which makes proper answers difficult. If you're still interested thereafter, I'll try and write something up.Esmerolda
Yes @Esmerolda I'm really really interested in this issue :) thanks for your help, If you give me some sort of keywords or any links It is just fine, I will search and review them by myself.Scintillant

© 2022 - 2024 — McMap. All rights reserved.