Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android PdfDocument.Page - Problems with image size

I am experiencing problems with images being larger when drawing onto a PdfDocument.Page. The app is targeted for a device running Android 4.4.4 (API level 19).

I am generating a pdf document and adding an image as follows:

PdfDocument document = new PdfDocument();

//Create an A4 sized page 595 x 842 in Postscript points.
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();

PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();

Bitmap logo = BitmapFactory.decodeResource(context.getResources(), R.drawable.pdf_logo);

Log.i(Consts.LOG_TAG, "pdf canvas density = " + canvas.getDensity());
Log.i(Consts.LOG_TAG, "pdf UOD logo density = " + logo.getDensity());

canvas.drawBitmap(logo, 50, 50, null);

document.finishPage(page);

/*
document is written out to a FileOuputStream().
Details omitted.
*/

The document is written out correctly, and other text I have rendered using Canvas.drawText() method looks fine.
However, the image drawn is always too big in the pdf document.

I have checked the density of both the image and canvas are the same. The image (pdf_logo.jpg) is:
- 160 dpi
- 160 x 160 physical pixels in resolution.
- So is 1 inch x 1 inch in size.

The logs in the above code also returned the following:

04-22 11:55:50.607: I/App(7856): pdf canvas density = 160
04-22 11:55:50.607: I/App(7856): pdf UOD logo density = 160

This shows that the image dpi matches the Canvas density as well. However, when the image is drawn onto the pdf document, the image is much larger than 1 inch x 1 inch. It is about double the size , just over 2 inch x 2 inch.

My suspicion is that Android has used the physical resolution of the image (160 x 160) and converted it into the PdfDocument.Page size units, Postscript points which are 1/72 inch. So 160 Postscript points equates to 2.2 inches ~ double the size of the original image (1 x 1 inch).

If I halve the size of the image then I get pixelation, as it will effectively be drawing an 0.5 x 0.5 inch image into a 1 x 1 inch space.

I would like to know how I can draw an image as actual size on a PdfDocument.Page, without having these scaling/size issues.

like image 425
Glen Au-Yeung Avatar asked Apr 22 '15 11:04

Glen Au-Yeung


2 Answers

This is a late answer, but a have been dealing with the same problem, and found the solution, with an explanation.

The explanation:

PdfDocument.Page size units, Postscript points which are 1/72 inch.

This means, that the PdfDocument uses points that measure 1/72th of an inch when physically printed, which is equal to say that in the printed document, there will be 72 points in 1 inch. This is also known as 72 DPI (Dots Per Inch).

So, with 72 DPI, if you wanted to see the document in your screen at the same exact size of the document printed (with no zoom ofc), you would need 72 pixels per inch (PPI)

Unlike pictures, PDF files have physical size, so the Canvas of the PdfDocument.Page can be understood as the "screen" where you are printing your document. This "screen" MUST have a density of 72 PPI for the content to be represented as the original.

The solution:

There is no need for logo.setDensity(DisplayMetrics.DENSITY_XHIGH); because you dont want to change the scale of the image, you need to specify the density of the canvas.

Solution is canvas.setDensity(72);

like image 58
Pablo Rodriguez Avatar answered Oct 18 '22 06:10

Pablo Rodriguez


The exact solution is to set the Canvas' density to 72 (But why?)

  • logo.setDensity(dpi); (calc dpi from desired image dimensions in pt and bitmap size)
  • canvas.setDensity(72);
  • canvas.drawBitmap(logo, ....);
like image 2
user1712200 Avatar answered Oct 18 '22 07:10

user1712200