A classe Camera é usado para definir as configurações de captura de imagem, iniciar, parar a visualização, tirar fotos, e recuperar quadros para codificação de vídeo. Esta classe é um cliente para o serviço de câmera, que gerencia o hardware da câmera real.
Para acessar a câmera do dispositivo, você deve declarar suas permissões no manifest:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
Neste post vamos realizar uma implementação simples, sem orientações e alterações nas configurações da câmera.
Vamos utilizar o componente SurfaceView para exibir a câmera e um botão para tirar a foto. Nossa tela deve ficar da seguinte maneira:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="15sp" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/foto_texto" /> <SurfaceView android:id="@+foto/area_view" android:layout_width="300sp" android:layout_height="0dp" android:layout_gravity="center_horizontal" android:layout_weight="1" /> <Button android:id="@+foto/bt_fotografar" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/foto_bt_fotografar" /> </LinearLayout>
Para implementar o SurfaceView criei uma classe que vai gerenciar a Câmera, chamei de “CameraController”:
/** * * @author Guilherme Biff Zarelli */ public class CameraController implements SurfaceHolder.Callback { private android.hardware.Camera camera; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private boolean previewing = false; public CameraController(Activity atividade, int surfaceView) { this.surfaceView = (SurfaceView) atividade.findViewById(surfaceView); surfaceHolder = this.surfaceView.getHolder(); surfaceHolder.addCallback(this); } /** * Isto é chamado imediatamente após o SurfaceHolder ser criado. * * @param holder */ @Override public void surfaceCreated(SurfaceHolder holder) { camera = android.hardware.Camera.open(); } /** * Isto é chamado imediatamente após as alterações estruturais (o formato ou * tamanho) foram feitos ao SurfaceHolder. */ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (previewing) { pararVisualizacao(); } if (camera != null) { try { camera.setPreviewDisplay(surfaceHolder); iniciarVisualizacao(); } catch (IOException e) { e.printStackTrace(); } } } /** * Isto é chamado imediatamente antes do SurfaceHolder ser destruído. * * @param holder */ @Override public void surfaceDestroyed(SurfaceHolder holder) { pararVisualizacao(); camera.release(); camera = null; } public void tirarFoto(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg) { camera.takePicture(shutter, raw, jpeg); } public void iniciarVisualizacao() { previewing = true; camera.startPreview(); } public void pararVisualizacao() { camera.stopPreview(); previewing = false; } public Camera getCameraControler() { return camera; } }
Nosso controlador foi criado, porem ainda precisamos tratar algumas coisas, como a ação de tirar foto, como notamos acima o método tirarFoto() recebe três parâmetros:
Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg
O primeiro é referente a ação de tirar foto o segundo e o terceiro é o retorno da imagem, podemos recebe-la em modo RAW (segundo parametro) ou em JPEG (terceiro parâmetro), normalmente o modo RAW não é utilizado, por isso podemos passar o valor como null.
Vamos ver como seria a implementação desta classe:
public class MainCamera extends Activity implements View.OnClickListener, ShutterCallback, Camera.PictureCallback { private CameraController cameraController; private boolean emCamera; private Button botaoCamera; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); emCamera = true; cameraController = new CameraController(this, R.foto.area_view); botaoCamera = (Button) findViewById(R.foto.bt_fotografar); botaoCamera.setOnClickListener(this); } public void onClick(View view) { switch (view.getId()) { case R.foto.bt_fotografar: if (emCamera) { cameraController.tirarFoto(this, null, this); } else { emCamera = true; botaoCamera.setText(R.string.foto_bt_fotografar); cameraController.iniciarVisualizacao(); } break; } } /** * Ação do click tirar foto */ public void onShutter() { botaoCamera.setText(R.string.foto_bt_camera); emCamera = false; } /** * Retorno da ação de tirar foto * * @param bytes * @param camera */ public void onPictureTaken(byte[] bytes, Camera camera) { Bitmap foto = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); cameraController.pararVisualizacao(); } }
Link do projeto de exemplo: (DropBox)
Fontes:
http://developer.android.com/reference/android/hardware/Camera.html
http://developer.android.com/reference/android/view/SurfaceView.html
excelente tutorial!
Ola amigo,
sabe como eu faço para aumentar a qualidade de uma foto usando o surface view?
Abraços.