WebCam com Unity

quicktuts06

Olá,

Vamos aprender como utilizar a câmera do dispositivo para captura de imagens e serialização em disco, para poder ser aplicada nos objetos do mundo do jogo!

Visão geral

  • Quando iniciada, a aplicação deverá procurar por uma imagem previamente serializada.
  • Caso encontrada, deverá ser carregada para uma região de visualização na tela.
  • Existirão dois botões: um para ativar o modo de fotografia e outro para capturar a foto.
  • Quando o modo de fotografia estiver ativo, a região de visualização exibirá constantemente o que está sendo capturado pela câmera.
  • Quando a fotografia for capturada, o modo de fotografia será pausado, e a imagem deve ser serializada em disco.

Este será o layout:

main_screen

Photographer

Classe que herda de MonoBehaviour e deve conter os seguintes fields:

  • Texture2D photoTexture2d: a textura capturada pela câmera;
  • RawImage rawimage: a região de visualização da câmera na UI;
  • WebCamTexture webcamTexture: classe da Unity API responsável pelo acesso ao hardware de captura de imagem (ela é quem faz o trabalho pesado para nós!);
  • Button btnOverride: botão para entrar em modo de captura de imagem (“Override”);
  • Button btnCapture: botão que captura a imagem (“Take Photo”).

No método Start:

Instancia-se webcamTexture. Procura no diretório ‘persistentDataPath’ por alguma imagem previamente serializada para carregá-la. O nome padrão adotado foi ‘my_photo.png’. A imagem é lida em um array de bytes, e caso não seja nulo, uma nova textura é criada e efetua-se o load da textura através do array de bytes. Essa textura é então atribuída ao material do elemento UI rawimage.

this.webcamTexture = new WebCamTexture();

var filename = Application.persistentDataPath + "/my_photo.png";
 var bytes = System.IO.File.ReadAllBytes(filename);
 if (bytes != null)
 {
    var texture = new Texture2D(800, 800);
    texture.LoadImage(bytes);
    this.rawimage.material.mainTexture = texture;
 }

O método OverrideImage apenas prepara a câmera e a UI para a captura da nova imagem. A textura de rawimage passa a ser o próprio webcamTexture, e então este é posto em modo de Play, para captura e exibição contínua de imagem na rawimage.

 this.rawimage.texture = this.webcamTexture;
 this.rawimage.material.mainTexture = this.webcamTexture;
 this.webcamTexture.Play();

No método TakePhoto, photoTexture2d é instanciado com dimensões equivalentes as da resolução da câmera do dispositivo. O método GetPixels de webcamTexture retorna os pixels obtidos pelo dispositivo no momento atual. Estes pixels são então atribuídos em photoTexture2d e então a ação é confirmada com Apply. Em seguida, webcamTextura é posto em modo de Pause, para interromper a captura de imagens e finalmente a imagem é serializada em arquivo.

this.photoTexture2d = new Texture2D(rawimage.texture.width, rawimage.texture.height);
this.photoTexture2d.SetPixels(this.webcamTexture.GetPixels());
this.photoTexture2d.Apply();

this.webcamTexture.Stop();

this.rawimage.texture = this.photoTexture2d;

System.IO.File.WriteAllBytes(Application.persistentDataPath + "/my_photo.png", this.photoTexture2d.EncodeToPNG());

Para interromper definitivamente a gravação de imagens e liberar o dispositivo, ele deve ser posto em modo Stop ao invés de Pause, do contrário ele ainda continuará ativo  (ao menos assim observei usando o Kinect V2 no PC).

O projeto pode ser encontrado aqui. 

Esse é o resultado final:Screenshot_2017-08-09-00-23-37.png

Uma vez capturada, é possível imaginar a vasta aplicação das imagens on the fly em materiais do jogo. Sua criatividade é o limite! Até a próxima!

Resposta