2012-01-06 43 views
6

CẬP NHẬT thể thay đổi kích thước Bitmap trong Hoạt động mới có thể khắc phục vấn đềAndroid Giảm kích thước của máy ảnh Ảnh

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

    } 

Something như thế này có lẽ?

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

Hoặc Có lẽ đây là cách tốt nhất dưới đây

Cho đến nay tôi có ứng dụng của tôi được chụp ảnh và sau đó sử dụng một Intent để thực hiện bức tranh trên và hiển thị trong một mới Activity . Một khi tôi đã làm điều này tôi có một số mã hiển thị hình ảnh trên đầu trang với onClick. Vấn đề là khi hình ảnh được chụp, nó đang được chụp ở kích thước tối đa, tôi nghĩ ứng dụng của tôi sẽ đóng lại.

Trong nhật ký của tôi, tôi nhận được java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=7431KB, Allocated=2956KB, Bitmap Size=19764KB) mà tôi nghĩ là hình ảnh quá lớn.

Tôi đã thử nghiệm bằng cách đặt một hình ảnh nhỏ hơn trong mã thay vì hình ảnh camera đã chụp và công trình đó cũng dẫn tôi trở lại vấn đề là kích thước của hình ảnh camera.

Vì vậy, tôi đang cố gắng triển khai This From CommonsWare nhưng không có may mắn cho đến thời điểm này. Nhìn qua mã Tôi nghĩ rằng nó tìm kiếm resouloution nhỏ nhất/kích thước và sau đó có máy ảnh bằng cách sử dụng những cài đặt tôi phải suy nghĩ rằng và nếu như vậy làm thế nào tôi có thể thực hiện điều đó vào mã của tôi?

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

là điều mà bạn đang cố gắng làm --- Chụp ảnh, chuyển hình ảnh sang hoạt động mới bằng onclick trên đó? Nếu tôi đúng, bạn cần một hình ảnh kích thước trung bình cho Nhấp chuột? –

+0

@Mohit Sharma: Tôi không hoàn toàn hiểu bạn nhưng có, một cái gì đó giống như vậy – Matt

Trả lời

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.

Trong hầu hết các trường hợp, thông qua dữ liệu giữa các hoạt động sử dụng Intent extras là một giải pháp tốt. Mặc dù vậy, các bitmap lớn gây ra vấn đề theo cách tiêu thụ bộ nhớ. Đây là một trường hợp tôi sẽ cẩn thận sử dụng thành viên dữ liệu tĩnh.

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.

Điều đó có nghĩa là bạn không có đủ bộ nhớ cho bất kỳ điều gì bạn đang cố gắng thực hiện.

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

Có.

if so how can I implement that into my code?

Sao chép và dán thường hoạt động. :-)

Để cho máy ảnh biết kích thước ảnh cần chụp, hãy sử dụng setPictureSize() trên Camera.Parameters. Tuy nhiên, bạn phải chọn kích thước nó hỗ trợ và không phải tất cả các thiết bị đều hỗ trợ các kích thước tùy ý. Gọi getSupportedPictureSizes() sẽ cho bạn biết kích thước nào được hỗ trợ. Tùy thuộc vào bạn để xác định kích thước nào cần sử dụng. Trong the example I linked từ câu hỏi khác của bạn, tôi lặp lại các kích thước đó và tìm kích thước nhỏ nhất về diện tích.

Điều đó đang được nói, nếu vấn đề chỉ với kích thước hình ảnh chuyển nó từ hoạt động này sang hoạt động khác, trước tiên tôi sẽ đi tuyến dữ liệu thành viên tĩnh. Chỉ cần chắc chắn null ra thành viên dữ liệu tĩnh đó khi bạn không còn cần hình ảnh nữa.

Something like this maybe?

Một lần nữa, điều đó phụ thuộc vào mục tiêu của bạn. Dường như bạn đang tìm kiếm giải pháp, khi bạn chỉ có một vấn đề (và, ngay cả ở đó, bạn chưa nói với chúng tôi nơi bạn đang gặp phải lỗi bộ nhớ).

Nếu mục tiêu của bạn là chụp ảnh có độ phân giải đầy đủ, hãy lưu nó vào một tệp, và sau đó giữ trong bộ nhớ hình thu nhỏ, createScaledBitmap() là một giải pháp tốt.

Nếu mục tiêu của bạn là chụp ảnh thu nhỏ ở đầu tiên (nghĩa là bạn không cần hoặc muốn có hình ảnh có độ phân giải đầy đủ), hãy sử dụng setPictureSize().

Nếu mục tiêu của bạn là sử dụng ảnh có độ phân giải đầy đủ, hãy sử dụng cẩn thận thành viên dữ liệu tĩnh để loại bỏ bất kỳ bản sao không cần thiết nào của Bitmap và xem điều đó có đủ không. Nó có thể không, tùy thuộc vào những gì bạn đang cố gắng làm với hình ảnh.

+0

Câu trả lời awsome Tôi có được những gì bạn có ý nghĩa. Mục tiêu của tôi về cơ bản là khi Camera Picture đã được chụp và đưa đến Activity tiếp theo, nó có 'onClick' chồng lên một hình ảnh khác nhau trên hình ảnh của camera trên mỗi' onClick'. Đó là khi lực lượng 'memory error' đóng khi tôi cố gắng' onCLick' – Matt

+0

Mã của bạn từ liên kết của bạn có tự động đặt camera ở kích thước thấp nhất tùy thuộc vào điện thoại hay người dùng vẫn phải chọn không? – Matt

+0

@Matt: Người dùng không nhận được lựa chọn nào trong mẫu của tôi. Nếu bạn muốn người dùng chọn kích thước, bạn sẽ sử dụng 'getSupportedPictureSizes()' để điền một 'Spinner' hoặc' AlertDialog' hoặc một số thứ như vậy. – CommonsWare

2

Thử hình ảnh chụp này từ Máy ảnh.

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

này sẽ trả lại cho bạn hình ảnh kích thước lớn, bây giờ để mở rộng nó xuống u có thể sử dụng một cái gì đó như thế này

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

Bây giờ u có thể thêm vào nhấp chuột vào đây.

Các vấn đề liên quan