Usando a câmera no Android (Tradução da documentação oficial)

O framework do Android inclui suporte para várias câmeras e recursos de câmera disponíveis em dispositivos diversos, permitindo que você capture imagens e vídeos em suas aplicações. Esse artigo irá mostra de forma rápida e simples como capturar imagens e vídeos e mostrará uma abordagem avançada para criar experiências personalizadas utilizando a câmera aos usuários de seu aplicativo.

Considerações


Antes de permitir que sua aplicação use a câmera do dispositivo Android, você deve considerar algumas poucas questões sobre como seu aplicativo pretende usar esse recurso de hardware.

  • Obrigatoriedade da Câmera – O uso da câmera é importante o bastante para sua aplicação  de forma que você não queira permitir que ela seja instalada em dispositivos que não possuam câmera? Em caso positivo, você deve declarar a obrigatoriedade da câmera em seu manifesto.
  • Imagem rápida ou câmera personalizada – Como a sua aplicação usará a câmera? Você está interessado apenas em obter uma imagem ou vídeo de forma rápida ou sua aplicação fornecerá uma nova forma de usar a câmera? Para obter uma imagem ou vídeo de forma rápida, considere os procedimentos descritos na seção Usando aplicativos existentes de câmera. Para  desenvolver um recurso personalizado, cheque a seção Criando um aplicativo de câmera.
  • Armazenamento – As imagens e vídeos geradas pela sua aplicação devem estar disponíveis apenas para ela ou devem ser compartilhadas como outros aplicativos, como o Gallery ou outro tipo de aplicativo? Você quer que as imagens e vídeos  permaneçam disponíveis mesmo após a remoção do aplicativo? Veja a seção Salvando os arquivos para ver como implementar essas opções.

O básico


O framework do Android suporta a captura de imagens e vídeos através da API Camera ou do Intent da câmera. Abaixo seguem as classes relevantes:

Camera

Essa classe é a API primária para controlar a câmera do dispositivo. Essa classe é usada para tirar fotos e vídeos quando se está construindo uma aplicação de câmera.

SurfaceView

Essa classe é usada para apresentar a pré-visualização da câmera ao usuário.

MediaRecorder

Essa classe é usada para gravar vídeo a partir da câmera.

Intent

Um intent do tipo MediaStore.ACTION_IMAGE_CAPTURE ou MediaStore.ACTION_VIDEO_CAPTURE pode ser usado para capturar imagens e vídeos sem usar diretamente o objeto Camera.

Declarações no Manifesto


Antes de começar o desenvolvimento de sua aplicação com a API da Câmera, você precisa se certificar que o seu arquivo de manifesto possui as declarações necessárias para permitir o uso do hardware da câmera e outros recursos relacionados.

  • Permissões da  Câmera – Sua aplicação precisa requerer permissão para usar a câmera do dispositivo.
    <uses-permission android:name="android.permission.CAMERA" />

    Nota: Se você estiver usando a câmera via intent, não precisa dessa permissão.

  • Recursos da Câmera – Sua aplicação precisa declarar o uso do recursos da câmera, por exemplo:
    <uses-feature android:name="android.hardware.camera" />

    Para uma lista de recursos de câmera, veja o manifesto Features Reference.

    Adicionar recursos de câmera ao seu manifesto faz com que o Google Play evite que sua aplicação seja instalada em dispositivos que não suportem os recursos de câmera que você especificar. Para mais informações sobre o filtro baseado nos recursos utilizados do Google Play, veja Google Play and Feature-Based Filtering.

    Se a sua aplicação puder usar uma câmera ou um recurso da câmera para operar de forma adequada, mas não necessitar desse recurso você deve especificar isso no manifesto pela inclusão do atributo android:required e o ajuste dele para o valor false:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
  • Permissões para armazenamento – Se a sua aplicação salva as imagens e vídeos no armazenamento externo (Cartão SD), você deve especificar isso no manifesto.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • Permissões para gravação de áudio – Para gravar áudio junto com o vídeo capturado, sua aplicação precisa requerer permissão para captura de áudio.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • Permissão para Geolocalização – Se sua aplicação anexa a geolocalização da imagem junto com ela, precisa requisitar permissão para geolocalização:
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 

Usando Aplicativos de Câmera existentes


Uma forma rápida para permitir que a sua aplicação tirar fotos ou vídeos sem ter que criar muito código extra é usar um  Intent para invocar uma aplicação de câmera existente do Android. Um intent de câmera faz uma requisição para capturar uma imagem ou clip de vídeo através de uma aplicação de câmera existente e em seguida retorna para a aplicação. Essa seção mostra como capturar uma imagem ou vídeo usando essa técnica.

