2012-07-29 27 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) का उपयोग करके यूआरआई से लोड करता हूं, तो यह 2560 x 1920 बिटमैप (!) लोड करता है और यह लगभग 20 एमबी मेमोरी का उपभोग करता है।

मैं मान लीजिए कि 480 x 800 (एक ही आकार कैमरा पूर्वावलोकन मुझे पता चलता) जाने कैसे लोड करूं?

स्मृति में 2560 x 1920 लोड करने के लिए हो रही है और उसके आकार को बिना।

+0

क्या इससे मदद मिलती है? http://stackoverflow.com/questions/3331527/android-resize-a-large-bitmap-file-to-scaled-output-file –

+0

शायद, लेकिन वहाँ एक रास्ता सिर्फ पाने के लिए मैं क्या स्क्रीन पर दिखाई नहीं दे रहा है तस्वीर लेते समय ...? मुझे और कुछ चाहिए नहीं। – Ixx

+0

बेन रूजिल का लिंक मुझे पता है कि सबसे अच्छे जवाब के लिए इंगित करता है। आपकी पसंद मूल रूप से या तो इरादे में थंबनेल या फ़ाइल में मूल-रिज़ॉल्यूशन फोटो है। तस्वीर को कम रिज़ॉल्यूशन पर सहेजने के लिए कैमरा ऐप प्राप्त करना अनुपस्थित है, यह आपकी पसंद है। – Sparky

उत्तर

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.6 एमबी मेमोरी है।

एक और अधिक स्मृति scale समायोजित नहीं करने के लिए अनुकूल तरीके से होगा, इसलिए एक छोटे बिटमैप को बढ़ाया दिया जाएगा आवश्यक आकार मिलान करने के लिए। लेकिन यह छवि की गुणवत्ता को कम करेगा।