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, ending up having a correct PDF. The only problem is the file is huge, 12Mb for just one page. Is there a way to reduce the File size?
The code I am using to generate the PDF 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;
}
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.