Christian Regli
Christian Regli

Reputation: 2246

Android PdfDocument too big (page dimensions)

I generate a simple PDF with an image (banner) and a title in code as follows:

    public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Bitmap headerBmp = BitmapFactory.decodeResource(getResources(), R.drawable.headerimage);
        PdfDocument pdfDocument = new PdfDocument();
        PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(2480, 3508, 1).create();
        PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);
        Canvas canvas = myPage.getCanvas();
        canvas.setDensity(300);

        canvas.drawBitmap(headerBmp, 50, 50, new Paint());
        Paint titlePaint = new Paint();

        titlePaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
        titlePaint.setTextSize(75);
        canvas.drawText("Title", 50, 250, titlePaint);
        pdfDocument.finishPage(myPage);
        File pdfPath = new File(getFilesDir(), "pdf");
        if (!pdfPath.exists()) {
            pdfPath.mkdir();
        }
        File pdfFile = new File(pdfPath, "document.pdf");

        try {

            pdfDocument.writeTo(new FileOutputStream(pdfFile, false));

        } catch (IOException e) {
            // below line is used
            // to handle error
            e.printStackTrace();
        } finally {


            // after storing our pdf to that
            // location we are closing our PDF file.
            pdfDocument.close();

        }
    }
}

The resulting Pdf document is too big (page size). It should fit A4 page size. The document size seems correct when I change this line

PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(2480, 3508, 1).create();

to this:

PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();

But now the image (about 1200 x 300) does not fit the page. If resized to 595 px width the image looks very bad.

2480 x 3508 is the correct size for A4 with 300 dpi 595 x 842 is the correct size for A4 with 72 dpi

But images normally have 300dpi.

How do I make the page fit without losing image quality?

Upvotes: 0

Views: 1920

Answers (2)

Umair Qayyum
Umair Qayyum

Reputation: 54

Option 1. Scaledown your bitmap to specific width this will scale it width according to your page width if width is greater than paper width, this will not reduce its quality.

 public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Bitmap headerBmp = BitmapFactory.decodeResource(getResources(), 
    R.drawable.headerimage);

    //scale downBitmap
    headerBmp = scaleDown(headerBmp,2048,true);
      
    PdfDocument pdfDocument = new PdfDocument();
    PdfDocument.PageInfo mypageInfo = new 
    PdfDocument.PageInfo.Builder(2480, 3508, 1).create();
    PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);
    Canvas canvas = myPage.getCanvas();
    canvas.setDensity(300);

    canvas.drawBitmap(headerBmp, 50, 50, new Paint());
    Paint titlePaint = new Paint();

    titlePaint.setTypeface(Typeface.create(Typeface.DEFAULT, 
    Typeface.BOLD));
    titlePaint.setTextSize(75);
    canvas.drawText("Title", 50, 250, titlePaint);
    pdfDocument.finishPage(myPage);
    File pdfPath = new File(getFilesDir(), "pdf");
    if (!pdfPath.exists()) {
        pdfPath.mkdir();
    }
    //generate random number and add it to file name otherwise same file 
    //will be displayed everytime.
    int random = getRandomInt();
    File pdfFile = new File(pdfPath, "document"+random+".pdf");

    try {

        pdfDocument.writeTo(new FileOutputStream(pdfFile, false));

    } catch (IOException e) {
        // below line is used
        // to handle error
        e.printStackTrace();
    } finally {


        // after storing our pdf to that
        // location we are closing our PDF file.
        pdfDocument.close();

    }
}

}

ScaleDown Function: public Bitmap scaleDown(Bitmap realImage, float maxImageSize, boolean filter) { float ratio = Math.min( maxImageSize / realImage.getWidth(), maxImageSize / realImage.getHeight());

    if (ratio >= 1.0) {
        return realImage;
    }

    int height = Math.round(ratio * realImage.getHeight());

    return Bitmap.createScaledBitmap(realImage, 3800, height, filter);
}

In random function:

public int generate_random() {
return new Random().nextInt((1000-10) + 1) + min;
}

Option 2: Use HTML Webview for designing frontend of pdf. You can style it according to your need by using CSS set width of image to 100%.

Upvotes: 0

Olivier
Olivier

Reputation: 18067

A PDF internally uses points. A point is defined as 1/72th of an inch. An inch is 25.4 mm.

A4 size is 210 x 297 mm, which gives in points:

210 / 25.4 * 72 = 595.3 pt
297 / 25.4 * 72 = 841.9 pt

The PdfDocument.PageInfo.Builder constructor takes integer values for the dimensions, which means you must pass 595 and 842 to get (almost) A4.

Now for the image. There is an overload of drawBitmap() that takes a RectF for the destination. That means that you can specify what area on the page the image will occupy.

Let's say you want your banner to be displayed at position (50 pt, 50 pt) and occupy an area of size (500 pt, 125 pt). Here is how you would do it:

Bitmap headerBmp = BitmapFactory.decodeResource(getResources(), R.drawable.headerimage);

PdfDocument pdfDocument = new PdfDocument();
PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();
PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);
Canvas canvas = myPage.getCanvas();
RectF dst = new RectF(50, 50, 50 + 500, 50 + 125);
canvas.drawBitmap(headerBmp, null, dst, null);
pdfDocument.finishPage(myPage);

Upvotes: 3

Related Questions