How Do You Deal With Insanely High Mp Cameras (and Images) On Android? - "canvas: Trying To Draw Too Large Bitmap"
Solution 1:
I tried this way to draw bitmap on canvas from URI
, try this:
(Explanation given below code)
privatevoiddrawBitmapUriOnCanvas(Uri selectedImage) {
if (selectedImage != null) {
BitmapFactory.OptionsbmpFactoryOptions=newBitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(getContentResolver().openInputStream(
selectedImage), null, bmpFactoryOptions);
bmpFactoryOptions.inSampleSize = 2;
bmpFactoryOptions.inJustDecodeBounds = false;
Bitmapbmp= BitmapFactory
.decodeStream(getContentResolver().openInputStream(
selectedImage), null, bmpFactoryOptions);
Bitmap alteredBitmap;
if (bmp != null) {
if (getDeviceRam(this) <= 1024) {
bmp = getResizedBitmap(bmp, displayWidth);
}
bmp = checkAndRotateBitmap(bmp);
alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
.getHeight(), bmp.getConfig());
Canvascanvas=newCanvas(alteredBitmap);
Paintpaint=newPaint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setAntiAlias(true);
Matrixmatrix=newMatrix();
canvas.drawBitmap(bmp, matrix, paint);
(now alteredBitmap is processed bitmap and you can use it)
}
} catch (FileNotFoundException e) {
Toast.makeText(this, "Error reading Image Metadata", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
Other included methods:
publicstaticlonggetDeviceRam(Context context) {
ActivityManageractManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfomemInfo=newActivityManager.MemoryInfo();
actManager.getMemoryInfo(memInfo);
longtotalMemory= memInfo.totalMem;
longfileSizeInKB= totalMemory / 1024;
// Convert the KB to MegaBytes (1 MB = 1024 KBytes)return fileSizeInKB / 1024;
}
publicstatic Bitmap getResizedBitmap(Bitmap image, int maxSize) {
intwidth= image.getWidth();
intheight= image.getHeight();
floatbitmapRatio= (float) width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
Here, first of all i decoded image uri using BitmapFactory
, then i checked device ram and it it was of 1GB then i resize the bitmap other wise original bitmap will be ok for next step,
And next was simply drawing bitmap on canvas and you will get alteredBitmap
will is processed bitmap and it will be easy to use.
If this will not work then there is another option for completing your requirement and it was given below:
Bitmapbitmap= getBitmapFromGallery(selectedImage.getPath(), 800, 800);
private Bitmap getBitmapFromGallery(String path, int width, int height) {
final BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, width, height);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmapbitmap= BitmapFactory.decodeFile(path, options);
// if you use image from camera then in some cases it will rotated automatically like it was captured landscape but displays portrait then you have to use method `checkAndRotateBitmap()` which was also given below// bitmap = checkAndRotateBitmap(bitmap);return bitmap;
}
publicstaticintcalculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of imagefinalintheight= options.outHeight;
finalintwidth= options.outWidth;
intinSampleSize=1;
if (height > reqHeight || width > reqWidth) {
finalinthalfHeight= height / 2;
finalinthalfWidth= width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both// height and width larger than the requested height and width.while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
private Bitmap checkAndRotateBitmap(Bitmap bmp) {
try {
ExifInterfaceei=newExifInterface(imgPath);
intorientation= ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Bitmap rotatedBitmap;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotatedBitmap = Helper.rotateImage(bmp, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotatedBitmap = Helper.rotateImage(bmp, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotatedBitmap = Helper.rotateImage(bmp, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
default:
rotatedBitmap = bmp;
}
return rotatedBitmap;
} catch (IOException e) {
e.printStackTrace();
return bmp;
}
}
EDIT
for more information on how getBitmapFromGallery()
method works, you should have look at https://medium.com/android-news/loading-large-bitmaps-efficiently-in-android-66826cd4ad53
That's all my friend, now try one of the methods for your requirement and let me know if this will work or not, also help me improve my answer if anything was wrong..Thank you!!
Post a Comment for "How Do You Deal With Insanely High Mp Cameras (and Images) On Android? - "canvas: Trying To Draw Too Large Bitmap""