Create Bitmap NullPointerException
I have a crash in an application that doesn't seem to work.
I am getting a bitmap from a resource like this.
Bitmap bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.map_distance_tag);
Now this seems to have problems on a very small minority of devices when it comes to creating a bitmap from that bitmap. For example...
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
I get NullPointerException
when it creates a line Bitmap
at line 468 of the class Bitmap
I was looking at and its when it sets the density scale of a new bitmap from its bitmap.
// The new bitmap was created from a known bitmap source so assume that
467 // they use the same density scale
468 bitmap.setDensityScale(source.getDensityScale());
Now I can't recreate the problem, but the fact that I don't get an exception when getWidth () is called on the original Bitmap tells me that the source is not null.
Here's the whole stack trace.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.app/com.my.app.recording.TrackingActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
at com.my.app.maps.MapFragment.createTabOverlay(MapFragment.java:663)
at com.my.app.maps.MapFragment.addMarkersForToolType(MapFragment.java:474)
at com.my.app.maps.MapFragment.onActivityCreated(MapFragment.java:405)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1468)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551)
at com.my.app.recording.TrackingActivity.onStart(TrackingActivity.java:272)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
at android.app.Activity.performStart(Activity.java:3781)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2636)
... 11 more
My idea
Could this be something related to me not including different bitmaps for different screen densities? All Bitmaps supplied are for mdpi screens.
I notice there is also a BackStackRecord. Could it crash when clicked by the user?
thanks in advance
source to share
The source you point to Bitmap.java:468
is on Android 1.5 and this is probably not your problem.
bitmap.setDensityScale(source.getDensityScale());
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
Line 468, in anything later than 2.2, is either part of the javadoc block or an unrelated function, so I'm assuming you are looking at version 1.6-2.2 and not the one you are trying to eliminate.
The only thing I can see on this line that can actually be null is config
. In your code, you are using getConfig()
to grab this from the current bitmap object. The docs for it show:
public final Bitmap.Config getConfig ()
Added to API level 1
If the internal bitmap configuration is in one of the common formats, return that configuration, otherwise return zero.
So it probably doesn't find the "public" format and returns null, which goes to createBitmap()
, and blows up your code.
You can use static config all the time, for example Bitmap.Config.ARGB_8888
, or do getConfig()
on the previous line and leave it blank - Check it out. If null, go to fallback configuration as above.
source to share
yourSelectedImageBitmap = BitmapFactory.decodeFile (filePath, options);
if (yourSelectedImageBitmap != null) {
// ----------resize for set in imageView------------
int width = yourSelectedImageBitmap.getWidth();
int height = yourSelectedImageBitmap.getHeight();
int newWidth = 140;
int newHeight = 140;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
if (exifOrientation.equals("6")) {
matrix.postRotate(90);
}
Bitmap resizedBitmap = Bitmap.createBitmap(yourSelectedImageBitmap,
0, 0, width, height, matrix, true);
image.setImageBitmap(resizedBitmap);
// Toast.makeText(getApplicationContext(),
// "in the select image loop", 2000).show();
// ----------resize for upload------------
int width1 = yourSelectedImageBitmap.getWidth();
int height1 = yourSelectedImageBitmap.getHeight();
You can try try this way. After getting an image from a file or camera source.
and then doing it.
Matrix matrix1 = new Matrix();
// resize the bit map
matrix.postScale(width1, height1);
if (exifOrientation.equals("6")) {
matrix1.postRotate(90);
}
Bitmap resizedBitmap1 = Bitmap.createBitmap(
yourSelectedImageBitmap, 0, 0, width1, height1, matrix1,
true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
resizedBitmap1.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] image_bytes = baos.toByteArray();
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("~~~~~~~~IOException~~~~~~~~~eeeeee~~~~",
"~~~~~~IOException~~~~~~~~~eeeee~~~~" + e.getMessage());
}
image_string = Base64.encodeToString(image_bytes, 0);
Hope this helps you
source to share
You can do the following:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
Bitmap bmpCompressed = Bitmap.createScaledBitmap(bitmap, 600, 400, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// CompressFormat set up to JPG, you can change to PNG
bmpCompressed.compress(CompressFormat.JPEG, 90, bos);
imageByteArray = bos.toByteArray();
source to share
I think this will work
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true; //you have to set bitmap to mutable
bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.map_distance_tag,opt);
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), Bitmap.Config.ARGB_8888);
//if you want to copy the bmp1 to bmOverlay
bmOverlay=Bitmap.createScaledBitmap(bmp1, bmp1.getWidth, bmp1.getHeight, false);
OR
//if did not work replace bmOverlay to this:
bmOverlay = Bitmap.createBitmap(bmp1);
source to share