Integração Biblioteca WebCAM no Framework Pessoal, bom dia! Consegui organizar uma biblioteca para capturar imagem webcam através do PHP. Esta biblioteca utiliza recursos flash e javascript. Eu preciso da ajuda de vocês para integrar numa página desenvolvida no Adianti Framework. Não sei como mesclar esta biblioteca à tela de cadastro....
PF
Integração Biblioteca WebCAM no Framework  
Pessoal, bom dia!

Consegui organizar uma biblioteca para capturar imagem webcam através do PHP. Esta biblioteca utiliza recursos flash e javascript. Eu preciso da ajuda de vocês para integrar numa página desenvolvida no Adianti Framework. Não sei como mesclar esta biblioteca à tela de cadastro.

Curso Dominando o Adianti Framework

O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado!


Dominando o Adianti Framework Quero me inscrever agora!

Comentários (15)


MG

Me interesso pelo assunto. Acompanhando.
LC

Eu consegui, mais usei o exemplo de um outro post seu:
https://www.adianti.com.br/forum/pt/view_4223?utilizar-webcamjs-para-tirar-fotos

Fiz umas coisas que não sei explicar direito (rsrs), vou tentar resumir, depois coloco aqui.
PF

Valeu! Aguardo o compartilhamento da idéia!
NR

