【问题标题】:BitmapFactory.decodeFile always return null on XiaomiBitmapFactory.decodeFile 在小米上总是返回 null
【发布时间】:2014-10-03 04:10:32
【问题描述】:

你好,我有这段代码:

编辑:

imageName = data.getData();

try{
    InputStream stream = getContentResolver().openInputStream(imageName);

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    bitmap = BitmapFactory.decodeStream(stream,null,options);

    final int REQUIRED_WIDTH=(int)screenWidth;
    final int REQUIRED_HIGHT=(int)screenHeight;

    int scale=1;
    while(options.outWidth/scale/2>=REQUIRED_WIDTH && options.outHeight/scale/2>=REQUIRED_HIGHT)
        scale*=2;

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize=scale;
    bitmap = BitmapFactory.decodeStream(stream, null, o2);

    if ( bitmap != null ){
        ok=true;
    }
}catch(Exception e){
    Toast.makeText(getBaseContext(),"error", Toast.LENGTH_SHORT).show();
}

但位图仍然为空

谁能告诉我为什么?或更好...如何解决?

【问题讨论】:

  • 什么是getPathFromURI()?如果是我认为的那样,请摆脱它,如a Uri is not necessarily a File
  • 我不明白。我会在这里添加方法
  • 删除该方法。阅读the blog post that I linked to。在ContentResolver 上使用openInputStream() 读取Uri 上的数据。
  • 请检查我的更新
  • 此时,我不知道你在做什么。如果您的目标是在Uri 表示的数据上获取Bitmap 对象,只需将stream 传递给decodeStream() 并去掉tmpByteArrayOutputStreamByteArrayInputStream。请记住,对于您的堆空间而言,图像可能太大。

标签: android bitmapfactory


【解决方案1】:

好的,所以如果我像现在在编辑后的帖子中那样做,我如何“调整”图像的大小以摆脱 outOfMemory Exception ?

啊哈!现在我们正在取得进展。

在您的问题之前的编辑中,您所拥有的是:

  1. 将整个位图读入一个字节数组
  2. 将整个位图作为低质量 JPEG 写入另一个字节数组
  3. 将整个位图读入Bitmap,由第三个字节数组支持

这将导致您消耗大约 2.1 倍的当前实现的堆空间,这已经给了您OutOfMemoryError 消息。上面 #1 和 #3 的字节数组大小相同,等于:

width x height x 4

宽度和高度以像素表示。

为了减少你的内存消耗,你需要做的事情:

  1. 读取位图一次,就像您当前的代码一样。

  2. 使用BitmapFactory.Options 控制位图的解码。特别是,use inSampleSize 减少了生成的Bitmap 中的像素数。引用 inSampleSize 的 JavaDocs:

如果设置的值 > 1,则请求解码器对原始图像进行二次采样,返回较小的图像以节省内存。样本大小是对应于解码位图中的单个像素的任一维度中的像素数。例如, inSampleSize == 4 返回的图像是原始宽度/高度的 1/4,像素数的 1/16。任何

This sample project 演示了将inSampleSize 用于各种硬编码值。实际Bitmap 加载来自:

private Bitmap load(String path, int inSampleSize) throws IOException {
  BitmapFactory.Options opts=new BitmapFactory.Options();

  opts.inSampleSize=inSampleSize;

  return(BitmapFactory.decodeStream(assets().open(path), null, opts));
}

【讨论】:

    【解决方案2】:

    您的 getPathFromUri 方法失败。它应该返回类似/storage/emulated/0/DCIM/camera/bla bla.jpg 的内容。 file:// 是权威,不是路径的一部分。 BitmapFactory 正在寻找一个实际的文件位置路径。

    您可以手动剥离它或使用 Uri 类,如下所示:

    Uri imgUri = Uri.parse(imgPath);
    String filePath = imgUri.getPath();
    

    【讨论】:

    • 仍然无法正常工作...现在 file:/// 已消失但仍为空
    猜你喜欢
    • 1970-01-01
    • 2016-10-17
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多