4

I need to create a bitmap in android and draw some stuff on it using a canvas which will eventually be printed using a photo printer. Basically I'm trying to create a jpg of actual 5x7 size (5 inches X 7 inches). So if the bitmap is emailed or copied to a computer, it correctly fit into a 5X7 photo printing paper.

When specifying the height and width in the createbitmap method, what values do I need to specify to make the actual size of the bitmap 5x7. Is this dependent on the screen density etc., of the device?

saj-and
  • 479
  • 2
  • 9
  • 20
  • Adding some more information. Is it even possible to create jpegs in different devices using createbitmap and canvas to generate images of consistent dimensions across all devices? Irrespective of the device if the image is copied to a computer, all images should have the same dimensions, more or less. Does it even make sense, or I'm wondering if I'm going down the wrong path here.. – saj-and Apr 18 '15 at 20:38

2 Answers2

3

Try this method:

public void setViewInInches(float width, float height, View v) {
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int widthInches = Math.round(width * metrics.xdpi);
    int heightInches = Math.round(height * metrics.ydpi);
    v.setLayoutParams(new LinearLayout.LayoutParams(widthInches, heightInches));
    v.requestLayout();
}

Pass in the width and height, followed by the view you want to set it to and it should work. Sample call to set image view to 5x7:

setViewInInches(5f, 7f, imageView);
Zamereon
  • 376
  • 1
  • 2
  • 17
  • Thanks. I have had some inconsistent results using getmetrics in the past on some devices, kindle fire first generation for example. Can't remember the details, I will surely be trying this out and update this thread. – saj-and Apr 04 '15 at 12:54
  • I tried this method (had tried this before for a different requirement). It is creating different image sizes on different devices. I created the images using the same code on different devices and copied the image to the computer. They all have different dimensions, for example an image created on HTC One S Mini is showing 2415 X 1729 when I select the imaeg on my windows laptop. The one created on Samsung Tab 10.1 is 2105 X 1505 , Kindle Fire (first generation) shows 1152 X 828. I'm checking this by highlighting the image on the windows explorer, it shows the dimensions on the bottom bar. – saj-and Apr 18 '15 at 19:59
  • @saj-and any solution? – Ram Oct 13 '20 at 07:10
3

How large the final image will be printed on paper is up to the printer, however you can give hints how large it should be with Bitmap.setDensity(). Note that image density is simply a numeric metadata embedded in the image file and it is up to the output device (i.e. the printer) to interpret or obey the hint.

The relationship between images size in pixel and the density you need to set to achieve a certain size is a fairly simple math, if you have an image whose pixel size is 360x504 pixels and you want to print it so the physical size of 5x7 inch, you'll need to set the density to be: 360px / 5 inch = 72ppi.

int IMAGE_WIDTH_IN_PIXEL = 360;
int IMAGE_HEIGHT_IN_PIXEL = 504;
float TARGET_WIDTH_IN_INCH = 5;
float TARGET_HEIGHT_IN_INCH = 7;
Bitmap bitmap = Bitmap.createBitmap(IMAGE_WIDTH_IN_PIXEL, IMAGE_HEIGHT_IN_PIXEL, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
... draw something ...
// you need make sure the Bitmap had the same aspect ratio as the target printing size
assert IMAGE_WIDTH_IN_PIXEL / TARGET_WIDTH_IN_INCH == IMAGE_HEIGHT_IN_PIXEL / TARGET_HEIGHT_IN_INCH;
bitmap.setDensity(IMAGE_WIDTH_IN_PIXEL / TARGET_WIDTH_IN_INCH);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outfile);

Note that how large the image is printed has nothing to do with the device's screen density, which determines how large the image will be viewed on screen.

If you have a predetermined printing density though, for example, most regular printers can print at least at 300ppi, as it's the lowest ppi which would not appear with pixelation at typical reading distance. If you have a preset ppi, what you need to control is then the image pixel size when you render the image to the Bitmap. The relationship is again pretty simple, to print an image at 5in wide at 300ppi you'll need 300ppi * 5 in = 1500 pixel wide image.

int TARGET_DENSITY = 300;
float PHYSICAL_WIDTH_IN_INCH = 5;
float PHYSICAL_HEIGHT_IN_INCH = 7;
Bitmap bitmap = Bitmap.createBitmap(PHYSICAL_WIDTH_IN_INCH * TARGET_DENSITY, PHYSICAL_HEIGHT_IN_INCH * TARGET_DENSITY, Bitmap.Config.ARGB_8888);
bitmap.setDensity(TARGET_DENSITY);
Canvas canvas = new Canvas(bitmap);
... draw something ...
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outfile);

Another possibility if the printer service supports it is to submit the intended physical size separately along with the printing request. The printer then will ignore the embedded density hint and calculate the image density required to print at that size.

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
  • Hmmm, looking at http://stackoverflow.com/questions/21879142/android-how-to-get-or-set-print-dpi-dots-per-inch-of-jpeg-file-while-loa it does not appear that Android actually use the density set in setDensity() when saving the image to a file. If that's the case, then you might need to edit the density to the file yourself, which is going to be image format dependant. – Lie Ryan Apr 03 '15 at 04:50
  • Interesting, this is useful info. Will have to try in different devices and see how it behaves, I will update this thread. – saj-and Apr 04 '15 at 12:52
  • I'm out of luck with this one so far. Not so much about the printing, but with my basic requirement to sort of create a jpeg of fixed dimensions irrespective of which device created the image. I tried using display metrics and then use the dpi multiplied by my required dimensions. But that is creating images of different sizes on different devices. When I think about it more, the display metrics probably has to do with how the device displays the image, and not how it stores the image. If that is the case, how do I manage to create a consistent image in all devices. Is it even possible? – saj-and Apr 18 '15 at 20:02