Android PdfDocument file size

后端 未结 5 1549
予麋鹿
予麋鹿 2021-01-05 02:03

I want to generate a PDF File from a View using the PdfDocument android class introduced in KitKat. I managed to do it, and the file is so far generated ok, end

相关标签:
5条回答
  • 2021-01-05 02:24

    To decrease PDF file size while using PdfDocument create your bitmap with Bitmap.Config.RGB_565 using Bitmap.Config.ARGB_8888 or Bitmap.Config.ARGB_4444 will increase the file size

    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    
    0 讨论(0)
  • 2021-01-05 02:33

    Using PDFDocument, be sure to downscale your images prior to drawing them in the canvas.

    When drawing to 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 downscale the bitmap, it will just squeeze it into a smaller zone. 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();
    

    This is embedded in Android so it is much easier than using a third-party library. (The above was tested on a Marshmallow platform)

    0 讨论(0)
  • 2021-01-05 02:34

    There are a few main things that increases 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. Following links give a basice 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

    https://stackoverflow.com/a/21025162/3110609

    0 讨论(0)
  • 2021-01-05 02:39

    This seems to just be a bug in PdfDocument. The PDF file I created with PdfDocument was 5.6 megabytes. The same document generated through the iOS equivalent was 500K. If I take the Android PDF and run it through Adobe Acrobat's pdf optimization, without compressing any images, the 5.6MB file becomes 350K. They look identical, and I applied no compression in Adobe Acrobat.

    In the actual PDF code, the Android image object dictionary is this

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

    The PDF from iOS 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 the FlateDecode filter in the Android version. When I run it through the Adobe Acrobat PDF optimizer, it gets the FlateDecode filter.

    0 讨论(0)
  • 2021-01-05 02:43

    In case anyone is still looking for a solution... I was working on a project to generate PDF from images and not satisfied with the file size generated by both Android's PdfDocument and 3rd party AndroidPdfWriter APW.

    After some trials I ended up using Apache's PdfBox, which gave me a PDF file (A4 size with a single 1960x1080 image) for around 80K, while it's 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();
    

    =====

    btw. I guess the reason why they generate a huge file size is because they don't compress the image data while writing to PDF file. If you take a look into AndroidPdfWriter's XObjectImage.deflateImageData() method you will see it's using java.util.zip.Deflater.NO_COMPRESSION option to write the image data which is kind of horrible if you've got a picture with size 1960x1080. If you change the options to e.g. Deflater.BEST_COMPRESSION you get much smaller file size however it takes up to 3-4 seconds for me to handle one single page which is not acceptable.

    0 讨论(0)
提交回复
热议问题