O procedimento para invocar um intent  de câmera segue os seguintes passos:

  1. Criar um Intent de câmera – Crie um Intent que represente uma imagem ou vídeo, usando um desses tipos de intent:
  2. Iniciar o Intent da câmera – Use o método startActivityForResult() para executar o intent da câmera. Após iniciar o intent, a interface da Câmera aparece na tela do dispositivo e o usuário pode tirar uma foto ou vídeo.
  3. Recepcionar o Resultado da Intent – Configure um método onActivityResult() em sua aplicação para receber a resposta e os dados do intent  da câmera. Quando o usuário termina de tirar a foto ou vídeo (ou cancela a operação), o sistema chama esse método imediatamente.

Intent de captura de imagem

Capturar imagens usando um intent de câmera é a forma mais rápida de permitir que sua aplicação tire fotos com o mínimo de codificação. Um intent  de captura de imagens pode incluir as seguintes informações extras:

  • MediaStore.EXTRA_OUTPUT – Esse ajuste necessita de um objeto Uri que especifica um caminho e um nome de arquivo onde você gostaria de salvar a imagem. Essa configuração é opcional mas fortemente recomendada. Se você não precisar especificar esse valor, a aplicação da câmera salva a imagem requisitada no local padrão com um nome padrão, especificado no campo Intent.getData() dointent.

O exemplo seguinte demonstra como criar um intent de captura de imagem e executá-lo. O método getOutputMediaFileUri() desse exemplo refere-se ao código fonte exemplo mostrado em Salvando arquivos de mídia.

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

    // start the image capture Intent
    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}

Quando um método startActivityForResult() é executado, os usuários verão a interface da câmera. Depois  que o usuário termina de tirar a foto (ou cancela a operação), a interface retorna para sua aplicação, e você precisa interceptar o método onActivityResult() para receber o resultado do intent e continuar a execução de sua aplicação. Para informações de como receber o intent completado, veja Receiving camera intent result.

Intent de captura de vídeo

Capturar vídeo usando um intent de câmera é a forma mais rápida de permitir que a sua aplicação tire vídeos com a mínima quantidade de código. Um intent de captura de vídeo pode incluir as seguintes informações extras:

  • MediaStore.EXTRA_OUTPUT – Essa configuração necessita de um Uri que especifica um caminho e um nome de arquivo onde você gostaria de salvar o vídeo. Essa configuração é opcional mas fortemente recomendada. Se você não especificar esse valor, a aplicação da Câmera salva o vídeo requisitado no local padrão com um nona padrão especificado no campo Intent.getData() do intent.
  • MediaStore.EXTRA_VIDEO_QUALITY – Esse valor pode ser ser 0 para a menor qualidade e arquivos menores ou 1 para para a melhor qualidade e arquivo maiores.
  • MediaStore.EXTRA_DURATION_LIMIT – Configure esse valor para o limite de tamanho, em segundos, do vídeo a ser capturado.
  • MediaStore.EXTRA_SIZE_LIMIT – Configure esse valor para o limite, em bytes, do arquivo a ser capturado.

O exemplo a seguir demonstra como criar um intent de captura de vídeo e executa-lo. O método getOutputMediaFileUri() nesse exemplo refere-se ao código fonte exemplo mostrada em Saving Media Files.

private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Uri fileUri;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //create new Intent
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name

    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

    // start the Video Capture Intent
    startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}

Quando o método startActivityForResult() é executado, os usuários verão a interface da aplicação de câmera. Depois que o usuário termina de gravar o vídeo (ou cancela a operação), a interface retorna para para sua aplicação, e você precisa interceptar o método onActivityResult() para receber o resultado do intent e continuar a execução de sua aplicação. Para obter informações de como fazer isso, veja a seção a seguir.

Recebendo o resultado do Intent da câmera

Uma vez que você criou e executou o intent para captura de imagem ou vídeo, sua aplicação precisa estar configurada para receber o resultado do intent. Essa seção descreve como interceptar o resultado de um intent  da câmerade forma que sua aplicação possa executar o processamento dessa imagem ou vídeo capturado.

De forma a receber o resultado de um intent, você precisa sobrecarregar o método onActivityResult() na Activity que iniciou o intent. O exemplo a seguir demonstra como sobrecarregar esse método para capturar o resultado dos exemplos de captura de imagem ou captura de vídeo das seções anteriores.

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Image captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Image saved to:\n" +
                     data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {
            // User cancelled the image capture
        } else {
            // Image capture failed, advise user
        }
    }

    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Video captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Video saved to:\n" +
                     data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {
            // User cancelled the video capture
        } else {
            // Video capture failed, advise user
        }
    }
}

Uma vez que a sua Activity receba o resultado com sucesso, a imagem ou vídeo capturado estará disponível no local especificado para acesso pela sua aplicação.

Criando um aplicativo de câmera


Alguns desenvolvedores podem precisar de uma interface de câmera que seja personalizada a aparência de suas aplicações ou forneça recursos especiais. Criar um Activity de câmera personalizada necessita de mais código do que o uso de um intent, mas pode fornecer uma experiência melhor ao usuário.

