在Android中计算合适的图像大小

时间:2014-06-10 21:16:59

标签: android bitmap

我目前正在使用此处的代码解码Android中的图片:

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

我使用1024的MinSize进行解码,这在Galaxy S4,Galaxy Note 3,Galaxy Tab 3,Xperia Z和HTC One M8等高端设备上运行得非常好。

我遇到的唯一问题是在一些较弱的手机(如Galaxy S2和Nexus One)中崩溃应用程序。

我正在尝试将图像缩减为最小宽度和高度为1024像素,而在Galaxy S2和Nexus One上,当我尝试加载文件时,它会抛出OutOfMemoryError

有没有办法计算出合适的图像尺寸,不会让Galaxy S2和Nexus One崩溃,但仍然可以在Galaxy S4等高端设备上保持适当的质量?

Galaxy S2上崩溃的堆栈跟踪如下:

06-10 21:17:18.345 I/dalvikvm-heap( 5973): Forcing collection of SoftReferences for 5992720-byte allocation
06-10 21:17:18.380 D/dalvikvm( 5973): GC_BEFORE_OOM freed <1K, 17% free 36845K/43911K, paused 34ms, total 34ms
06-10 21:17:18.380 E/dalvikvm-heap( 5973): Out of memory on a 5992720-byte allocation.
06-10 21:17:18.380 I/dalvikvm( 5973): "Thread-3353" prio=5 tid=26 RUNNABLE
06-10 21:17:18.380 I/dalvikvm( 5973):   | group="main" sCount=0 dsCount=0 obj=0x420cf690 self=0x54c821a0
06-10 21:17:18.380 I/dalvikvm( 5973):   | sysTid=6099 nice=0 sched=0/0 cgrp=apps handle=1422403056
06-10 21:17:18.380 I/dalvikvm( 5973):   | schedstat=( 1566617822 87113594 202 ) utm=152 stm=4 core=0
06-10 21:17:18.385 I/dalvikvm( 5973):   at android.graphics.Bitmap.nativeCreate(Native Method)
06-10 21:17:18.385 I/dalvikvm( 5973):   at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
06-10 21:17:18.390 I/dalvikvm( 5973):   at android.graphics.Bitmap.createBitmap(Bitmap.java:575)
06-10 21:17:18.390 I/dalvikvm( 5973):   at android.graphics.Bitmap.createBitmap(Bitmap.java:501)
06-10 21:17:18.390 I/dalvikvm( 5973):   at com.aura.app.fragments.CameraFragment$AuraCameraHost.saveImage(CameraFragment.java:675)
06-10 21:17:18.390 I/dalvikvm( 5973):   at com.commonsware.cwac.camera.ImageCleanupTask.run(ImageCleanupTask.java:195)
06-10 21:17:18.390 I/dalvikvm( 5973): 
06-10 21:17:18.390 W/dalvikvm( 5973): threadid=26: thread exiting with uncaught exception (group=0x40f8d2a0)
06-10 21:17:18.390 E/ACRA    ( 5973): ACRA caught a OutOfMemoryError exception for com.aura.app. Building report.

编辑:

解码代码如下:

public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    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;

        // Calculate the largest inSampleSize value that is a power of 2 and
        // keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

public static Pair<Integer, Bitmap> decodeSampledBitmapFromByteArray(
        byte[] data, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(data, 0, data.length, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return new Pair<Integer, Bitmap>(options.inSampleSize,
            BitmapFactory.decodeByteArray(data, 0, data.length, options));
}

2 个答案:

答案 0 :(得分:1)

我假设您为reqWidthreqHeight使用了固定值1024。如果是这种情况,并且您在屏幕上显示图像,请获取屏幕的宽度和高度,并将其用作reqWidthreqHeight

通过使用1024的硬编码值,您可能会加载高达2047x2047px的图像,这对于较小的设备来说太大了。

答案 1 :(得分:-1)

您需要设置样本大小。我发现即使对于大型位图(如12MP照片),2也足够好。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;

image = BitmapFactory.decodeFile(filename, options);

其中filename是位图的文件名。