Reputation: 479
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?
Upvotes: 4
Views: 4565
Reputation: 64913
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.
Upvotes: 3
Reputation: 386
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);
Upvotes: 3