2012-01-06 22 views
6

अद्यतन हो सकता है नई गतिविधि में बिटमैप आकार बदलने समस्या हल हो सकतीएंड्रॉयड कैमरा चित्र के आकार को कम

String myRef = this.getIntent().getStringExtra("filepath"); 
    File imgFile = new File(myRef); 

    Log.e("BeatEmUp", myRef); 
    if(imgFile.exists()){ 

     Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); 
     ImageView myImage = (ImageView) findViewById(R.id.imagepunch); 
     myImage.setImageBitmap(myBitmap); 

    } 

कुछ इस तरह हो सकता है?

Bitmap scaled = Bitmap.createScaledBitmap(bit, 200, 200, true);

या हो सकता है कि यह नीचे

सबसे अच्छा तरीका है अब तक मैं अपने ऐप जो एक तस्वीर ले जा रहा है और फिर एक नई Activity में प्रदर्शन एक Intent का उपयोग करने पर चित्र ले जाने के लिए और है । एक बार ऐसा करने के बाद मेरे पास कुछ कोड है जो शीर्ष पर छवियों को onClick के साथ प्रदर्शित करता है। समस्या यह है कि जब छवि ली जाती है तो इसे अधिकतम आकार में लिया जा रहा है, मुझे लगता है कि मेरा ऐप बंद हो रहा है।

मेरे लॉगकट में मुझे java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) मिल रहा है जो मुझे लगता है कि छवि बहुत बड़ी है।

मैंने कैमरे की छवि के बजाय कोड में एक छोटी छवि डालने का परीक्षण किया है और यह काम करता है जो मुझे समस्या की ओर ले जाता है कि यह कैमरा चित्र का आकार है।

तो मैं This From CommonsWare को लागू करने की कोशिश कर रहा हूं लेकिन अब तक कोई भाग्य नहीं है। कोड के माध्यम से देखकर मुझे लगता है कि यह सबसे छोटे resouloution/आकार के लिए खोज करता है और फिर कैमरे को उन सेटिंग्स का उपयोग कर लेता है, मैं सही सोच रहा हूं और यदि ऐसा है तो मैं इसे अपने कोड में कैसे कार्यान्वित कर सकता हूं?

public class AndroidCamera extends Activity implements SurfaceHolder.Callback{ 

Camera camera; 
SurfaceView surfaceView; 
SurfaceHolder surfaceHolder; 
boolean previewing = false; 
LayoutInflater controlInflater = null; 

final int RESULT_SAVEIMAGE = 0; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 



    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

    getWindow().setFormat(PixelFormat.UNKNOWN); 
    surfaceView = (SurfaceView)findViewById(R.id.camerapreview); 
    surfaceHolder = surfaceView.getHolder(); 
    surfaceHolder.addCallback(this); 
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    controlInflater = LayoutInflater.from(getBaseContext()); 
    View viewControl = controlInflater.inflate(R.layout.control, null); 
    LayoutParams layoutParamsControl 
     = new LayoutParams(LayoutParams.FILL_PARENT, 
     LayoutParams.FILL_PARENT); 
    this.addContentView(viewControl, layoutParamsControl); 

    Button buttonTakePicture = (Button)findViewById(R.id.takepicture); 
    buttonTakePicture.setOnClickListener(new Button.OnClickListener(){ 

     public void onClick(View arg0) { 
      // TODO Auto-generated method stub 
      camera.takePicture(myShutterCallback, 
        myPictureCallback_RAW, myPictureCallback_JPG); 



     }}); 

} 

ShutterCallback myShutterCallback = new ShutterCallback(){ 

    public void onShutter() { 
     // TODO Auto-generated method stub 

    }}; 

PictureCallback myPictureCallback_RAW = new PictureCallback(){ 

    public void onPictureTaken(byte[] arg0, Camera arg1) { 
     // TODO Auto-generated method stub 

    }}; 

