Android PdfDocument文件大小

问题描述 投票:5回答:4

我想使用KitKat中引入的PdfDocument android类从View生成PDF文件。我设法做到了,文件到目前为止生成正常,最终得到了正确的PDF。唯一的问题是文件很大,只有一页12Mb。有没有办法减少文件大小?

我用来生成PDF的代码是:

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;
}
android pdf-generation filesize
4个回答
4
投票

有一些主要因素会增加PDF文件的大小:

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

尝试使用iText。以下链接为Android中的iText提供了一个基本的想法。

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


3
投票

如果有人还在寻找解决方案......我正在开发一个项目来从图像生成PDF,而不满足于Android的PdfDocument和第三方AndroidPdfWriter APW生成的文件大小。

经过一些试验后,我最终使用了Apache的PdfBox,它给了我一个PDF文件(A4大小,单个1960x1080图像)大约80K,而通常是2~3M的PdfDocument或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();

=====

顺便说一句。我猜他们生成巨大文件大小的原因是因为他们在写入PDF文件时不压缩图像数据。如果你看看AndroidPdfWriter的XObjectImage.deflateImageData()方法,你会看到它正在使用java.util.zip.Deflater.NO_COMPRESSION选项来编写图像数据,如果你有一张尺寸为1960x1080的照片,那就太可怕了。如果您将选项更改为例如Deflater.BEST_COMPRESSION你的文件大小要小得多,但是我需要3-4秒来处理一页不可接受的页面。


2
投票

这似乎只是PdfDocument中的一个错误。我用PdfDocument创建的PDF文件是5.6兆字节。通过iOS等效生成的同一文档是500K。如果我使用Android PDF并通过Adobe Acrobat的pdf优化运行它,而不压缩任何图像,5.6MB文件将变为350K。它们看起来完全相同,我在Adobe Acrobat中没有应用压缩。

在实际的PDF代码中,Android图像对象字典就是这样

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

来自iOS的PDF有这个词

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

我认为问题是Android版本中缺少FlateDecode过滤器。当我通过Adobe Acrobat PDF优化器运行它时,它获取FlateDecode过滤器。


1
投票

使用PDFDocument时,请确保在将图像绘制到画布之前缩小图像。

绘制到屏幕时,这足以缩放位图:

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

但是,当使用来自PdfDocument.Page.getCanvas的画布时,此画布不会缩小位图,只会将其挤压到较小的区域。相反,你应该做这样的事情:

// 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();

这是嵌入在Android中,因此它比使用第三方库容易得多。 (以上是在Marshmallow平台上测试的)

© www.soinside.com 2019 - 2024. All rights reserved.