Os passos gerais para criar uma interface personalizada da câmera para sua aplicação são os seguintes:

  • Detectar e acessar a cãmera – Criar o código para verificar a existência de câmeras e solicitar acesso.
  • Criar uma classe de pré-visualização – Criar um classe de pré-visualização que estenda SurfaceView e implemente a interface SurfaceHolder. Essa classe visualiza imagens ao vivo da cãmera.
  • Criar o layout da pré-visualização – Uma vez que você tenha a classe de pré-visualização, crie um layout que incorpore a pré-visualização e os controles que você deseja.
  • Ajustar os ouvintes para a captura – Conecte os ouvintes para que os controles de sua interface possam iniciar a captura da imagem ou vídeo em resposta a alguma ação, como pressionar um botão.
  • Capturar e salvar aqquivos – Configure o código para capturar images e vídeos e salvar a saída.
  • Liberar a câmera – Depois de usar a câmera, sua aplicação precisa libera-la adequadamente para que outras aplicações possam usa-la.

O hardware da câmera é um recurso compartilhado que precisa ser gerenciado cuidadosamente de forma que a sua aplicação não colida com outras aplicações que também queiram usa-lo. As seções a seguir discutem como detectar o hardware da câmera,  como solicitar acesso a câmera, como capturar imagens e vídeos e como liberar a câmera quando sua aplicação não estiver mais usando ela.

Cuidado: Lembre de liberar o objeto Camera pela chamada à Camera.release() quando sua aplicação tiver finalizado o uso da câmera. Se sua aplicação não liberar a câmera adequadamente, todas as tentativas subsequentes de acesso a câmera, incluindo os da sua própria aplicação, irão falhar e podem fazer com que tanto sua aplicação quanto as outras fechem.

Detectando o hardware da câmera

Se a sua aplicação não solicita a câmera usando uma declaração no manifesto, você deve verificar para verificar se existe uma câmera em tempo de execução. Para executar essa checagem, use o método PackageManager.hasSystemFeature(), como mostrado no código abaixo:

/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

Dispositivos Android podem ter múltiplas câmeras, por exemplo, uma câmera na parte de trás para fotografia e uma câmera frontal para videochamadas. O Android 2.3 (API Level 9) e superiores permitem que você verifiquem o número de câmeras disponíveis em um dispositivo usando o método Camera.getNumberOfCameras().

Acessando a câmera

Se você determinar que o dispositivo onde sua aplicação está sendo executada possui uma câmera, você precisa solicitar acesso a ela pela obtenção de uma instância de Camera (a menos que esteja usando um intent de acesso a câmera).

Para acessar a câmera primária, use o método Camera.open() e certifique-se de capturar qualquer exceção, como mostrado no código abaixo:

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

Cuidado: Sempre cheque por exceções quando usar Camera.open(). Não checar por exceções quando a câmera estiver em uso ou não exista acarretará no encerramento de sua aplicação pelo sistema.

Em dispositivos rodando o Android 2.3 (API Level 9) ou superior, você pode acessar câmeras especificas usando Camera.open(int). O exemplo de código acima irá acessar a primeira câmera, na parte de trás, em um dispositivo com mais de uma câmera.

Verificando os recursos da câmera

Uma vez que você tenha obtido a uma câmera, você pode obter informações sobre os seus recursos usando o método Camera.getParameters() e verificando o retorno do objeto Camera.Parameters por recursos suportados. Quando estiver usando a API Level 9 ou superior, use Camera.getCameraInfo() para determinar se a câmera está na parte da frente ou de trás, e a orientação da imagem.

Criando uma classe para pre-visualização

Para que os usuários tirem efetivamente fotos e vídeos, eles precisam serem capazes de ver o que a câmera vê. Uma classe de pré-visualização é um SurfaceView que pode exibir os dados de imagem vindos da câmera, de forma que os usuários possam enquadrar e capturar um imagem ou vídeo.

O exemplo de código a seguir demonstra como criar uma classe de pré-visualização básica que pode ser incluída em um layout. Essa classe implementa SurfaceHolder.Callback de forma a poder capturar eventos para a criação e destruição do view, que é necessário para atribuir a entrada da pré-visualização da câmera.

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

Se você quiser ajustar um tamanho específico para a pré-visualização da câmera, configure isso no método surfaceChanged() como observado no comentário acima. Quando ajustar o tamanho da pré-visualização, você precisa usar os valores de getSupportedPreviewSizes(). Não ajuste o tamanho para valores arbitrários no método setPreviewSize().

Colocando a pré-visualização no layout

Uma classe de pré-visualização de câmera, como no exemplo mostrado acima, precisa ser colocada no layout de uma Activity com outros controles para usuário tirar fotos e vídeos. Essa seção mostra como você pode criar um layout básico para a pré-visualização.

