2012-01-06 22 views
6

UPDATE forse modificando la dimensione bitmap nella nuova attività potrebbe risolvere il problemaAndroid ridurre la dimensione del Immagine fotocamera

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); 

    } 

Qualcosa di simile forse?

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

O forse questo è il modo migliore di sotto

Finora ho la mia applicazione che sta prendendo una foto e poi utilizzando un Intent per portare l'immagine più e mostra in una nuova Activity . Una volta che ho fatto questo ho un po 'di codice che mostra le immagini in alto con il onClick. Il problema è quando l'immagine è scattata è presa alla dimensione massima, credo che la mia app sia in chiusura forzata.

Nel mio logcat sto ricevendo java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) che penso significa che l'immagine è troppo grande.

Ho provato mettendo un'immagine più piccola nel codice anziché l'immagine della telecamera che è stata scattata e ciò funziona che mi riporta anche al problema che è la dimensione dell'immagine della telecamera.

Quindi sto cercando di implementare This From CommonsWare ma senza fortuna finora. Guardando attraverso il codice penso che cerchi la risoluzione/dimensione più piccola e poi riprenda la fotocamera usando quelle impostazioni. Ho ragione nel pensarlo e, in tal caso, come posso implementarlo nel mio codice?

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

è questo che stai cercando di fare --- Scatta foto, passa l'immagine a una nuova attività con onclick su di esso? Se sono corretto, hai bisogno di un'immagine di dimensioni medie per fare clic? –

+0

@Mohit Sharma: Non ho abbastanza capito ma si, qualcosa del genere – Matt

risposta

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.

Nella maggior parte dei casi, il passaggio di dati tra le attività che utilizzano Intent extra è una bella soluzione. Le grandi bitmap, tuttavia, causano problemi in questo modo a causa del consumo di memoria. Questo è un caso in cui vorrei che con attenzione utilizzi un membro di dati statici.

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.

Significa che non si dispone di memoria sufficiente per qualsiasi cosa si stia tentando di fare.

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

Sì.

if so how can I implement that into my code?

Copia e incolla di solito funziona. :-)

Per comunicare alla foto la dimensione dell'immagine da prendere, utilizzare setPictureSize() su Camera.Parameters. Tuttavia, devi scegliere una dimensione che supporta e non tutti i dispositivi supporteranno dimensioni arbitrarie. Chiamando il numero getSupportedPictureSizes() ti diremo quali sono le dimensioni supportate. Spetta a te determinare quale di queste dimensioni utilizzare. In the example I linked da un'altra domanda, eseguo l'iterazione su quelle dimensioni e trovo la più piccola in termini di area.

Detto questo, se il problema solo con la dimensione dell'immagine è passarlo da attività a attività, vorrei andare prima il percorso membro dei dati statici. Assicurati di specificare null come membro dei dati statici quando non hai più bisogno dell'immagine.

Something like this maybe?

Ancora una volta, ciò dipende dal tuo obiettivo. Sembra che tu stia agitando la ricerca di soluzioni, quando hai solo articolato un problema (e, anche lì, non ci hai detto dove hai riscontrato l'errore di memoria insufficiente).

Se il tuo obiettivo è scattare una foto a piena risoluzione, salvarla in un file e quindi tenere in memoria una miniatura, createScaledBitmap() è una soluzione eccellente.

Se il tuo obiettivo è quello di scattare una foto in miniatura in primo luogo (ad esempio, non è necessario o vuoi un'immagine a piena risoluzione), utilizzare setPictureSize().

Se l'obiettivo è utilizzare un'immagine a piena risoluzione, utilizzare con attenzione un membro di dati statici per eliminare eventuali copie non necessarie di Bitmap e verificare se è sufficiente. Potrebbe non essere, a seconda di cosa stai cercando di fare con l'immagine.

+0

Una risposta stupenda, capisco cosa intendi. Il mio obiettivo è fondamentalmente una volta che l'immagine della fotocamera è stata scattata e portata alla successiva attività che ha "onclick" che si sovrappone a un'immagine diversa sopra l'immagine della telecamera su ciascun 'onClick'. Questo è quando la forza di 'errore di memoria' si chiude quando provo a' onCLick' – Matt

+0

Il tuo codice dal tuo collegamento imposta automaticamente la fotocamera da prendere alla dimensione più bassa a seconda del telefono o l'utente deve scegliere ancora? – Matt

+0

@Matt: l'utente non ha scelta nel mio esempio. Se si desidera che l'utente scelga la dimensione, si utilizzerà 'getSupportedPictureSizes()' per popolare uno 'Spinner' o' AlertDialog' o alcuni di questi. – CommonsWare

2

Prova questa immagine catturata dalla fotocamera.

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

Questo lo restituisca un'immagine di grandi dimensioni, ora per il ridimensionamento verso il basso u possibile utilizzare qualcosa di simile

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(); 
          } 

Ora u può aggiungere al clic su questo.

Problemi correlati