Conheça as melhorias da versão 8.0, 8.1, 8.2!
Clique aqui para saber mais
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.