Android PdfDocument.Page - Problems with image siz

2019-06-16 09:09发布

问题:

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.

回答1:

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.



回答2:

[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 to DENSITY_XHIGH.)



回答3:

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, ....);