O código abaixo fornece um view básico que pode ser usado para exibir a pré-visualização da câmera Nesse exemplo, p elemento FrameLayout é o contêiner para a classe da pré-visualização da câmera. Esse tipo de layout é usado de forma que imagens adicionais ou controles possam ser sobrepostos sobre a imagem da pré-visualização.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

Em muitos dispositivos, a orientação padrão da pré-visualização da câmera é a Paisagem. Esse exemplo de layout especifica um layout horizontal e o código abaixo corrige a orientação da aplicação para Paisagem. Para simplificar a renderização da pré-visualização da câmera, você deve alterar a orientação da Activity de sua aplicação pela adicção do seguinte código ao seu manifesto.

<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Nota: Uma pré-visualização não tem que estar no modo Paisagem. Desde o Android 2.2 (API Livel 8), você pode usar o método setDisplayOrientation() para ajustar a rotação da imagem de pré-visualização. De forma a alterar a orientação da pré-visualização quando o usuário re-orienta o telefone, dentro do método surfaceChanged() de sua classe de pré-visualização, primeiro interrompa a pré-visualização com Camera.stopPreview() mude a orientação e em seguida inicie a pré-visualização com Camera.startPreview().

Na Activity de sua pré-visualização de câmera, adicione sua classe de pré-visualização como o elemento  FrameLayout mostrado no exemplo acima. Sua Activity de câmera precisa também garantir que a câmera seja liberada quando a ela seja pausada ou encerrada. O exemplo seguinte mostra como modificar a Activity da câmera para anexar a classe de pré-visualização mostrada na seção anterior.

public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(id.camera_preview);
        preview.addView(mPreview);
    }
}

Nota: O método getCameraInstance() do exemplo acima refere-se ao método do exemplo da seção Acessando a câmera.

Capturando imagens

Uma vez que você tenha criado uma classe de pré-visualização e um layout para exibi-la, você está pronto para iniciar a captura de imagens em sua aplicação. No código de sua aplicação, você precisa configurar ouvintes para os controles da interface para responder às ações do usuário ao tirar uma foto.

De modo a recuperar uma imagem, use o método Camera.takePicture(). Esse método usa três parâmetros qu recebem dados da câmera. Para que os dados sejam recebidos em formato JPEG, você precisa implementar a interface Camera.PictureCallback para receber os dados da imagem e receber esses dados em um arquivo. O código a seguir mostra uma implementação básica da interface Camera.PictureCallback para salvar uma imagem recebida da câmera.

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

Dispare a captura de uma imagem pela chamada do método Camera.takePicture(). O código fonte a seguir mostra como chamar esse método a partir de um botão View.OnClickListener.

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get an image from the camera
            mCamera.takePicture(null, null, mPicture);
        }
    }
);

Nota: O membro mPicture do exemplo refere-se ao código mostrado acima.

Cuidado: Lembre de liberar o objeto Camera pela chamada a Camera.release() quando a sua aplicação tiver terminado de usar a cãmera.

Capturando vídeos

Captura de vídeos usando o framework do Android necessita de um gerenciamento cuidadoso do objeto Camera e coordenação com a classe MediaRecorder. Quando estiver gravando um vídeo com Camera, você precisa gerenciar as chamadas a Camera.lock() e Camera.unlock() para permitir o acesso a MediaRecorder ao hardware da câmera, em adição às chamada a Camera.open() e Camera.release().

Nota: A partir do Android 4.0 (API Level 14), as chamadas à Camera.lock() e Camera.unlock() são gerenciadas automaticamente.

