PdfDocument file size for Android

I want to create a PDF file from a view using the PdfDocument android class provided in KitKat. I managed to do this, and the file is still generated fine, the result is the correct PDF file. The only problem is that the file is huge, 12 MB for one page. Is there a way to reduce the file size?

The code I use to create the PDF file is:

 public static File generateDocument(Activity activity, String fileName, ViewGroup container) throws IOException{ File f = new File(activity.getExternalFilesDir(null), fileName); PdfDocument document = new PdfDocument(); try{ for(int i=0;i<container.getChildCount();i++){ View v = container.getChildAt(i); PdfDocument.PageInfo.Builder pageBuilder = new PdfDocument.PageInfo.Builder(v.getWidth(), v.getHeight(), i); Page page = document.startPage(pageBuilder.create()); v.draw(page.getCanvas()); document.finishPage(page); } document.writeTo(new FileOutputStream(f)); } finally{ if(document!=null){ document.close(); } } return f; } 
+4
source share
4 answers

There are a few basic things that increase the size of a PDF file:

 hi-resolution pictures (where lo-res would suffice) embedded fonts (where content would still be readable "good enough" without them) PDF content not required any more for the current version/view (older version of certain objects) embedded ICC profiles embedded third-party files (using the PDF as a container) embedded job tickets (for printing) embedded Javascript and a few more 

Try using iText. The following links give a basic idea for iText in android.

http://technotransit.wordpress.com/2011/06/17/using-itext-in-android/

http://www.mysamplecode.com/2013/05/android-itext-pdf-bluetooth-printer.html

fooobar.com/questions/935204 / ...

+4
source

This seems to be just a bug in the PdfDocument. The PDF file I created with PdfDocument was 5.6 megabytes. The same document created using the iOS equivalent was 500K. If I take Android PDF and run it using Adobe Acrobat pdf, without compressing any images, the 5.6MB file will become 350K. They look the same, and I did not use compression in Adobe Acrobat.

In real PDF, the Android object image dictionary is

 <</Type /XObject /Subtype /Image /Width 1224 /Height 1584 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Length 5816448 >> 

IOS PDF has this dict

 << /Length 8 0 R /Type /XObject /Subtype /Image /Width 1224 /Height 1584 /ColorSpace /DeviceRGB /SMask 9 0 R /BitsPerComponent 8 /Filter /FlateDecode >> 

I think the problem is the lack of a FlateDecode filter in the Android version. When I run it through the Adobe Acrobat PDF optimizer, it gets the FlateDecode filter.

+2
source

If someone is still looking for a solution ... I was working on a project to create a PDF file from images and am not satisfied with the file size created by both Android PdfDocument and third-party > AndroidPdfWriter APW .

After some testing, I ended up using Apache PdfBox , which gave me a PDF file (A4 size with a single 1960x1080 image) about 80K, while usually 2 ~ 3M with PdfDocument or AndroidPdfWriter .

 PDDocument document = new PDDocument(); PDPage page = new PDPage(PDRectangle.A4); document.addPage(page); // Define a content stream for adding to the PDF contentStream = new PDPageContentStream(document, page); Bitmap bimap = _get_your_bitmap_(); // Here you have great control of the compression rate and DPI on your image. // Update 2017/11/22: The DPI param actually is useless as of current version v1.8.9.1 if you take a look into the source code. Compression rate is enough to achieve a much smaller file size. PDImageXObject ximage = JPEGFactory.createFromImage(document, bitmap, 0.75, 72); // You may want to call PDPage.getCropBox() in order to place your image // somewhere inside this page rect with (x, y) and (width, height). contentStream.drawImage(ximage, 0, 0); // Make sure that the content stream is closed: contentStream.close(); document.save(_your_file_path_); document.close(); 

=====

by the way. I think the reason they generate a huge file size is because they do not compress image data while writing to a PDF file. If you look at the AndroidPdfWriter XObjectImage.deflateImageData () method, you will see it using the java.util.zip.Deflater.NO_COMPRESSION option to write image data that looks awful if you have an image of 1960x1080 size. If you change the settings, for example. Deflater.BEST_COMPRESSION you get a much smaller file size, but it takes me 3-4 seconds to process a single page, which is unacceptable.

+1
source

Using PDFDocument, be sure to reduce your images to drawing them on canvas.

When drawing on the screen, this is enough to scale the bitmap:

 canvas.drawBitmap(bmp, src, dst, paint); 

However, when using the canvas from PdfDocument.Page.getCanvas this canvas will not reduce the bitmap, it simply compresses it into a smaller area. Instead, you should do something like this:

 // Scale bitmap : filter = false since we are always downSampling Bitmap scaledBitmap = Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, false); // filter=false if downscaling, true if upscaling canvas.drawBitmap(scaledBitmap, null, dst, paint); scaledBitmap.recycle(); 

It is built into Android, so it is much simpler than using a third-party library. (Above was tested on the Marshmallow platform)

+1
source

Source: https://habr.com/ru/post/1237860/


All Articles