来自Assets的BitmapFactory.decodeStream在Android 7上返回null [英] BitmapFactory.decodeStream from Assets returns null on Android 7

查看:152
本文介绍了来自Assets的BitmapFactory.decodeStream在Android 7上返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Android 7中解码Asset目录中的位图?

How to decode bitmaps from Asset directory in Android 7?

我的应用"在高达棉花糖的Android版本上运行良好.使用Android 7时,无法从Asset目录加载图像.

My App is running well on Android versions up to Marshmallow. With Android 7 it fails to load images from the Asset directory.

我的代码:

private Bitmap getImage(String imagename) {
    // Log.dd(logger, "AsyncImageLoader: " + ORDNER_IMAGES + imagename);

    AssetManager asset = context.getAssets();
    InputStream is = null;
    try {
        is = asset.open(ORDNER_IMAGES + imagename);
    } catch (IOException e) {
        // Log.de(logger, "image konnte nicht gelesen werden: " + ORDNER_IMAGES + imagename);
        return null;
    }


    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, PW, PH);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    // Lesen des Bitmaps in der optimierten Groesse
    return BitmapFactory.decodeStream(is, null, options);

}

结果(仅适用于Android 7) BitmapFactory.decodeStream 为空.它可以在较旧的Android API上正常工作.

As a result (only Android 7) BitmapFactory.decodeStream is null. It works correctly an older Android APIs.

在调试模式下,我看到以下消息:

In debug mode I see the following Message:

09-04 10:10:50.384 6274-6610/myapp D/skia:--SkAndroidCodec :: NewFromStream返回null

09-04 10:10:50.384 6274-6610/myapp D/skia: --- SkAndroidCodec::NewFromStream returned null

有人可以告诉我原因以及如何纠正编码吗?

Can someone tell me the reason and how to correct the coding?

同时,我发现使用inJustDecodeBounds = true删除第一个BitmapFactory.decodeStream会导致之后使用inJustDecodeBounds = false的BitmapFactory.decodeStream成功.不知道原因,也不知道如何替代位图​​大小的度量.

Meanwhile i found, that removing of the first BitmapFactory.decodeStream with inJustDecodeBounds=true leads to a successful BitmapFactory.decodeStream afterwards with inJustDecodeBounds=false. Don't know the reason and don't know how to substitute the measurement of bitmap size.

推荐答案

我认为我们在同一条船上.我的团队像您一样在这个问题上停留了一段时间.

I think we are in the same boat. My team stuck in this problem for a while like you.

BitmapFactory.cpp(

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");
}

当我设置 inJustDecodeBounds = false 后,我发现 BitmapFactory.decodeStream 方法没有创建位图,但是当我尝试创建没有绑定解码的位图时.其作品!问题与BitmapOptions有关,因为当我们再次调用 BitmapFactory.decodeStream 时,InputStream不会更新.

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.

所以我先重置InputStream,然后再进行解码

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;
}

似乎我们每次都必须重置InputStream才能重新使用它.

It's looks like we have to reset InputStream every time before reuse it.

这篇关于来自Assets的BitmapFactory.decodeStream在Android 7上返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