Ao contrário da captura de fotos com a câmera do dispositivo, a captura de vídeos requer uma ordem de chamada de métodos muito particular. Você precisa seguir uma ordem de execução específica para preparar com sucesso e capturar um vídeo pela sua aplicação, como descrito a seguir.

  1. Abrir a câmera – Use o método Camera.open() para obter uma instância do objeto câmera.
  2. Conectar a Pré-visualização – Preparar uma imagem ao vivo da câmera pela conexão de um SurfaceView à câmera usando Camera.setPreviewDisplay().
  3. Iniciar a Pré-visualização – Chamar Camera.startPreview() para iniciar a exibição da pré-visualização da câmera.
  4. Iniciar a gravação do vídeo – Os seguintes passos precisam ser executados de forma que o vídeo seja gravado com sucesso:
    1. Desbloquear a câmera – Desbloqueie a câmera para uso pelo MediaRecorder através da chamada à Camera.unlock().
    2. Configurar o MediaRecorder – Chame os seguintes métodos de MediaRecorder nessa ordem. Para mais informações, veja a documentação deMediaRecorder.
      1. setCamera() – Configura a câmera a ser usada para a captura de vídeo, use a instância atual de Camera da sua aplicação.
      2. setAudioSource() – Configure a fonte do áudio, use MediaRecorder.AudioSource.CAMCORDER.
      3. setVideoSource() – Configure a fonte do vídeo, use MediaRecorder.VideoSource.CAMERA.
      4. Configure a codificação da saída de vídeo. Para o Android 2.2 (API Level 8) ou superior, use o método MediaRecorder.setProfile, e obtenha uma instância do perfil usando CamcorderProfile.get(). Para versões do Android anteriores a 2.2, você precisa configurar o formato de saída do vídeo e parâmetros de codificação:
        1. setOutputFormat() – Configura o formato da saída, especificando a configuração padrão ou MediaRecorder.OutputFormat.MPEG_4.
        2. setAudioEncoder() – Configura o tipo de codificação do áudio, especificando a configuração padrão ou MediaRecorder.AudioEncoder.AMR_NB.
        3. setVideoEncoder() – Configura o tipo de codificação do vídeo, especificando a configuração padrão ou MediaRecorder.VideoEncoder.MPEG_4_SP.
      5. setOutputFile() – Configura o arquivo de saída, use o método getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() do exemplo da seção Salvando arquivos de mídia.
      6. setPreviewDisplay() – Especifica o elemento do layout associado ao SurfaceView para sua aplicação. Use o nome que você especificou para o Connect Preview.
    3. Preparar o MediaRecorder – Prepara o MediaRecorder com as configurações fornecidas através da chamada a MediaRecorder.prepare().
    4. Iniciar o MediaRecorder – Inicia a gravação do vídeo através da chamada a MediaRecorder.start().
  5. Interromper a gravação do vídeo – Chame os seguintes métodos nessa ordem, para completar com sucesso uma gravação de vídeo:
    1. Interromper o MediaRecorder – Interrompa a gravação do vídeo pela chamada a MediaRecorder.stop().
    2. Reiniciar o MediaRecorder – Opcionalmente, remova as configurações pela chamada a MediaRecorder.reset().
    3. Liberar o MediaRecorder – Libere o MediaRecorder através da chamada a MediaRecorder.release().
    4. Bloquear a câmera – Trave a câmera de forma que sessões futuras do MediaRecorder possam usa-lo através da chamada a Camera.lock(). A partir do Android 4.0 (API level 14), essa chamada não é necessária a menos que MediaRecorder.prepare() falhe.
  6. Interromper a pré-visualização – Quando a sua Activity tiver terminado de usar a câmera, interrompa a pré-visualização usando Camera.stopPreview().
  7. Liberar a câmera – Libere a câmera de forma que outras aplicações possam usa-la através da chamada a Camera.release().

Nota: É possível usar o MediaRecorder sem criar primeiro uma pré-visualização da câmera e pular os primeiros passos desse processo. Porém, como os usuários preferem ver uma prévia antes de começar a gravação, esse processo não é discutido aqui.

Dica: Se sua aplicação for usada tipicamente para gravação, ajuste setRecordingHint(boolean) para true antes de iniciar a pré-visualização. Essa ajuste pode reduzir o tempo de início da gravação.

Configurando o MediaRecorder

Quando estiver usando a classe MediaRecorder para gravar vídeo, você precisa executar os passos da configuração em uma ordem específica e depois chamar o método MediaRecorder.prepare() para verificar e implementar a configuração. O exemplo de código a seguir demonstra como configurar e preparar de forma adequada a classe MediaRecorder para gravação de vídeo.

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

Os parâmetros de gravação de vídeo a seguir recebem valores padrão, porém, você pode desejar ajusta-los m sua aplicação:

Iniciando e interrompendo o MediaRecorder

Quando se inicia e interrompe a gravação de vídeo usando a classe MediaRecorder, você precisa seguir uma ordem especifica, como listada abaixo.

  1. Desbloquear a câmera com Camera.unlock()
  2. Configurar o MediaRecorder como mostrado no código acima.
  3. Iniciar a gravação usando MediaRecorder.start()
  4. Gravar o vídeo.
  5. Interromper a gravação pelo uso de MediaRecorder.stop()
  6. Libere o MediaRecorder com MediaRecorder.release()
  7. Bloqueie a câmera usando Camera.lock()

O código a seguir demonstra como usar um botão para iniciar e interromper a gravação de vídeo usando a câmera e a classe MediaRecorder.

Nota: Quando a gravação do vídeo é terminada, não libere a câmera ou a pré-visualização será interrompida.

private boolean isRecording = false;

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isRecording) {
                // stop recording and release camera
                mMediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped
                setCaptureButtonText("Capture");
                isRecording = false;
            } else {
                // initialize video camera
                if (prepareVideoRecorder()) {
                    // Camera is available and unlocked, MediaRecorder is prepared,
                    // now you can start recording
                    mMediaRecorder.start();

                    // inform the user that recording has started
                    setCaptureButtonText("Stop");
                    isRecording = true;
                } else {
                    // prepare didn't work, release the camera
                    releaseMediaRecorder();
                    // inform user
                }
            }
        }
    }
);