PictureCallback myPictureCallback_JPG = new PictureCallback(){ 

    public void onPictureTaken(byte[] arg0, Camera arg1) { 
     // TODO Auto-generated method stub 
     /*Bitmap bitmapPicture 
      = BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */ 
     int imageNum = 0; 
     Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
     File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch"); 
     imagesFolder.mkdirs(); // <---- 
     String fileName = "image_" + String.valueOf(imageNum) + ".jpg"; 
     File output = new File(imagesFolder, fileName); 
     while (output.exists()){ 
      imageNum++; 
      fileName = "image_" + String.valueOf(imageNum) + ".jpg"; 
      output = new File(imagesFolder, fileName); 
     } 

     Uri uriSavedImage = Uri.fromFile(output); 
     imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); 


     OutputStream imageFileOS; 
     try { 
      imageFileOS = getContentResolver().openOutputStream(uriSavedImage); 
      imageFileOS.write(arg0); 
      imageFileOS.flush(); 
      imageFileOS.close(); 

      Toast.makeText(AndroidCamera.this, 
        "Image saved", 
        Toast.LENGTH_LONG).show(); 

     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     Intent intent = new Intent(getBaseContext(), Punch.class); 
     intent.putExtra("filepath",Uri.parse(output.getAbsolutePath()).toString()); 
     //just using a request code of zero 
     int request=0; 
     startActivityForResult(intent,request); 
    }}; 

public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    // TODO Auto-generated method stub 
    if(previewing){ 
     camera.stopPreview(); 
     previewing = false; 
    } 

    if (camera != null){ 
     try { 
      camera.setPreviewDisplay(surfaceHolder); 
      camera.startPreview(); 
      previewing = true; 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      camera.release(); 
      e.printStackTrace(); 
     } 
    } 
} 





public void surfaceCreated(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 

    camera = Camera.open(); 
    try { 
      Camera.Parameters parameters = camera.getParameters(); 

      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { 
       // This is an undocumented although widely known feature 
       parameters.set("orientation", "portrait"); 
       // For Android 2.2 and above 
       camera.setDisplayOrientation(90); 
       // Uncomment for Android 2.0 and above 
       parameters.setRotation(90); 
      } else { 
       // This is an undocumented although widely known feature 
       parameters.set("orientation", "landscape"); 
       // For Android 2.2 and above 
       camera.setDisplayOrientation(0); 
       // Uncomment for Android 2.0 and above 
       parameters.setRotation(0); 
      } 


      camera.setParameters(parameters); 
      camera.setPreviewDisplay(holder); 
     } catch (IOException exception) { 
     camera.release(); 


     } 
     camera.startPreview(); 

    } 


public void surfaceDestroyed(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 
    if(previewing && camera != null) { 
     if(camera!=null) { 
      camera.stopPreview(); 
      camera.release(); 
      camera = null; 
     } 
     previewing = false; 
    } 
} 


} 
+0

यह वही है जो आप करने की कोशिश कर रहे हैं --- तस्वीर लें, नई गतिविधि में छवि को उस पर क्लिक करें? यदि मैं सही हूं तो आपको क्लिक करने के लिए मध्यम आकार की छवि की आवश्यकता है? –

+0

@ मोहित शर्मा: मैं आपको काफी समझ नहीं पा रहा हूं लेकिन हां, – Matt

उत्तर

13

So far I have my app which is taking a picture and then using an Intent to carry the picture over and display in a new Activity.

ज्यादातर मामलों में, Intent एक्स्ट्रा कलाकार का उपयोग कर गतिविधियों के बीच डेटा गुजर एक ठीक समाधान है। बड़े बिटकमैप, हालांकि, स्मृति खपत के कारण इस तरह की समस्याएं पैदा करते हैं। यह एक ऐसा मामला है जहां मैं ध्यान से एक स्थिर डेटा सदस्य का उपयोग करूंगा।

In my logcat I am getting java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) which I think means that the image is too large.

इसका मतलब है कि आपके पास जो कुछ भी करने की कोशिश कर रहे हैं उसके लिए पर्याप्त स्मृति नहीं है।

Looking through the code I think it searches for the smallest resouloution/size and then takes the camera using those settings am I right in thinking that

हां।

if so how can I implement that into my code?

कॉपी और पेस्ट आमतौर पर काम करता है। :-)

कैमरे को बताने के लिए कि किस आकार की तस्वीर लेनी है, setPictureSize()Camera.Parameters पर उपयोग करें। हालांकि, आपको इसका आकार चुनने का आकार चुनना है, और सभी डिवाइस मनमाने ढंग से आकार का समर्थन नहीं करेंगे। कॉलिंग getSupportedPictureSizes() आपको बताएगा कि कौन से आकार समर्थित हैं। यह निर्धारित करने के लिए कि आप किस आकार का उपयोग करना चाहते हैं। the example I linked में आपके अन्य प्रश्न से, मैं उन आकारों पर पुन: प्रयास करता हूं और क्षेत्र के मामले में सबसे छोटा ढूंढता हूं।

