2012-07-29 33 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,所以較小的位圖將被調整以匹配所需的大小。但是這會降低圖像的質量。