Nota: No exemplo acima, o método prepareVideoRecorder() refere-se ao código mostrado na seção Configurando o MediaRecorder. Esse método cuida do bloqueio da câmera, configuração e preparação a instância do MediaRecorder.

Liberando a câmera

Câmeras são recursos que são compartilhados por várias aplicações instaladas no dispositivo. Sua aplicação pode fazer uso da câmera após obter uma instância de Camera, e você precisa ser particularmente cuidadoso quando a sua aplicação termina de usa-la, e assim que a aplicação seja pausada  (Activity.onPause()). Se a sua aplicação não liberar de forma adequada a câmera, todas a tentativas de acesso subsequentes a câmera, incluindo aquelas vindas de sua própria aplicação, irão falhar e podem causar o enceramento da aplicação.

Para liberar uma instância do objeto Camera, use o método Camera.release(), como mostrado no exemplo a seguir.

public class CameraActivity extends Activity {
    private Camera mCamera;
    private SurfaceView mPreview;
    private MediaRecorder mMediaRecorder;

    ...

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
        releaseCamera();              // release the camera immediately on pause event
    }

    private void releaseMediaRecorder(){
        if (mMediaRecorder != null) {
            mMediaRecorder.reset();   // clear recorder configuration
            mMediaRecorder.release(); // release the recorder object
            mMediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
}

Salvando os arquivos


Arquivos de mídia criados pelos usuários como fotos e vídeos devem ser salvos em um diretório do armazenamento externo do dispositivo (Cartão SD) para preservar o espaço do sistema e permitir que os usuários possam acessar esses arquivos sem o dispositivo. Existem muitos diretórios em que os arquivos podem ser armazenados, porém existem apenas dois locais padrão que você deveria considerar:

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) – Esse método retorna o local padrão, compartilhado e recomendado para salvar fotos e vídeos. Esse diretório é público, de forma que outras aplicações podem facilmente descobrir, ler, alterar e apagar os arquivos salvados dentro dele. Se a sua aplicação for desinstalada pelo usuário, os arquivos de mídia salvos nesse local não serão removidos. Para evitar interferência com as imagens e vídeos existentes, você deve criar um sub-diretório para os arquivos de mídia de sua aplicação, como mostrado no código abaixo. Esse método está disponível no Android 2.2 (API Level 8).
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) – Esse método retorna um local padrão para salvar fotos e vídeos que estejam associados a sua aplicação. Se a sua aplicação for desinstalada, qualquer arquivo salvo nesse local será removido. A segurança não é reforçada para arquivos nesse diretório, de forma que outras aplicações podem ler, alterar e apagar os arquivos.

O exemplo de código a seguir demonstra como criar um File ou Uri para um arquivo de mídia que pode ser usado quando se invoca a câmera do dispositivo com um  Intent ou como parte da Criação de uma aplicação de câmera.

public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
      return Uri.fromFile(getOutputMediaFile(type));
}

/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}

Nota: Environment.getExternalStoragePublicDirectory() está disponível no Android 2.2 (API Level 8) ou superior. Se seu objetivo for dispositivos com versões mais antigas do Android, use Environment.getExternalStorageDirectory() ao invés disso.

Recursos de câmera


O Android suporta uma gama ampla de recursos de câmera que você pode controlar com a sua aplicação, como formato da imagem, modo de flash, ajustes de foco, e muito mais. Essa seção lista os recursos de câmera comuns, e discute brevemente como usar cada um. Muitos dos recursos de câmera podem ser acessados e configurados através do objeto Camera.Parameters. Porém, existem diversos recursos importantes que necessitam do que ajustes simples no Camera.Parameters. Esses recursos são cobertos nas seguintes seções:

  • Medição e foco de certas áreas
  • Detecção de rostos
  • Timelapse

Tabela 1. Recursos de câmera comuns ordenados pela Nível de API do Android onde eles foram introduzidos.