adianti.com.br/framework-extensibility
LC

 
  1. <?php
 
  1. <?php
  2. /**
  3. * WebcamForm Registration
  4. * @author Imprime Informática
  5. */
  6. class WebcamForm extends TPage
  7. {
  8. protected $form; // form
  9. private $frameFoto;
  10. private $frameFotoWebCan;
  11. /**
  12. * Class constructor
  13. * Creates the page and the registration form
  14. */
  15. function __construct()
  16. {
  17. parent::__construct();
  18. TPage::include_js('app/lib/components/webcam/webcam.min.js');
  19. TPage::include_js('app/lib/components/webcam/webcam.nome_seu_arquivo.js');
  20. // creates the form
  21. $this->form = new BootstrapFormBuilder('form_Pessoa');
  22. $this->form->setFormTitle('Pessoa');
  23. $this->form->setFieldSizes('100%');
  24. // create the form fields
  25. $id = new TEntry('id');
  26. $datacadastro = new TDate('datacadastro');
  27. $datanascto = new TDate('datanascto');
  28. $fj = new TRadioGroup('fj');
  29. $nome = new TEntry('nome');
  30. $nomefantasia = new TEntry('nomefantasia');
  31. $situacao = new TRadioGroup('situacao');
  32. $situacao->addItems(array('0'=>'Ativo','1'=>'Inativo'));
  33. $situacao->setLayout('Horizontal');
  34. $situacao->setValue('0');
  35. $situacao->setUseButton();
  36. $nome_arq_foto = new TFile('nome_arq_foto');
  37. $nome_arq_foto->setAllowedExtensions( ['png', 'jpg'] );
  38. // complete upload action
  39. $nome_arq_foto->setCompleteAction( new TAction( array( $this, 'onCompleteFoto' ) ) );
  40. // Propriedades dos campos
  41. $id->setEditable(False);
  42. $datacadastro->setMask('dd/mm/yyyy');
  43. $datacadastro->setValue( date('d/m/Y') );
  44. $datacadastro->setTip('Data de Cadastro');
  45. $datanascto->setMask('dd/mm/yyyy');
  46. $fj->addItems(array('1'=>'Física','2'=>'Jurídica'));
  47. $fj->setLayout('Horizontal');
  48. $fj->setValue('1');
  49. $fj->setUseButton();
  50. $nome->addValidation('Nome/Razão Social', new TRequiredValidator);
  51. $nome_arq_foto->setSize('100%');
  52. // add one row for each form field
  53. $row = $this->form->addFields( [ new TLabel('ID'), $id ],
  54. [ new TLabel('Data Cadastro'), $datacadastro ],
  55. [ new TLabel('Situação'), $situacao],
  56. [ new TLabel('Data Nascto'), $datanascto ],
  57. [ new TLabel('Pessoa'), $fj ] );
  58. $row->layout = ['col-sm-2', 'col-sm-3', 'col-sm-2', 'col-sm-3', 'col-sm-2'];
  59. $label_nome = new TLabel('Nome/Razão Social');
  60. $row = $this->form->addFields( [ $label_nome, $nome ],
  61. [ new TLabel('Nome Fantasia'), $nomefantasia ] );
  62. $label_nome->setFontColor('#FF0000');
  63. $row->layout = ['col-sm-6', 'col-sm-6'];
  64. $divisor = new TFormSeparator('Foto <span class="fa fa-long-arrow-down" aria-hidden="true"></span>', '#333333;margin-bottom:0', '18', '#000;margin-bottom:0');
  65. $divisor->style = 'background-color: #b1d4e8; padding-top: 1px';
  66. $this->form->addContent( [ $divisor ] );
  67. // campo para fazer upload de uma imagem qualquer (caso não use a webcam)
  68. $row = $this->form->addFields( [ new TLabel('Foto <b>(PNG ou JPG)</b>'), $nome_arq_foto ] );
  69. // div onde fica a foto se existir ou a camera apos clicar no botão Acessar Webcam
  70. $this->frameFoto = new TElement( 'div' );
  71. $this->frameFoto->id = 'user_foto_frame';
  72. $this->frameFoto->style = '';
  73. // div onde fica a foto tirada apos clicar no botão Bater Foto
  74. $this->frameFotoWebCan = new TElement( 'div' );
  75. $this->frameFotoWebCan->id = 'user_foto_frameWebCam';
  76. $this->frameFotoWebCan->style = '';
  77. // label que fica acima da div
  78. $labelframeFotoWebCan = new TLabel('Foto Tirada');
  79. $labelframeFotoWebCan->id = 'labelframeFotoWebCan';
  80. $labelframeFotoWebCan->style = 'display:none';
  81. // botão para acessar a webcam
  82. $btnWebcam = new TButton('btnWebcam');
  83. $btnWebcam->addFunction("setup(); $(this).hide(); $( '#labelAcessarWebcam' ).css( 'display', 'none' ); $( '#btnWebcamBaterFoto' ).css( 'display', '' ); $( '#labelWebcamBaterFoto' ).css( 'display', '' )");
  84. $btnWebcam->setImage('fa:camera');
  85. $btnWebcam->setLabel('Acessar Webcam');
  86. $btnWebcamLabel = new TLabel('&nbsp&nbsp');
  87. $btnWebcamLabel->id = 'labelAcessarWebcam';
  88. // botão para bater a foto
  89. $btnWebcamBaterFoto = new TButton('btnBaterFoto');
  90. $btnWebcamBaterFoto->addFunction("take_snapshot(); $( '#labelframeFotoWebCan' ).css( 'display', '' )");
  91. $btnWebcamBaterFoto->setImage('fa:camera');
  92. $btnWebcamBaterFoto->id = 'btnWebcamBaterFoto';
  93. $btnWebcamBaterFoto->style = 'display:none';
  94. $btnWebcamBaterFoto->setLabel('Bater Foto');
  95. $btnWebcamBaterFotoLabel = new TLabel('&nbsp&nbsp');
  96. $btnWebcamBaterFotoLabel->id = 'labelWebcamBaterFoto';
  97. $btnWebcamBaterFotoLabel->style = 'display:none';
  98. // adiciona os campos no form
  99. $row = $this->form->addContent( [ new TLabel('Formato 300x300 (Recomendado)'), $this->frameFoto ],
  100. [ $labelframeFotoWebCan, $this->frameFotoWebCan ],
  101. [ $btnWebcamLabel, $btnWebcam ],
  102. [ $btnWebcamBaterFotoLabel, $btnWebcamBaterFoto ] );
  103. $row->layout = ['col-sm-4', 'col-sm-4', 'col-sm-2', 'col-sm-2'];
  104. // campo text para receber a datauri da foto tirada (uso este campo para gerar/salvar a foto)
  105. $fotoWebcam = new TText('fotoWebcam');
  106. $fotoWebcam->id = 'idFotoWebcam';
  107. $fotoWebcam->style = 'display:none;';
  108. $this->form->addFields( [ $fotoWebcam ] );
  109. // create the form actions
  110. $btn = $this->form->addAction( _t('Save'), new TAction([$this, 'onSave']), 'fa:floppy-o' );
  111. $btn->class = 'btn btn-sm btn-primary';
  112. $btnNovo = $this->form->addAction( _t('New'), new TAction([$this, 'onEdit']), 'fa:eraser red' );
  113. $this->form->addAction( _t('Back to the listing'), new TAction(['PessoasList', 'onReload']), 'fa:table blue' );
  114. $this->form->addHeaderAction( _t('Save'), new TAction([$this, 'onSave']), 'fa:save green' );
  115. $this->form->addHeaderAction( _t('Back'), new TAction(['PessoasList', 'onReload']), 'fa:table blue' );
  116. // wrap the page content
  117. $vbox = new TVBox;
  118. $vbox->style = 'width: 98%';
  119. //$vbox->add(new TXMLBreadCrumb('menu.xml', 'PessoasList'));
  120. $vbox->add($this->form);
  121. // add the form inside the page
  122. parent::add($vbox);
  123. }
  124. /**
  125. * On complete upload
  126. */
  127. public static function onCompleteFoto( $param ) {
  128. //new TMessage('info', 'Upload completed: '.$param['nome_arq_foto']);
  129. //var_dump($param);
  130. // refresh photo_frame
  131. TScript::create( "$('#user_foto_frame').html('')" );
  132. TScript::create( "$('#user_foto_frame').append(\"<img style='max-width: 100%;' src='tmp/{$param[ 'nome_arq_foto' ]}'>\");" );
  133. }
  134. /**
  135. * method onSave()
  136. * Executed whenever the user clicks at the save button
  137. */
  138. public function onSave( $param )
  139. {
  140. try
  141. {
  142. TTransaction::open('db'); // open a transaction
  143. // get the form data into an active record Pessoa
  144. $object = $this->form->getData('Pessoa');
  145. //var_dump($object);
  146. //die;
  147. $this->form->validate(); // form validation
  148. // move a foto para a pasta
  149. $sourceUserFoto = 'tmp/' . $object->nome_arq_foto;
  150. $targetUserFoto = 'fotos/' . $object->nome_arq_foto;
  151. $finfoBanner = new finfo( FILEINFO_MIME_TYPE );
  152. //echo $sourceUserFoto . '<br>';
  153. //echo $targetUserFoto . '<br>';
  154. // validação do campo logo PNG/JPG
  155. if ( $object->nome_arq_foto != '' and file_exists( $sourceUserFoto ) and $finfoBanner->file( $sourceUserFoto ) != 'image/png' and $finfoBanner->file( $sourceUserFoto ) != 'image/jpeg' )
  156. {
  157. // excluir arquivo temporario
  158. unlink( $sourceUserFoto );
  159. // limpa o campo
  160. $object->nome_arq_foto = '';
  161. // retorna mensagem de erro
  162. throw new Exception( 'Foto inválida, escolha um arquivo no formato <strong>PNG</strong> ou <strong>JPG</strong> !' );
  163. }
  164. // nome fantasia igual ao nome se o fantasia estiver em banco
  165. if ( empty($object->nomefantasia) ):
  166. $object->nomefantasia = $object->nome;
  167. endif;
  168. // foto webcam
  169. if ( $object->fotoWebcam != '' )
  170. {
  171. $img = $object->fotoWebcam;
  172. $img = str_replace('data:image/jpeg;base64,', '', $img);
  173. $img = str_replace(' ', '+', $img);
  174. $data = base64_decode($img);
  175. //var_dump($data);
  176. $f = md5(uniqid(rand(), true)) . '_fotowebcam_pessoa.jpg';
  177. $success = file_put_contents('fotos/' . $f, $data);
  178. if ($success)
  179. {
  180. $object->nome_arq_foto = $f;
  181. $targetUserFoto = 'fotos/' . $object->nome_arq_foto;
  182. //var_dump($object->nome_arq_foto);
  183. }
  184. // limpa o campo
  185. $object->fotoWebcam = ' ';
  186. }
  187. // salva o registro
  188. //$object->store(); // stores the object
  189. $this->form->setData($object); // keep form data
  190. TTransaction::close(); // close the transaction
  191. // if the user uploaded a source file
  192. if ( ($object->nome_arq_foto != '') and file_exists( $sourceUserFoto ) and ( $finfoBanner->file( $sourceUserFoto ) == 'image/png' or $finfoBanner->file( $sourceUserFoto ) == 'image/jpeg') )
  193. {
  194. // redimenciona se a larguda for maior que 800px
  195. $img = new Canvas( $sourceUserFoto );
  196. //var_dump($img);
  197. $larg = 300;
  198. $altu = 300;
  199. // se tem largura ou altura então redimenciona
  200. if ($larg != 0 || $altu != 0):
  201. $img->redimensiona( $larg, $altu, 'preenchimento' );
  202. endif;
  203. // grava uma nova imagem com 90% de qualidade da original
  204. $img->grava( $sourceUserFoto, 90 );
  205. // move to the target directory
  206. rename( $sourceUserFoto, $targetUserFoto );
  207. }
  208. // exibe a imagem
  209. if ( $object->nome_arq_foto != '' ):
  210. $image = new TImage( $targetUserFoto );
  211. $image->style = 'max-width: 100%;';
  212. $this->frameFoto->clearChildren();
  213. $this->frameFoto->add( $image );
  214. endif;
  215. // neste reload vai colocar os endereços e contatos na tela
  216. $this->onReload( $param ); // reload
  217. $alert = new TAlert('info',TAdiantiCoreTranslator::translate( 'Record saved' ));
  218. $alert->id = 'alertOnSave';
  219. $alert->style = 'width: 98%';
  220. TScript::create( "$('#alertOnSave').fadeOut(5000);");
  221. parent::add( $alert );
  222. // shows the success message
  223. //new TMessage('info', TAdiantiCoreTranslator::translate('Record saved'));
  224. }
  225. catch (Exception $e) // in case of exception
  226. {
  227. new TMessage('error', '<b>Erro</b> ' . $e->getMessage()); // shows the exception error message
  228. $data = $this->form->getData();
  229. $this->form->setData( $data ); // keep form data
  230. if ( $data->nome_arq_foto != '' ): // se existe informação no campo
  231. if ( file_exists( 'tmp/' . $data->nome_arq_foto ) ): // se tem arquivo na pasta temporaria
  232. $image = new TImage( 'tmp/' . $data->nome_arq_foto );
  233. $image->style = 'max-width: 100%;';
  234. $this->frameFoto->add( $image );
  235. elseif ( file_exists( 'fotos/' . $data->nome_arq_foto ) ): // se não tem na pasta temporaria, então verifica a pasta padrão
  236. $image = new TImage( 'fotos/' . $data->nome_arq_foto );
  237. $image->style = 'max-width: 100%;';
  238. $this->frameFoto->add( $image );
  239. endif;
  240. endif;
  241. // neste reload vai colocar os endereços e contatos na tela
  242. $this->onReload( $param ); // reload
  243. TTransaction::rollback(); // undo all pending operations
  244. }
  245. }
  246. /**
  247. * method onEdit()
  248. * Executed whenever the user clicks at the edit button da datagrid
  249. */
  250. function onEdit($param)
  251. {
  252. try
  253. {
  254. if (isset($param['key']))
  255. {
  256. $key=$param['key']; // get the parameter $key
  257. TTransaction::open('db'); // open a transaction
  258. $object = new Pessoa($key); // instantiates the Active Record
  259. $this->form->setData($object); // fill the form
  260. // mostra imagem se existir
  261. if ( $object->nome_arq_foto ):
  262. $image = new TImage( 'fotos/' . $object->nome_arq_foto );
  263. $image->style = 'max-width: 100%;';
  264. $this->frameFoto->add( $image );
  265. endif;
  266. // neste reload vai colocar os endereços na tela
  267. $this->onReload( $param ); // reload endereços
  268. TTransaction::close(); // close the transaction
  269. }
  270. else
  271. {
  272. //$this->form->clear();
  273. }
  274. }
  275. catch (Exception $e) // in case of exception
  276. {
  277. new TMessage('error', '<b>Erro</b> ' . $e->getMessage()); // shows the exception error message
  278. TTransaction::rollback(); // undo all pending operations
  279. }
  280. }
  281. /**
  282. * Reload the item list
  283. * @param $param URL parameters
  284. */
  285. public function onReload($param)
  286. {
  287. $data = $this->form->getData();
  288. $this->loaded = TRUE;
  289. }
  290. }
  291. ?>


