2012-01-06 44 views
6

UPDATE也許改變位圖大小在新的活動可能會解決問題的Android減小尺寸相機圖片的

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

或者,也許這就是下面

最好的辦法到目前爲止,我有我的應用程序,它是拍攝照片,然後使用Intent來的過載圖片並顯示在一個新的Activity 。一旦我完成了這一步,我有一些代碼在onClick的頂部顯示圖像。問題是當圖像被拍攝時,我認爲我的應用程序正在強制關閉。

在我的logcat我得到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

這就是你想要做的---拍照,傳遞圖像到onclick上的新活動?如果我是正確的,你需要一箇中等大小的圖像點擊? – 2012-01-06 13:00:16

+0

@Mohit Sharma:我不太瞭解你,但是,類似這樣的事情 – Matt 2012-01-06 13:10:23

回答

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?

通常複製和粘貼工作。 :-)

要告訴相機要拍攝什麼尺寸的照片,請使用Camera.Parameters上的setPictureSize()。但是,您必須選擇支持的大小,並非所有設備都支持任意大小。調用getSupportedPictureSizes()會告訴你哪些尺寸被支持。由您決定使用哪些尺寸。在the example I linked來自你的另一個問題,我遍歷這些大小,並找到面積方面最小的一個。

這就是說,如果只有問題與圖像大小是從活動傳遞給活動,我會先去靜態數據成員的路線。當您不再需要圖像時,請確保將null輸出爲靜態數據成員。

Something like this maybe?

同樣,這取決於你的目標是什麼。當你只說明瞭一個問題時(你甚至沒有告訴我們你得到了內存不足的錯誤),你似乎一直在尋找解決方案。

如果您的目標是拍攝全分辨率圖片,請將其保存在文件中,然後在內存中保留縮略圖,createScaledBitmap()是一個很好的解決方案。

如果您的目標是首先拍攝縮略圖(即,您不需要或不需要全分辨率圖像),請使用setPictureSize()

如果您的目標是在整個過程中使用全分辨率圖片,請仔細使用靜態數據成員來消除Bitmap的任何不必要的副本,然後查看是否足夠。它可能不是,取決於你想要對圖像做什麼。

+0

令人難以置信的答案我明白你的意思。我的目標基本上是一旦相機照片被拍攝並帶到下一個具有「onClick」功能的「onClick」,該照相機會在每個「onClick」上的相機圖像上疊加一個不同的圖像。這是當我嘗試'onCLick'時,'內存錯誤'強制關閉。 – Matt 2012-01-06 13:35:49

+0

您的鏈接中的代碼是否自動將相機設置爲取決於手機的最小尺寸還是用戶必須選擇靜止? – Matt 2012-01-06 13:37:59

+0

@Matt:用戶在我的示例中沒有得到選擇。如果你想讓用戶選擇大小,你可以使用'getSupportedPictureSizes()'來填充'Spinner'或'AlertDialog'等。 – CommonsWare 2012-01-06 13:54:07

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

這將返回大尺寸的圖像,現在比例縮小u可以使用這樣的事情

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

現在美國可以在此上單擊添加。