Recursos API Level Descrição
Face Detection 14 Identify human faces within a picture and use them for focus, metering and white balance
Metering Areas 14 Specify one or more areas within an image for calculating white balance
Focus Areas 14 Set one or more areas within an image to use for focus
White Balance Lock 14 Stop or start automatic white balance adjustments
Exposure Lock 14 Stop or start automatic exposure adjustments
Video Snapshot 14 Take a picture while shooting video (frame grab)
Time Lapse Video 11 Record frames with set delays to record a time lapse video
Multiple Cameras 9 Support for more than one camera on a device, including front-facing and back-facing cameras
Focus Distance 9 Reports distances between the camera and objects that appear to be in focus
Zoom 8 Set image magnification
Exposure Compensation 8 Increase or decrease the light exposure level
GPS Data 5 Include or omit geographic location data with the image
White Balance 5 Set the white balance mode, which affects color values in the captured image
Focus Mode 5 Set how the camera focuses on a subject such as automatic, fixed, macro or infinity
Scene Mode 5 Apply a preset mode for specific types of photography situations such as night, beach, snow or candlelight scenes
JPEG Quality 5 Set the compression level for a JPEG image, which increases or decreases image output file quality and size
Flash Mode 5 Turn flash on, off, or use automatic setting
Color Effects 5 Apply a color effect to the captured image such as black and white, sepia tone or negative.
Anti-Banding 5 Reduces the effect of banding in color gradients due to JPEG compression
Picture Format 1 Specify the file format for the picture
Picture Size 1 Specify the pixel dimensions of the saved picture

Verificando a disponibilidade do recurso

A primeira coisa a se entender quando estiver configurando o uso de recursos de câmera em dispositivos Android é que nem todos os recursos são suportados em todos os dispositivos. Além disso, os dispositivos que suportem um recurso em particular podem suportar esse recurso em níveis diferentes ou com opções diferentes. Por esse motivo, parte do processo de decisão do desenvolvedor de uma aplicação de câmera é decidir quais recursos de câmera serão suportados e em que nível. Após tomar essas decisões, você deve planejar incluir código em sua aplicação para verificar se o hardware do dispositivo suporta esses recursos e evitar ser executado caso o recurso não esteja disponível.

Você pode verificar a disponibilidade de recursos de câmera pela obtenção de uma instância do objeto de parâmetros da câmera, e checando os métodos relevantes. O código a seguir mostra como obter acesso a um objeto Camera.Parameters e verificar se a câmera suporta o recurso de auto-foco:

// get Camera parameters
Camera.Parameters params = mCamera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  // Autofocus mode is supported
}

Você pode usar a técnica mostrada acima para outros recursos de câmera. O objeto Camera.Parameters fornece um método getSupported...()is...Supported() ou getMax...() para determinar se (e em que nível) um recurso é suportado.

Se a sua aplicação precisar de um determinado recurso de câmera para funcionar corretamente, você pode requerer esses recursos através do manifesto. Quando você declara o uso de recursos específicos da câmera, como flash ou auto-foco, o Google Play restringe a instalação de sua aplicação em dispositivos que não suportem esses recursos. Para obter uma lista de recursos que podem ser declarados no seu manifesto, veja Features Reference.

Usando os recursos da câmera

Muitos recursos de câmera são ativados usando um objeto Camera.Parameters. Você obtém esses objeto criando uma instância do objeto Camera, chamando o método getParameters(), alterando o parâmetro retornado e então configurando de volta para o objeto da câmera, como demonstrado no código a seguir:

// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);

Essa técnica funciona para quase todos os recursos de câmera, e muitos parâmetros podem ser alterado a qualquer tempo após a obtenção de uma instância do objeto Camera. Alterações nos parâmetros são tipicamente visíveis aos usuários imediatamente pela pré-visualização da câmera. Do lado do software, alterações nos parâmetros podem levar vários quadros da imagem para surtirem efeito e o hardware da câmera processe as novas instruções e atualize os dados da imagem.

Outros recursos de câmera necessitam de mais código para serem implementados, incluindo:

  • Medição e foco de certas áreas
  • Detecção de rostos
  • Timelapse

Medição e focando de certas áreas

In some photographic scenarios, automatic focusing and light metering may not produce the desired results. Starting with Android 4.0 (API Level 14), your camera application can provide additional controls to allow your app or users to specify areas in an image to use for determining focus or light level settings and pass these values to the camera hardware for use in capturing images or video.

Areas for metering and focus work very similarly to other camera features, in that you control them through methods in the Camera.Parameters object. The following code demonstrates setting two light metering areas for an instance of Camera:

// Create an instance of Camera
mCamera = getCameraInstance();

// set Camera parameters
Camera.Parameters params = mCamera.getParameters();

if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // specify an area in center of image
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // specify an area in upper right of image
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
    params.setMeteringAreas(meteringAreas);
}

mCamera.setParameters(params);

The Camera.Area object contains two data parameters: A Rect object for specifying an area within the camera’s field of view and a weight value, which tells the camera what level of importance this area should be given in light metering or focus calculations.

The Rect field in a Camera.Area object describes a rectangular shape mapped on a 2000 x 2000 unit grid. The coordinates -1000, -1000 represent the top, left corner of the camera image, and coordinates 1000, 1000 represent the bottom, right corner of the camera image, as shown in the illustration below.

Figure 1. The red lines illustrate the coordinate system for specifying a Camera.Area within a camera preview. The blue box shows the location and shape of an camera area with the Rect values 333,333,667,667.
Figure 1. The red lines illustrate the coordinate system for specifying a Camera.Area within a camera preview. The blue box shows the location and shape of an camera area with the Rect values 333,333,667,667.