conteudo do: webcam.nome_seu_arquivo.js
Webcam.set({ // live preview size width: 380, height: 300, // device capture size dest_width: 380, dest_height: 300, // final cropped size crop_width: 300, crop_height: 300, image_format: 'jpeg', jpeg_quality: 90 }); function setup() { Webcam.reset(); Webcam.attach('#user_foto_frame'); } function take_snapshot() { // take snapshot and get image data Webcam.snap(function (data_uri) { // display results in page document.getElementById('user_foto_frameWebCam').innerHTML = '<img src="' + data_uri + '"/>'; $("textarea[name='fotoWebcam']").val(data_uri); }); }
LC

O arquivo webcam.min.js pode pegar neste link:https://www.adianti.com.br/forum/pt/view_4223?utilizar-webcamjs-para-tirar-fotos
PF

Leandro, valeu a dica e exemplo. Farei a implementação em meu site.
PM

Eu reproduzi o conteudo acima porem ao clicar em acessar a webcam nada acontece, alguem ai conseguiu?
LC

Pedro, inspecione ai e veja se carregou os arquivos js :
<script language="JavaScript" src="app/lib/components/webcam/webcam.min.js"></script> <script language="JavaScript" src="app/lib/components/webcam/webcam.nome_seu_arquivo.js"></script>


Se carregou veja se no inicio do arquivo webcam.min.js esta com essa versão:
// WebcamJS v1.0.24 - http://github.com/jhuckaby/webcamjs - MIT Licensed


Confirme se o conteúdo do webcam.nome_seu_arquivo.js está conforme abaixo:
Webcam.set({ // live preview size width: 380, height: 300, // device capture size dest_width: 380, dest_height: 300, // final cropped size crop_width: 300, crop_height: 300, image_format: 'jpeg', jpeg_quality: 90 }); function setup() { Webcam.reset(); Webcam.attach('#user_foto_frame'); } function take_snapshot() { // take snapshot and get image data Webcam.snap(function (data_uri) { // display results in page document.getElementById('user_foto_frameWebCam').innerHTML = '<img src="' + data_uri + '"/>'; $("textarea[name='fotoWebcam']").val(data_uri); }); }


LC

Pedro, inspecione ai e veja se carregou os arquivos js :
 
  1. <?php
  2. <script language="JavaScript" src="app/lib/components/webcam/webcam.min.js"></script>
  3. <script language="JavaScript" src="app/lib/components/webcam/webcam.nome_seu_arquivo.js"></script>
  4. ?>


Se carregou veja se no inicio do arquivo webcam.min.js esta com essa versão:
// WebcamJS v1.0.24 - http://github.com/jhuckaby/webcamjs - MIT Licensed


Confirme se o conteúdo do webcam.nome_seu_arquivo.js está conforme abaixo:
 
  1. <?php
  2. Webcam.set({
  3. // live preview size
  4. width: 380,
  5. height: 300,
  6. // device capture size
  7. dest_width: 380,
  8. dest_height: 300,
  9. // final cropped size
  10. crop_width: 300,
  11. crop_height: 300,
  12. image_format: 'jpeg',
  13. jpeg_quality: 90
  14. });
  15. function setup() {
  16. Webcam.reset();
  17. Webcam.attach('#user_foto_frame');
  18. }
  19. function take_snapshot() {
  20. // take snapshot and get image data
  21. Webcam.snap(function (data_uri) {
  22. // display results in page
  23. document.getElementById('user_foto_frameWebCam').innerHTML = '<img src="' + data_uri + '"/>';
  24. $("textarea[name='fotoWebcam']").val(data_uri);
  25. });
  26. }
  27. ?>


PM

Agora funcionou! Obrigado!
AC

Muito bom meu caro. Adaptei ao meu código, porém quando eu tento salvar uma imagem via webcam ele perde o endereço da imagem. Observei que a pasta tmp é excluída. Já passou por algo similar?
LC

Alexsandro, aqui comigo funciona normal.

Veja que ai a pasta tmp é usada quando carrega um arquivo usando o campo TFile ($nome_arq_foto).

A imagem vindo pela captura da Webcam não passa pela pasta tmp, ai no exemplo ela vai para uma pasta chamada fotos, neste comando:
 
  1. <?php
  2. $success = file_put_contents('fotos/' . $f, $data);
  3. ?>
AC

Eu já faço isso meu caro. Estou tentado aqui.
AC

Depois de algumas modificações eu consegui resolver o problema.