Android OutOfMemoryError 大图像

2023-11-29

对于尺寸较大的图像(不是按分辨率),该方法会抛出 OutOfMemoryError 我有 12 MP 照片,所有照片的大小都不同(1.5MB、2.5MB、3.2MB、4.1MB)等,所有照片的分辨率都是相同的 4000 x 3000(像素)。

resizer 方法对于大小小于 3MB 的图像效果很好,但对于那些大于 3MB 的图像,它会抛出 OutOfMemoryError 我不知道什么可以解决它,我的应用程序主要用于调整大图像的大小,这真的让我无处可去。

调整大小的方法是:

public File resizeBitmap(String imPath, int reqSize) {
    File fl = null;
    try{

    // First decode with inJustDecodeBounds=true to check dimensions

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;

    BitmapFactory.decodeFile(imPath, options);

    // Calculate inSampleSize

    options.inSampleSize = calculateInSampleSize(options, reqSize);

    // Decode bitmap with inSampleSize set

    options.inJustDecodeBounds = false;
    Bitmap saveImg = BitmapFactory.decodeFile(imPath, options);

    //save resized image
    String tmpName = "IMG_"+String.valueOf(System.currentTimeMillis()) + ".jpg";
    fl = fileCache.getRawFile(tmpName);
    FileOutputStream fos = new FileOutputStream(fl);
    saveImg.compress(Bitmap.CompressFormat.JPEG, 95, fos);
    saveImg.recycle();


    return fl;
}
catch (Throwable eex){
    eex.printStackTrace();
    if(eex instanceof OutOfMemoryError) {
        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(Resizer.this, "Memory ran out", Toast.LENGTH_SHORT).show();
            }
        });
    }
    return null;
 }
}
//Method for calculating insamplesize
public int calculateInSampleSize(BitmapFactory.Options options, int reqSize) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.i("width",""+width);
Log.i("height",""+height);
int inSampleSize = 1;

if (height > reqSize || width > reqSize) {

        if (width > height) {
            inSampleSize = Math.round((float) height / (float) reqSize);
        } else {
            inSampleSize = Math.round((float) width / (float) reqSize);
         }


}

return inSampleSize;

}

//Stacktrace
04-11 09:01:19.832: W/System.err(8832): java.lang.OutOfMemoryError
04-11 09:01:19.953: W/System.err(8832):     at  android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
04-11 09:01:19.972: W/System.err(8832):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
04-11 09:01:19.993: W/System.err(8832):     at com.scale.app.Resizer.resizeBitmap(Resizer.java:1290)

阅读文章

图像尺寸:4000*3000 像素

当图像加载时:4000*3000*4 = ?知识库

所以,Android设备的虚拟堆内存有:32 MB、64 MB、128 MB...等等

如果您使用:

<application

    android:largeHeap="true">

</application>

这将增加 VHM 双倍(如果 32 MB = 2* 32 MB)。但这不是一个好方法,会影响操作系统

您需要减小图像的尺寸。


使用下面的类并传递图像的路径和宽度,高度你想要的

位图 bitmap = BitmapSize.getDecodedBitmap(path, 400, 400);

班级::::

public class BitmapSize{



public static Bitmap getDecodedBitmap(String path, float target_width, float target_height) {
    Bitmap outBitmap = null;
    try {
        Options decode_options = new Options();
        decode_options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path,decode_options);  //This will just fill the output parameters
        int inSampleSize = calculateInSampleSize(decode_options, target_width, target_height);

        Options outOptions = new Options();
        outOptions.inJustDecodeBounds = false;
        outOptions.inSampleSize = inSampleSize;
        outOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
        outOptions.inScaled = false;

        Bitmap decodedBitmap = BitmapFactory.decodeFile(path,outOptions);
        outBitmap = Bitmap.createScaledBitmap(decodedBitmap,// (int)target_width, (int)target_height, true);
                (int)((float)decodedBitmap.getWidth() / inSampleSize),
                (int)((float)decodedBitmap.getHeight() / inSampleSize), true);
        System.out.println("Decoded Bitmap: Width "  + outBitmap.getWidth() + " Height = " + outBitmap.getHeight() + " inSampleSize = " + inSampleSize);

    } catch (Exception e) {
        // TODO: handle exception
    }

    return outBitmap;
}