कहा जा रहा है कि अगर छवि आकार के साथ केवल समस्या गतिविधि से गतिविधि तक गुजर रही है, तो मैं पहले स्थिर डेटा सदस्य मार्ग पर जाऊंगा। जब आपको अब छवि की आवश्यकता नहीं है तो उस स्थिर डेटा सदस्य को null पर सुनिश्चित करें।

Something like this maybe?

फिर, यह आपके उद्देश्य पर निर्भर करता है। आप समाधान की तलाश में घूमते प्रतीत होते हैं, जब आपने केवल एक समस्या व्यक्त की है (और यहां तक ​​कि, आपने हमें नहीं बताया है जहां आपको स्मृति त्रुटि से बाहर हो रहा है)।

यदि आपका लक्ष्य पूर्ण-रिज़ॉल्यूशन चित्र लेना है, तो उसे फ़ाइल में सहेजें, और फिर स्मृति में थंबनेल रखें, createScaledBitmap() एक अच्छा समाधान है।

यदि आपका लक्ष्य पहले स्थान पर थंबनेल-आश चित्र लेना है (यानी, आपको पूर्ण-रिज़ॉल्यूशन छवि की आवश्यकता नहीं है या नहीं), setPictureSize() का उपयोग करें।

यदि आपका लक्ष्य पूरे पूर्ण-रिज़ॉल्यूशन चित्र का उपयोग करना है, तो Bitmap की किसी भी अनावश्यक प्रतियों को समाप्त करने के लिए सावधानीपूर्वक एक स्थिर डेटा सदस्य का उपयोग करें और देखें कि यह पर्याप्त है या नहीं। यह हो सकता है कि आप छवि के साथ क्या करने की कोशिश कर रहे हैं।

+0

कुछ ऐसा जवाब है जो मुझे मिलता है। मेरा उद्देश्य मूल रूप से कैमरा पिक्चर लिया गया है और अगली गतिविधि में ले जाने के बाद इसे 'ऑनक्लिक' है जो प्रत्येक 'ऑनक्लिक' पर कैमरे की तस्वीर पर एक अलग छवि को ओवरले करता है। वह तब होता है जब 'ऑन-लिक' – Matt

+0

पर 'स्मृति त्रुटि' बल बंद हो जाता है क्या आपके लिंक से आपका कोड स्वचालित रूप से कैमरे को फोन के आधार पर निम्नतम आकार पर लेने के लिए सेट करता है या उपयोगकर्ता को अभी भी चुनना है? – Matt

+0

@Matt: उपयोगकर्ता को मेरे नमूने में कोई विकल्प नहीं मिलता है। यदि आप चाहते हैं कि उपयोगकर्ता आकार चुनने के लिए, तो आप 'स्पिनर' या 'अलर्टडिअलॉग' या कुछ ऐसे लोगों को पॉप्युलेट करने के लिए 'getSupportedPictureSizes()' का उपयोग करेंगे। – CommonsWare

2

कैमरा से इस कैप्चरिंग छवि को आज़माएं।

Intent cameraActivity=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      cameraActivity.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(left)); 
      startActivityForResult(cameraActivity,CAMERA_PIC_REQUEST_LEFTIMAGE); 

यह आप इसे नीचे स्केलिंग यू अब यू इस पर क्लिक करने पर ही जोड़ सकते हैं इस

BitmapFactory.Options options=new BitmapFactory.Options(); 
         options.inSampleSize = 6; 
         FileInputStream fileInputStream;  
         try { 
           fileInputStream=new FileInputStream(left); 
           leftPhoto=BitmapFactory.decodeStream(fileInputStream,null,options); 
           leftImage.setImageBitmap(leftPhoto); 
           fileInputStream.close(); 
          } catch (FileNotFoundException e) { 
           Toast.makeText(getCurrentContext(), e.getMessage(),Toast.LENGTH_LONG).show(); 
           e.printStackTrace(); 
          } catch (IOException e) { 
           e.printStackTrace(); 
           Toast.makeText(getCurrentContext(), e.getMessage(),Toast.LENGTH_LONG).show(); 
          } 

की तरह कुछ का उपयोग कर सकते के लिए बड़े आकार छवि वापस, अब होगा।

संबंधित मुद्दे