2012-07-29 49 views
13

如何从相机获取具有特定(内存容量)大小的位图?相机通过意图返回的位图大小?

我开始照相机与意图:

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
cameraIntent.putExtra("return-data", true); 

photoUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "mytmpimg.jpg")); 
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);   

startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA); 

我这里处理结果:

// Bitmap photo = (Bitmap) intent.getExtras().get("data"); 

Bitmap photo = getBitmap(photoUri); 

现在,如果我使用注释行 - 直接将位图,我总是得到一个160 x 120位图,这太小了。如果我使用我发现的一些标准东西(方法getBitmap)从URI加载它,它将加载一个2560 x 1920位图(!),并消耗近20 MB内存。

如何加载比方说480 * 800(同样大小的相机预览显示我)?

而无需将2560×1920加载到内存中和按比例缩小。

+0

这有帮助吗? http://stackoverflow.com/questions/3331527/android-resize-a-large-bitmap-file-to-scaled-output-file – 2012-07-29 13:42:09

+0

也许,但没有办法让我在屏幕上看到的东西当拍照时......?我不需要更多。 – Ixx 2012-07-29 13:46:21

+0

Ben Rujil的链接指向我所知道的最佳答案。您的选择基本上是Intent中的缩略图或File中的原生分辨率照片。如果没有让相机应用程序以较低的分辨率保存照片,那是您的选择。 – Sparky 2012-07-29 22:25:46

回答

2

这里是我想出的基础上,从中旧Android版本移除的裁剪库调用getBitmap()方法。我做了一些修改:

private Bitmap getBitmap(Uri uri, int width, int height) { 
    InputStream in = null; 
    try { 
     int IMAGE_MAX_SIZE = Math.max(width, height); 
     in = getContentResolver().openInputStream(uri); 

     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 

     BitmapFactory.decodeStream(in, null, o); 
     in.close(); 

     int scale = 1; 
     if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { 
      scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/(double) Math.max(o.outHeight, o.outWidth))/Math.log(0.5))); 
     } 

     //adjust sample size such that the image is bigger than the result 
     scale -= 1; 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     in = getContentResolver().openInputStream(uri); 
     Bitmap b = BitmapFactory.decodeStream(in, null, o2); 
     in.close(); 

     //scale bitmap to desired size 
     Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, width, height, false); 

     //free memory 
     b.recycle(); 

     return scaledBitmap; 

    } catch (FileNotFoundException e) { 
    } catch (IOException e) { 
    } 
    return null; 
} 

这样做是加载使用BitmapFactory.Options()位图+一些样本量 - 这样,原始图像不会被加载到内存中。问题在于样本量正好在步骤中起作用。我使用我复制的一些数学得到了我的图像的“最小”样本大小 - 并减去1以获得将产生最小值的样本大小。位图大于我需要的大小。

再按顺序正好与所要求的尺寸来得到位图进行正常的缩放与Bitmap.createScaledBitmap(b, width, height, false);。并且在它回收了更大的位图后立即进行。这很重要,因为,例如,在我的情况下,为了获得480 x 800位图,较大的位图是1280 x 960,占用了4.6mb的内存。

了更大的内存友好的方式将不会调整scale,所以较小的位图将被调整以匹配所需的大小。但是这会降低图像的质量。