The bounds of this coordinate system always correspond to the outer edge of the image visible in the camera preview and do not shrink or expand with the zoom level. Similarly, rotation of the image preview usingCamera.setDisplayOrientation() does not remap the coordinate system.

Detecção de rostos

For pictures that include people, faces are usually the most important part of the picture, and should be used for determining both focus and white balance when capturing an image. The Android 4.0 (API Level 14) framework provides APIs for identifying faces and calculating picture settings using face recognition technology.

Nota: While the face detection feature is running, setWhiteBalance(String)setFocusAreas(List)and setMeteringAreas(List) have no effect.

Using the face detection feature in your camera application requires a few general steps:

  • Check that face detection is supported on the device
  • Create a face detection listener
  • Add the face detection listener to your camera object
  • Start face detection after preview (and after every preview restart)

The face detection feature is not supported on all devices. You can check that this feature is supported by calling getMaxNumDetectedFaces(). An example of this check is shown in the startFaceDetection()sample method below.

In order to be notified and respond to the detection of a face, your camera application must set a listener for face detection events. In order to do this, you must create a listener class that implements theCamera.FaceDetectionListener interface as shown in the example code below.

class MyFaceDetectionListener implements Camera.FaceDetectionListener {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {
        if (faces.length > 0){
            Log.d("FaceDetection", "face detected: "+ faces.length +
                    " Face 1 Location X: " + faces[0].rect.centerX() +
                    "Y: " + faces[0].rect.centerY() );
        }
    }
}

After creating this class, you then set it into your application’s Camera object, as shown in the example code below:

mCamera.setFaceDetectionListener(new MyFaceDetectionListener());

Your application must start the face detection function each time you start (or restart) the camera preview. Create a method for starting face detection so you can call it as needed, as shown in the example code below.

public void startFaceDetection(){
    // Try starting Face Detection
    Camera.Parameters params = mCamera.getParameters();

    // start face detection only *after* preview has started
    if (params.getMaxNumDetectedFaces() > 0){
        // camera supports face detection, so can start it:
        mCamera.startFaceDetection();
    }
}

You must start face detection each time you start (or restart) the camera preview. If you use the preview class shown in Creating a preview class, add your startFaceDetection() method to both thesurfaceCreated() and surfaceChanged() methods in your preview class, as shown in the sample code below.

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // start face detection feature

    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null){
        // preview surface does not exist
        Log.d(TAG, "mHolder.getSurface() == null");
        return;
    }

    try {
        mCamera.stopPreview();

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
    }

    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

        startFaceDetection(); // re-start face detection feature

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

Nota: Remember to call this method after calling startPreview(). Do not attempt to start face detection in the onCreate() method of your camera app’s main activity, as the preview is not available by this point in your application’s the execution.

Timelapse

Time lapse video allows users to create video clips that combine pictures taken a few seconds or minutes apart. This feature uses MediaRecorder to record the images for a time lapse sequence.

To record a time lapse video with MediaRecorder, you must configure the recorder object as if you are recording a normal video, setting the captured frames per second to a low number and using one of the time lapse quality settings, as shown in the code example below.

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
...
// Step 5.5: Set the video capture rate to a low number
mMediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds

These settings must be done as part of a larger configuration procedure for MediaRecorder. For a full configuration code example, see Configuring MediaRecorder. Once the configuration is complete, you start the video recording as if you were recording a normal video clip. For more information about configuring and running MediaRecorder, see Capturing videos.

 

  • Wellington Lopes

    Olá Kleber, estou tentando implementar em minha aplicação, a camera sem visualização da imagem, ou seja, ao pressionar um botão, será tirado a foto sem que o usuário perceba. Estou usando o cordova, e dá problemas ao usar o PictureCallback pois não encontra essa classe, tem alguma ideia para este fato?

  • David Silva

    E ai Kleber, Blz.. Parabens pelo material.
    implementei em minha aplicação um método para chamar a câmera retirar a foto e armazenar em uma pasta determinada. gostaria de saber se consigo colocar o texto de uma string nessa foto antes de salvar. semelhante a geolocalização que grava na foto.

    • Olá David. Se eu precisasse implementar a função descrita por você, eu usaria alguma implementação da bibliotecas libjpeg compatível com Android, para pegar a imagem capturada da câmera e salvar na memória com as informações desejadas salvas no cabeçalho do arquivo (modificado através da biblioteca). Eu já trabalhei com a libjpeg usando C++, mas nunca com Android/Java (mas acredito que tenha exista algo para essa plataforma sim).

  • Junim Moreira

    Boa tarde, kleber..Parabéns pelo material

    estou precisando captura uma imagem através da camera, mas nao quero bater a foto. quero usar a camera para identificar uma cor atraves do aplicativo.