Android – Implementar a câmera usando SurfaceView (How can I implement the Android camera)

android-camera-surfaceview

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:

surfaceview

<?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

Help DEV – Analista desenvolvedor Java / Android
https://helpdev.com.br/zarelli

Android – Implementar a câmera usando SurfaceView (How can I implement the Android camera)

2 pensou em “Android – Implementar a câmera usando SurfaceView (How can I implement the Android camera)

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Rolar para o topo