2013-04-30 14 views
13

Tôi muốn hiển thị một hình ảnh chụp từ máy ảnh trong một ImageView sử dụngandroid: Chụp hình camera mà không có "tiết kiệm"/"xóa" xác nhận

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 

này hoạt động tốt cho đến nay nhưng sau khi người dùng mất ảnh bằng cách sử dụng ứng dụng máy ảnh đã chọn, hộp thoại (có thể từ ứng dụng) xuất hiện hỏi có lưu hoặc xóa ảnh đã chụp (ít nhất trên Android 2.3 và 4.2 bằng ứng dụng máy ảnh mặc định).

Tôi muốn bỏ thêm thoại này và trực tiếp hiển thị hình ảnh trong ImageView (khi onActivityResult được gọi), bởi vì nó có nghĩa là một bước tương tác thêm cho người sử dụng, đó là không cần thiết bởi vì anh ta sẽ có khả năng để lưu hoặc xóa ảnh trong ứng dụng của tôi.

Điều này có thể thực hiện bằng ACTION_IMAGE_CAPTURE Intent đơn giản hay tôi cần một thứ phức tạp hơn như Camera Preview và SurfaceView cho mục đích này?

Trả lời

15

Bạn ca sử dụng SurfaceView để chụp ảnh

package com.camera; 

import java.io.IOException; 

import android.app.Activity; 
import android.content.Intent; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 

public class Camera_capture extends Activity implements SurfaceHolder.Callback { 

private Camera mCamera; 
private SurfaceView surfaceView; 
private SurfaceHolder surfaceHolder; 
private Button capture_image; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.camera_layout); 
    capture_image = (Button) findViewById(R.id.capture_image); 
    capture_image.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      capture(); 
     } 
    }); 
    surfaceView = (SurfaceView) findViewById(R.id.surfaceview); 
    surfaceHolder = surfaceView.getHolder(); 
    surfaceHolder.addCallback(Camera_capture.this); 
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    try { 
     mCamera = Camera.open(); 
     mCamera.setPreviewDisplay(surfaceHolder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void capture() { 
    mCamera.takePicture(null, null, null, new Camera.PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 
      Toast.makeText(getApplicationContext(), "Picture Taken", 
        Toast.LENGTH_SHORT).show(); 
      Intent intent = new Intent(); 
      intent.putExtra("image_arr", data); 
      setResult(RESULT_OK, intent); 
      camera.stopPreview(); 
      if (camera != null) { 
       camera.release(); 
       mCamera = null; 
      } 
      finish(); 
     } 
    }); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    Log.e("Surface Changed", "format == " + format + ", width === " 
      + width + ", height === " + height); 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Log.e("Surface Created", ""); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.e("Surface Destroyed", ""); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    if (mCamera != null) { 
     mCamera.stopPreview(); 
     mCamera.release(); 
    } 
} 
} 

Và file layout sẽ

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 

<SurfaceView 
    android:id="@+id/surfaceview" 
    android:layout_width="fill_parent" 
    android:layout_weight="100" 
    android:layout_height="wrap_content" /> 

<Button 
    android:id="@+id/capture_image" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    android:text="Capture" /> 

</LinearLayout> 

Bắt đầu hoạt động này Camera_capture với startActivityForResultonActivityResult bạn có thể nhận hình ảnh dưới dạng byte mảng dưới dạng

byte[] image = data.getExtras().getByteArray("image_arr"); 

trong đó data là dữ liệu nhận được.

Giải mã các byte mảng để Bitmap sử dụng

Bitmap bmp = BitmapFactory.decodeByteArray(image, 0, 
        image.length); 

tại thiết lập này Bitmap


Sửa

Như có một số vấn đề trong khi trở về byte[], các byte[] nên tiết kiệm trong một tập tin và p a của tập tin sẽ được gửi đến Activity trước đó để tập tin có thể được đọc.

Trong onPictureTaken(), chỉ cần thêm

String PATH = "Any path to store a file"; 
try { 
    FileOutputStream fos=new FileOutputStream(PATH); 

    fos.write(data); 
    fos.close(); 
    } 
    catch (java.io.IOException e) { 

    } 

và ở vị trí của:

intent.putExtra("image_arr", data); 

ghi

intent.putExtra("image_path", PATH); 

và nhận con đường này trong trước Activity 's onActivityResult như:

String imagePath = data.getExtras().getString("image_path"); 
+1

Cảm ơn! Điều này đã cho tôi một ý tưởng tốt như thế nào nó sẽ làm việc. Tôi nhận thấy rằng bằng cách sử dụng đoạn mã trên, hình ảnh được xoay 90 độ và sau khi gọi xong() độ nhạy không đóng, vì vậy nó không bao giờ quay trở lại hoạt động chính - ứng dụng bị treo ... – fritz

+0

welcome .. :) Vui lòng trợ giúp .. –

+0

sẽ kiểm tra sự cố của bạn. –

-2

Sử dụng MediaStore.EXTRA_OUTPUT param cho bạn ứng dụng máy ảnh chạy ý định

intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 
+0

Bạn có chắc chắn điều này đáp ứng các Ops mong muốn bỏ qua các lưu/xóa xác nhận. Nó không dành cho tôi. – paulkayuk

+0

Điều này không hữu ích, hộp thoại xuất hiện mặc dù tôi đang thêm intent.putExtra (android.provider.MediaStore.EXTRA_OUTPUT, \t \t Uri.fromFile (tệp mới (Environment.getExternalStorageDirectory() + "/ image11.jpg"))); – fritz

+0

Đây là liên kết đến tài liệu chính thức http://developer.android.com/guide/topics/media/camera.html#intent-image – httpdispatch

2

Nếu hình ảnh của bạn được luân chuyển, bạn có thể sử dụng này:

mCamera.setDisplayOrientation(90); 

sau

mCamera.startPreview(); 
1

Bạn có thể sử dụng giải pháp của AnujMathur_07, nhưng nếu bạn không muốn làm việc với những con đường và các tập tin , trong phương thức onPictureTaken, bạn có thể trả về bitmap:

@Override 
      public void onPictureTaken(byte[] data, Camera camera) { 
       Toast.makeText(getApplicationContext(), "Picture Taken", 
         Toast.LENGTH_SHORT).show(); 
       Intent intent = new Intent(); 

      Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, 
        data.length); 

      intent.putExtra("image", bmp); 
      setResult(RESULT_OK, intent); 
      camera.stopPreview(); 
      if (camera != null) { 
       camera.release(); 
       mCamera = null; 
      } 
      finish(); 
     } 

Và tôi n phương pháp onActivityResult bạn có thể nhận bitmap:

Bundle extras = data.getExtras(); 
Bitmap imageBitmap = (Bitmap) extras.get("image"); 
6

Sử dụng "android.intent.extra.quickCapture"

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
intent.putExtra("android.intent.extra.quickCapture",true); 
if (intent.resolveActivity(getPackageManager()) != null) { 
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); 
} 
+0

Cảm ơn, điều này làm việc cho tôi. –

+0

Không thay đổi bất cứ điều gì, mặc dù điều đó sẽ tốt đẹp – Twometer