Bitmapfactory example
Building Bitmap Objects
1) From a File
Use the adb tool with push option to copy test2.png onto the sdcard
This is the easiest way to load bitmaps from the sdcard. Simply pass the path to the image to BitmapFactory.decodeFile() and let the Android SDK do the rest.
public class TestImages extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image = (ImageView) findViewById(R.id.test_image);
Bitmap bMap = BitmapFactory.decodeFile("/sdcard/test2.png");
image.setImageBitmap(bMap);
}
}
All this code does is load the image test2.png that we previously copied to the sdcard. The BitmapFactory creates a bitmap object with this image and we use the ImageView.setImageBitmap()
method to update the ImageView component.
2) From an Input stream
Use BitmapFactory.decodeStream()
to convert a BufferedInputStream into a bitmap object.
public class TestImages extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image = (ImageView) findViewById(R.id.test_image);
FileInputStream in;
BufferedInputStream buf;
try {
in = new FileInputStream("/sdcard/test2.png");
buf = new BufferedInputStream(in);
Bitmap bMap = BitmapFactory.decodeStream(buf);
image.setImageBitmap(bMap);
if (in != null) {
in.close();
}
if (buf != null) {
buf.close();
}
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
}
}
This code uses the basic Java FileInputStream and BufferedInputStream to create the input stream for BitmapFactory.decodeStream()
. The file access code should be surrounded by a try/catch block to catch any exceptions thrown by FileInputStream or BufferedInputStream. Also when you're finished with the stream handles they should be closed.
3) From your Android project's resources
Use BitmapFactory.decodeResource(res, id)
to get a bitmap from an Android resource.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image = (ImageView) findViewById(R.id.test_image);
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
image.setImageBitmap(bMap);
}
Android BitmapFactory.decodeFile(path) always returns null
Or use the simple method of BitmapFactory
BitmapFactory.decodeResource(getResources(), R.id.arrow);
Or you can use context.getDrawable(R.drawable.arrow)
which will return a drawable
that is ready to use.
Read more about this here
If you would like to still use the path then use java.nio.file.Paths(folder1, folder2.. .. .)
Read more about this here
BitmapFactory.decodeStream from Assets returns null on Android 7
I think we are in the same boat. My team stuck in this problem for a while like you.
It seems be a problem in BitmapFactory.cpp (https://android.googlesource.com/platform/frameworks/base.git/+/master/core/jni/android/graphics/BitmapFactory.cpp) Some code was added in Android 7.0 and made the problem occurred.
// Create the codec.
NinePatchPeeker peeker;
std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(), &peeker));
if (!codec.get()) {
return nullObjectReturn("SkAndroidCodec::NewFromStream returned null");
}
And I found out the BitmapFactory.decodeStream
method didn't create the bitmap after we set inJustDecodeBounds=false
but when I try to create bitmap without bound decoding. It's works! The problem is about BitmapOptions in that InputStream doesn't updated when we called BitmapFactory.decodeStream
again.
So I reset that InputStream before decode again
private Bitmap getBitmapFromAssets(Context context, String fileName, int width, int height) {
AssetManager asset = context.getAssets();
InputStream is;
try {
is = asset.open(fileName);
} catch (IOException e) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
try {
is.reset();
} catch (IOException e) {
return null;
}
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(is, null, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
It's looks like we have to reset InputStream every time before reuse it.
bitmapFactory.decodefile giving null as output
- Make sure the obtained file path is a valid path.
- Make sure you have the permissions to access storage.
If above things are okay and you still get null result, try following code:
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
BitmapFactory.decodeFile returns null
Remove the following from your code:
options.inJustDecodeBounds = true;
From the documentation of inJustDecodeBounds
:
If set to true, the decoder will return null (no bitmap), but the
out... fields will still be set, allowing the caller to query the
bitmap without having to allocate the memory for its pixels.
inJustDecodeBounds
is useful to load large Bitmap
s efficiently, since you can read their dimensions without having to allocate the memory for them, although it has no purpose in your code.
BitmapFactory can't decode a Bitmap from Uri after photos taken on Android Nougat
I tried your code. Here's the sample of my try.https://github.com/raghunandankavi2010/SamplesAndroid/tree/master/StackOverFlowTest.
Have a look at this blog https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html
In the blog commonsware mentions that you should not do new File (mPicPath.getPath())
.
Instead you should use the below in onActivityResult
try {
InputStream ims = getContentResolver().openInputStream(mPicPath);
// just display image in imageview
imageView.setImageBitmap(BitmapFactory.decodeStream(ims));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
And the xml
<external-files-path name="external_files" path="path" />
Note: its a content uri that you have. On my phone i get the uri as below. Tested only on Nexus6p.
content://com.example.raghu.stackoverflowtest.fileProvider/external_files/Pictures/JPEG_20170424_161429691143693160.jpg
More on file provider https://developer.android.com/reference/android/support/v4/content/FileProvider.html
Android: BitmapFactory.decodeByteArray - reduce image quality
Is there any solution using BitmapFactory.Options which can lead to the same result as bitmap.compress: lower quality, same dimensions?
Not really. A Bitmap
is uncompressed by its very nature.
The problem is, that in my case I cannot use bitmap.compress because my bitmap is null.
You are confusing an encoded JPEG image with a Bitmap
. An encoded JPEG image is compressed. A Bitmap
is not. A Bitmap
always consumes memory based on the width, height, and the number of bits per pixel.
You could use a different number of bits per pixel. BitmapFactory
uses ARGB_8888
(32 bits/pixel). You could switch to RGB_565
(16 bits/pixel), if your image has no alpha channel and you can live with the reduced range of colors.
Otherwise, your only option is to reduce the size (width and height) of the image.
Related Topics
Error:Execution Failed for Task ':App:Kaptdebugkotlin'
Check for Access to Notifications Using Notificationlistenerservice
Stop Scrollview from Auto-Scrolling to an Edittext
How to Make Space Between Linearlayout Children
How to Repeat Notification Daily on Specific Time in Android Through Background Service
Recyclerview Smoothscroll to Position in The Center. Android
Db File in Assets Folder. Will It Be Updated
How to Execute Background Task When Android App Is Closed/Set to Background
Change The Background Color of Cardview Programmatically
Supporting Amazon and Android Market (Google Play) Links Inside Application
When Using Alertdialog.Builder with Edittext, The Soft Keyboard Doesn't Pop
List View Item Swipe Left and Swipe Right
Putting Screen Densities into The Correct Bucket