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.
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, ....);
As requested, the solution I found was to set the density to a value higher than what it should be. Setting the bitmap density to DENSITY_XHIGH instead of DENSITY_HIGH improved the rendered bitmap considerably for me. The bitmap is closer to the size I would expect when the pdf is generated.
[I copied your solution to an answer. If you have found a solution please create an answer and accept it yourself]
I have tried setting the bitmap density to a value higher than what I think it should be:
logo.setDensity(DisplayMetrics.DENSITY_XHIGH);
And this did the trick. (I originally set it to DENSITY_HIGH, but it was still scaling the image up slightly, so changed it toDENSITY_XHIGH
.)