public static int calculateInSampleSize(Options options, float reqWidth, float reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android OutOfMemoryError 大图像 的相关文章

随机推荐

  • 页面重新加载时正在进行的 Ajax 请求会发生什么情况 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我们有报告页面 用户可以在其中导出 CSV 格式的报告 在服务器中C MVC我们创造MemoryStream并在数据转换后写入每一行 最后将响应作为File 请求完成后 浏览器会
  • 我应该在 JPA 实体 equals 方法中使用 getter 或字段吗?

    当写一个equals我的 JPA 实体的方法 我应该直接访问字段 还是应该通过 getter 换句话说 我这样做吗 Override public boolean equals Object o if this o return true
  • 使用官方 Alpine Docker 镜像向 php 添加 yaml 扩展

    我正在使用这个官方 php Docker 镜像 https github com docker library php blob 76a1c5ca161f1ed6aafb2c2d26f83ec17360bc68 7 1 alpine Doc
  • Windows:文件被进程锁定

    是否有另一个 winapi 调用来检测哪些文件被特定锁定 然后使用duplicatehandle和ntquerysysteminformation进行处理 我正在使用重启管理器 api 来注册我正在寻找的文件 但是 不幸的是 重启管理器 a
  • 如何在 GCP BigQuery 联合查询中使用查询参数

    我有一个基于 gcp 的环境 我在 gcp BigQuery 中使用标准 SQL 脚本 并在 cloudsql MySql 中使用联合查询 联合查询从cloudsql mysql数据库中选择数据 我需要根据依赖于 BigQuery 中数据的
  • 我可以使用Environment.GetEnvironmentVariable方法从Azure应用程序设置中读取环境变量吗?

    我正在将 Firebase SDK 添加到服务器 第一步是设置 GOOGLE APPLICATION CREDENTIALS 环境变量 所以我在中设置环境变量Azure 服务 gt 配置 gt 应用程序设置 我检查了环境变量kudu too
  • GNU GCC 编译器错误“main 的多重定义”

    我是 ubuntu 新手 现在我需要用 C 开发我的作业 我正在使用 codeblocks IDE 编写 C 程序 每当我在其中编译某些内容时 都会出现以下错误 multiple definition of main warning con
  • 在循环中使用innerHTML无法正确显示json结果集

    我使用 HTML onclick 事件来调用一个函数 该函数将读取包含 JSON 语法的 Javascript 字符串并输出结果 但仅显示最后一个结果 var resorts skiResorts resortName Afton Alps
  • firebase 逆序排序

    var playersRef firebase database ref team mapping playersRef orderByChild score limitToFirst 7 on child added function d
  • 使用 OU 的部分路径在 Active Directory 中搜索 OU

    AD 查询语法中是否有一种方法可以通过搜索 OU 的部分路径来查找 OU 的完整路径 例如 我的 OU 的完整路径是 OU Clerks OU OfficeA OU Administration DC domain DC local 现在
  • gif 动画在 Chrome 和 Firefox 中仅循环一次

    我有一个 gif 动画 我想在页面加载时随时显示它 当我在浏览器外部查看图像时 图像无限循环并且工作得很好 但每当我在浏览器中显示图像时 动画仅循环一次 有人对让图像无限循环有什么建议吗 目前 我这样做只是为了使图像出现 这确实使它出现 但
  • 在 R 中读取两行标题

    当标题有两行必要的标题时 将文件读入 R 的最佳方法是什么 这种情况经常发生在我身上 因为人们经常使用一行作为列名称 然后在其下面包含另一行作为测量单位 我不想跳过任何事情 我希望将名称和单位保留下来 这是什么具有两个标头的典型文件可能如下
  • 无法使用 gethostbyname() 获取本地 IP

    一位朋友用过以下代码片段检索 LAN 中主机的本地 IP 地址 int buffersize 512 char name buffersize if gethostname name buffersize 1 Exception excep
  • 为什么 deref 强制转换不适用于 `From::from`?

    来自section在书里 Deref 强制转换将引用转换为实现Deref特征转换为对另一种类型的引用 它会自动发生 当我们传递对特定类型值的引用作为参数时 与参数类型不匹配的函数或方法 函数或方法定义 我正在尝试找出两者之间的区别bar a
  • Z3 优化超时

    如何为 z3 优化器设置超时 以便在超时时为您提供最知名的解决方案 from z3 import s Optimize Hard Problem print s check print s model 后续问题 你可以将z3设置为随机爬山还
  • NHibernate 删除 DAL?

    使用 NHibernate 或任何其他 ORM 消除了 DAL 的必要性 我说得对吗 或不 我试图思考如何回答这个问题 但答案是否定的 它不会消除 DAL 的必要性 而不是成为该 DAL 的一部分 毫无疑问 您之前所做的就是访问调用 sql
  • Spring @Bean 与 @Lookup 方法

    我已经利用 Lookup 注释实现了一个 Spring bean 该线程很有帮助 如何使用spring Lookup注解 随后我注意到一种奇怪的行为 我不确定是有意为之还是我自己的误解 Spring 将在使用 Service Compone
  • Android 中的图像内存管理

    这是初学者最常问的问题之一 但不幸的是我仍然无法得到任何帮助 在一个活动中 我有一个 viewflipper 我以编程方式将图像视图分配给它 使用 for 循环将大约 100 个图像添加到 viewflipper 可能是由于图像大小或由于图
  • 基于 redshift 中的自表查找更新表

    我有下表 id email mgr email mgr id 1 email1 email2 2 email2 email3 3 email3 email4 我想通过将 mgr email 与电子邮件匹配来填充 id 列中的 mgr id
  • Android OutOfMemoryError 大图像

    对于尺寸较大的图像 不是按分辨率 该方法会抛出 OutOfMemoryError 我有 12 MP 照片 所有照片的大小都不同 1 5MB 2 5MB 3 2MB 4 1MB 等 所有照片的分辨率都是相同的 4000 x 3000 像素 r