I am developing an android application which should help users to annotate the PDF file. I am using MuPDF to parse the PDF on android device. I am able to read the PDF but unable to figure out a way which will help me implement annotations features for the PDF. I couldn't find any sample core nor could I find any manuals that explains what I am looking for. Anyone have any sample code, any other material or any links which will give me an idea on how can I support simple annotations (say draw a rectangle or write freely) on PDF files.
Any kind of help in this regard is much appreciated.
Thanks in advance.
You CAN draw annotations by completely delegating into the MuPDF library.
The sample app provided my them includes code for this.
The method in the native layer of MuPDF supporting this is addMarkupAnnotationInternal(int page, PointF[] quadPoints, int type)
The passed PointF[] defines the rectangle that you want to annotate. This is likely to come from a the text the user has selected.
If you are using the java wrapper that they provide, com.artifex.mupdfdemo.MuPDFCore.java, they provide the method called:
MuPDFCore#addMarkupAnnotation(int page, PointF[] quadPoints, Annotation.Type type)
To see how it is actually done and how the MuPDFCore#addMarkupAnnotation receives the quadpoints from the selection of the user, try the sample app while reading the code.
Basically, for adding an annotation you need to:
1- provide a list of points (quads) defining the box and the page of the highlighted area.
2- delegate into the MuPDF library by using the aforementioned method to add the annotation to the document and to render it.
For the first step, you will likely want to let the user select the area of the document to highlight. If so, you can let the user select by starting selection mode with:
MuPDFReaderView#setMode(MuPDFReaderView.Mode.Selecting);
and when the user finishes, get the selection with:
MuPDFView#selectText();
Doing all of this is not straightforward and you need to understand the API, so, I really recommend you to read the sample code.
In regards as where do you save the annotations, that is another story. You can save them in the PDF file (MuPDF lets you doing this) or you can store them anywhere else, which will require more code and will dissociate the annotations from the PDF file.
So, you can do it entirely with MuPDF, there is no need to draw the annotations as another layer to the Canvas/View using the Android API.
Do you want to store the annotations in the PDF file or separately?
The former is not possible with muPDF.
However, if you intend to store the annotations separately, then you could conceivably render the PDF to a canvas as background and then draw over it. You'll still have to write the equivalent of a drawing app. There's "FingerPaint" in the Android samples, and also Android Paint in open source.
If you want to highlight specific text in the PDF, things will get quite complex. You'd have to extract the character dimensions from fitz and manage a cursor of sorts in your touch handlers. This isn't impossible, but far from trivial.
Related
I am currently using Xfinium PDF to generate pdf into images and do some drawing on to the pdf using their Graphics api e.g. drawing cubic paths.
There is a constructor PdfFixedDocument which I used it to load the document. The problem is when I tried to load a 30mbyte document to get the page information it would take 10+second to call the PdfFixedDocument constructor which is quite inefficient if I just want to fetch the page information or just loading a single page.
Does anyone have any better idea? I can't use PDFRender on android because I am running kitkat. Will there be a better api which can give me a better efficiency.
For extracting a single page you can open the file using the PdfFile class and then extract the page using the PdfFile.ExtractPage method.
You can also extract the basic page information (width, height, rotation) using the PdfFile.ExtractPageInfo method.
The PdfFixedDocument constructor loads the entire file into memory and maps it to XFINIUM.PDF object model so that any object can be easily updated and depending on the objects in the PDF file this can take some time.
Disclaimer: I work for the company that develops XFINIUM.PDF library.
I plan to use the built-in android pdf library. In my app I need to display a pdf report that may consist of several pages. Users should be able to print those pages. Printing with the PrintDocumentAdapter seems pretty straight forward, but what's unclear to me is what is the best way to create the pdf. I know that you can generate a PdfDocument with simply a View/canvas and or take more "low-level" approach where you draw lines,text, paint, etc.
I see three possibilities:
Create a view for each page. The user can navigate between the views as needed and print. However it's unclear to me how to generate a pdf for each page/view. What I mean by this is if I'm viewing page/view 1, yes I can easily create a pdf from this, but what about the other pages? Yes I can have this in memory, but what I've found is if they aren't actively being displayed on screen, they create empty pdfs. I don't want to have the user print each page individually.
Create the pdf documents (low-level approach), integrate a pdf reader and just display/print the pdf from there.
Create a view for each page that the user can navigate through. When the print option is invoked, generate the pdf documents again (low-level approach)
Obviously option 1 is the preferred approach, but I'm not clear on how I can do that. Of course, I could be missing something here so any help would be appreciated!
Android didn't have built in pdf genaration library, but in API19 android provided an api https://developer.android.com/reference/android/graphics/pdf/PdfDocument.html
But as #Ivan Wooll said itext is a nice pdf generation library if you want to use.
...but what's unclear to me is what is the best way to create the pdf...
Yet, it is relative. It really is a matter of what library/framework you find more convenient to work with, because each of them offers quit the same functionality with its own disadvantages. For instance, those I worked with, have the following ones:
iText - you must buy a licenece for comircial use (see What is latest version of itext that is not AGPL?);
Android Print Framework - no built-in pdf preview before printing as you mentioned in the 2nd item (you can use built-in PdfRenderer though for API 21+; also see Display PDF within app on Android?). Another disadvantage is the disturbing system dialogs when you'd like to save/print "silently" :)
Even the official documentation states that "You can use any PDF generation library to generate a PDF document and pass it to the Android print framework for printing."
...Yes I can have this in memory, but what I've found is if they aren't actively being displayed on screen, they create empty pdfs...
The reason for empty pdfs when you keep the views that have been left by a user in memory is their 0-dimension because of not being laied out (see Android: PdfDocument generates empty pdf). The same will happen if you try to inflate the views that haven't been reached by a user yet... In fact, there is nothing you can do about it, this is how Android works.
I don't want to have the user print each page individually.
In this case I suggest you to create pdf pages in advance for each content view a user is currently interacting with, just make sure that the view is still laied out when drawing it on canvas. For the views that aren't currently laied out use the "low-level approach". And once printing requested pass the output pdf to Android Print Framework.
There are a few pdf generation libraries out there. Itext being the simplest to use but it's ludicrously expensive. Pdfjet is another one which is reasonably priced. A quick google will provide you with more i'm sure.
I want to add a vector that's a map. I want to show this to the user, but I'm unsure of the best way to do this.
The only requirements I have are:
Show a vector
Start "zoomed" in (start at a specific point of the the map)
Work on 4.0 and up
I'm up for suggestion on which file type to use
Ah, that is definitely not how I interpreted "I don't want to specify one".
SVG is probably the lightest-weight solution. There are libraries that can display SVG in an ImageView as a Drawable, though these will only handle a subset of SVG. WebView on Android 3.0+ is supposed to be able to handle SVG files, though I haven't tried it.
Many, perhaps most, Android users have a PDF viewer, so if you're willing to open up a third-party app, you can do that easily enough. There are PDF libraries as well, though PDF is a more complex file format than is SVG, and therefore the libraries suffer.
I am not aware of any easy way to show an AI file directly, and those are the primary 2D vector formats in use today.
I would like to display rich maps contained in Autocad .dwg files in my Android app. I'd like to know if there is an existing java library to do so?
If not, is it doable to translate a dwg file to a model and draw that model shape by shape on the screen?
I can't use Google maps instead of these files. The whole point of the app is to display a map with a lot of data and all that data is contained in my autocad files library.
Besides, is there an alternative format to DWG that I could use to do exactly this? (UPDATE: would SVG do the trick?)
What I ended up doing is to convert all my files in KML. I've selected this format because it might be the most used format on Android to do GIS.
To make a custom map, I'm drawing overlays on a mapview using these hints. It's basically the most interesting solution. I don't need to pay attention to geolocation stuff, the cursor and the scale are manage by Google API itself.
If you're going to convert I'd probably suggest DXF. I haven't used it, but YCad is a java DXF library. There are also a number of DXF to SVG converters available but it's probably best to avoid two conversions.
I have to make an application that should capable of reading PDF documents on Android device. Actually I do not want my app to be dependent on other apps to read the PDF file.
I had gone through the questions that are asked here and at some other places also. They all directly or indirectly using third party app.
Is there any API or something similar is available through which I can implement reading of PDF files directly in my app? How about converting the PDF document to PNG image? But the PDF-PNG method wont let users select the texts.
Any suggestions?
Thanks
There exists an library from Adobe that you can use. Its based on the NDK and you need to do the wrapping all by yourself. Its also extremely expensive, basically nothing for a small firm/single developer but for bigger companies. Afaik the license is not only expensive but also annual based, so you need to pay for it in every year...
There are other libraries, basically open source. Some of them have good performance but a lack of functionality (most of them based on NDK, too). I found only one pure "java" library but the performance was more than worse (loading time 10sec for a page and more).
There are three possibilities you should consider:
Using an external application, so you just need to implement the library of your PDF documents
You write everything by yourself including a pdf reader part
You create a middle "tier" where you convert your PDF into PNGs or JPG (I prefer PNG for better quality). The much better performance comes with a lack of features.
I'm currently developing a complex application like mentioned in 3. but I can't go into details, sorry.
I would definitely recommend the Qoppa stuff on Android.