Bitmapfactory Example

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 Bitmaps 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



Leave a reply



Submit