MC
Componente de upload de imagens, com crop e rotação de imagem
Componente de upload de imagens, com cropp e rotação de imagem.
Bom dia a todos, no desenvolvimento de um novo projeto, me deparei com a necessidade de realizar o upload e manipulação de imagens, e por várias vezes tentei adaptar soluções expostas nos exemplos do framework, mas precisava de mais opções de configurações, como o crop, o giro e marca dágua, etc..., sem falar que os celulares de hoje em dia tem alta definição de imagens, e isso com o tempo poderia se tornar um problema salvar imagens "tão grandes". pesquisando na internet, efetuei a compra do plugin "Slim Image Cropper", por cerca de 17 dólares, e com a ajuda do Nataniel, experiente programador e membro da adianti, que adaptou o mesmo, venho até vocês compartilhar e tentar de alguma forma contribuir nesse meio tão importante de comunicação.
Primeiramente quero deixar claro que o plugin é pago, e comercializado pela empresa codecanyon, deixo apenas nesse artigo, o link de compra, as instruções para configuração no frame, e os fontes de demonstração de uso.
1- primeiro passo, Efetuar a compra do plugin em https://pqina.nl/slim/.
2- Após a compra e download do plugin, descompactar o conteúdo em app/lib/slim
3- Copiar o arquivo TSlim.class.php para a pasta app/lib/widget/ (em anexo )
3- Em app/templates/theme4/libraries.html adicionar a linha <link href="app/lib/slim/css/slim.min.css?appver=400" rel="stylesheet" type="text/css" media="screen"><!--componente slim-->
(observar o template de uso)
4 - Os fontes de demostração de uso está nos 3 arquivos postados abaixo, Imagem.class.php(colocar em app/model), ImagemList.class.php(colocar em app/control), ImagemForm.class.php(colocar em app/control) , ( em anexo as instruções de uso )
5 - Criar a pasta images, na raiz do projeto ( onde serão salvas as imagens )
Para demostrar o uso do plugin, no banco de dados permission.db, crie uma tabela com o nome "imagem" com o campo chamado nome, que armazenará o caminho da imagem após o upload.
Abaixo a classe adaptada pelo Nataniel para o frame , que deverá ser copiada para app/lib/widget/
Abaixo a classe de modelo, que deverá ser salva em app/model/
Abaixo a classe ImagemForm, que deverá ser salva na pasta app/control/.
Abaixo a grid de listagem, que deverá ser salva na pasta app/control
No exemplo acima, utilizei o template 4
Os arquivos podem ser baixados no formato .zip no link em anexo, eles contem as classes citadas acima, e as instruções de uso;
Podem também ser visualizados nos links abaixo:
https://ibb.co/fCVNST
imagizer.imageshack.us/a/img923/3059/WHqFqZ.gif
https://i.imgur.com/ewxHm4C.gifv
https://uploaddeimagens.com.br/imagens/amostra-gif-33f5ddd4-ed6f-463a-8dfb-f79263717155
Espero de alguma forma estar contribuindo com todos que gostarem deste componente, fiquem a vontade em postarem perguntas, boa sorte a todos.
Bom dia a todos, no desenvolvimento de um novo projeto, me deparei com a necessidade de realizar o upload e manipulação de imagens, e por várias vezes tentei adaptar soluções expostas nos exemplos do framework, mas precisava de mais opções de configurações, como o crop, o giro e marca dágua, etc..., sem falar que os celulares de hoje em dia tem alta definição de imagens, e isso com o tempo poderia se tornar um problema salvar imagens "tão grandes". pesquisando na internet, efetuei a compra do plugin "Slim Image Cropper", por cerca de 17 dólares, e com a ajuda do Nataniel, experiente programador e membro da adianti, que adaptou o mesmo, venho até vocês compartilhar e tentar de alguma forma contribuir nesse meio tão importante de comunicação.
Primeiramente quero deixar claro que o plugin é pago, e comercializado pela empresa codecanyon, deixo apenas nesse artigo, o link de compra, as instruções para configuração no frame, e os fontes de demonstração de uso.
1- primeiro passo, Efetuar a compra do plugin em https://pqina.nl/slim/.
2- Após a compra e download do plugin, descompactar o conteúdo em app/lib/slim
3- Copiar o arquivo TSlim.class.php para a pasta app/lib/widget/ (em anexo )
3- Em app/templates/theme4/libraries.html adicionar a linha <link href="app/lib/slim/css/slim.min.css?appver=400" rel="stylesheet" type="text/css" media="screen"><!--componente slim-->
(observar o template de uso)
4 - Os fontes de demostração de uso está nos 3 arquivos postados abaixo, Imagem.class.php(colocar em app/model), ImagemList.class.php(colocar em app/control), ImagemForm.class.php(colocar em app/control) , ( em anexo as instruções de uso )
5 - Criar a pasta images, na raiz do projeto ( onde serão salvas as imagens )
Para demostrar o uso do plugin, no banco de dados permission.db, crie uma tabela com o nome "imagem" com o campo chamado nome, que armazenará o caminho da imagem após o upload.
CREATE TABLE imagem ( id INTEGER PRIMARY KEY NOT NULL, nome varchar(100));
Abaixo a classe adaptada pelo Nataniel para o frame , que deverá ser copiada para app/lib/widget/
- <?php
- class TSlim extends TField implements AdiantiWidgetInterface
- {
- protected $value;
- public $container;
- public function __construct($name)
- {
- parent::__construct($name);
- //$this->id = 'slim_' . uniqid();
- $this->tag->type = 'file';
- $this->container = new TElement('div');
- $this->container->class = 'slim';
- $this->setDataProperties(['size'=>'640,640','label'=>'Upload imagem','button-confirm-label'=>'Confirmar',
- 'button-confirm-title'=>'Confirmar','button-cancel-label'=>'Cancelar',
- 'button-cancel-title'=>'Cancelar','button-edit-label'=>'Editar',
- 'button-edit-title'=>'Editar','button-remove-label'=>'Remover',
- 'button-remove-title'=>'Remover','button-rotate-label'=>'Girar',
- 'button-rotate-title'=>'Girar']);
- }
- public function setDataProperties($props)
- {
- foreach ($props as $prop => $val)
- {
- $this->container->{"data-{$prop}"} = $val;
- }
- }
- public function show()
- {
- $this->container->add($this->tag);
- if ($this->value)
- $this->container->add(new TImage($this->value));
- $js = TScript::create('',false);
- $js->src = 'app/lib/slim/js/slim.kickstart.min.js';
- $this->container->add($js);
- $this->container->show();
- }
- }
- ?>
Abaixo a classe de modelo, que deverá ser salva em app/model/
- <?php
- class Imagem extends TRecord
- {
- const TABLENAME = 'imagem';
- const PRIMARYKEY= 'id';
- const IDPOLICY = 'max'; // {max, serial}
- public function __construct($id = NULL, $callObjectLoad = TRUE)
- {
- parent::__construct($id, $callObjectLoad);
- parent::addAttribute('nome');
- }
- }?>
Abaixo a classe ImagemForm, que deverá ser salva na pasta app/control/.
- <?php
- class ImagemForm extends TPage
- {
- protected $form; // form
- public function __construct( $param )
- {
- parent::__construct();
- // creates the form
- $this->form = new TQuickForm('form_Imagem');
- $this->form->class = 'tform'; // change CSS class
- $this->form = new BootstrapFormWrapper($this->form);
- $this->form->style = 'display: table;width:100%'; // change style
- // define the form title
- $this->form->setFormTitle('Imagem');
- // create the form fields
- $id = new TEntry('id');
- $nome = new TSlim('nome');
- $nome->container->style = 'width:100%;height:240px;border:2px solid black';//tamanho do container do plugin no form
- $nome->setDataProperties(['label'=>'Upload imagem']);//aqui eu seto o nome do label
- //tamanho final no máximo 1500x1500 e proporção de 4:3 na janela de visualização
- $nome->setDataProperties(['size'=>'1500,1500','ratio'=>'4:3']);
- // add the fields
- $this->form->addQuickField('Id', $id, '100%' );
- $this->form->addQuickField('Nome', $nome, '100%' );
- if (!empty($id))
- {
- $id->setEditable(FALSE);
- }
- $nome->setDataProperties(['will-transform'=>'addWatermark']);
- //abaixo o código para inserir marca dágua
- $script = new TElement('script');
- $script->type = 'text/javascript';
- $javascript = "
- function addWatermark(data, ready) {
- // get the drawing context for the output image
- var ctx = data.output.image.getContext('2d');
- // draw our watermark on the center of the image
- var size = data.output.width / 40
- ctx.font = size + 'px sans-serif';
- var x = data.output.width * .5;
- var y = data.output.height * .9;
- var text = ctx.measureText('nome: nome que você escolher');
- var w = text.width * 1.15;
- var h = size * 1.75;
- ctx.fillStyle = 'rgba(0,0,0,.75)';
- ctx.fillRect(
- x - (w * .5),
- y - (h * .5),
- w, h
- );
- ctx.fillStyle = 'rgba(255,255,255,.9)';
- ctx.fillText(
- 'nome: nome que você escolher',
- x - (text.width * .5),
- y + (size * .35)
- );
- // continue saving the data
- ready(data);
- }
- ";
- $script->add($javascript);
- parent::add($script);
- // create the form actions
- $btn = $this->form->addQuickAction(_t('Save'), new TAction(array($this, 'onSave')), 'fa:floppy-o');
- $btn->class = 'btn btn-sm btn-primary';
- $btn2 = $this->form->addQuickAction(_t('New'), new TAction(array($this, 'onClear')), 'bs:plus-sign green');
- $btn3 = $this->form->addQuickAction( 'List' , new TAction(array('ImagemList', 'onClear')), 'fa:table blue' );
- // vertical box container
- $container = new TVBox;
- $container->style = 'width: 90%';
- // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
- $container->add(TPanelGroup::pack('Title', $this->form));
- parent::add($container);
- }
- public function onSave( $param )
- {
- try
- {
- TTransaction::open('permission'); // open a transaction
- /**
- if (empty($object->nome))
- {
- throw new Exception( 'O campo IMAGEM é obrigatório');
- }
- **/
- $this->form->validate(); // validate form data
- $object = new Imagem; // create an empty object
- $data = $this->form->getData(); // get form data as array
- $object->fromArray( (array) $data); // load the object with data
- $object2 = new Imagem($data->id); //objeto criado para testar se imagem foi repetida
- $images = Slim::getImages();
- // No image found under the supplied input name
- if ($images)
- {
- $image = $images[0];
- // save output data if set
- if (isset($image['output']['data']))
- {
- // Save the file
- $name = $image['output']['name'];
- // We'll use the output crop data
- $data = $image['output']['data'];
- //salva o arquivo na pasta images/ com o nome concatenado com o tempo
- $output = Slim::saveFile($data, time().'-'.$name, 'images/', false);
- //var_dump( $output );
- if( $object2->nome != $output )//teste de imagem repetida
- {
- if( file_exists ($object2->nome))// se existir apaga o anterior
- {
- unlink( $object2->nome ); //apaga
- }
- }
- $object->nome = $output['path'];//recebe o caminho para salvar
- }
- }
- else
- {
- $object2 = new Imagem($data->id);
- $object->nome = $object2->nome;
- }
- $object->store(); // save the object
- $this->form->setData($data); // fill form data
- TTransaction::close(); // close the transaction
- new TMessage('info', TAdiantiCoreTranslator::translate('Record saved'), new TAction(array('ImagemList', 'onClear')) );
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage()); // shows the exception error message
- $this->form->setData( $this->form->getData() ); // keep form data
- TTransaction::rollback(); // undo all pending operations
- }
- }
- public function onClear( $param )
- {
- $this->form->clear(TRUE);
- }
- public function onEdit( $param )
- {
- try
- {
- if (isset($param['key']))
- {
- $key = $param['key']; // get the parameter $key
- TTransaction::open('permission'); // open a transaction
- $object = new Imagem($key); // instantiates the Active Record
- $this->form->setData($object); // fill the form
- TTransaction::close(); // close the transaction
- }
- else
- {
- $this->form->clear(TRUE);
- }
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage()); // shows the exception error message
- TTransaction::rollback(); // undo all pending operations
- }
- }
- }
- ?>
Abaixo a grid de listagem, que deverá ser salva na pasta app/control
- <?php
- class ImagemList extends TStandardList
- {
- protected $form; // registration form
- protected $datagrid; // listing
- protected $pageNavigation;
- protected $formgrid;
- protected $deleteButton;
- protected $transformCallback;
- public function __construct()
- {
- parent::__construct();
- parent::setDatabase('permission'); // defines the database
- parent::setActiveRecord('Imagem'); // defines the active record
- parent::setDefaultOrder('id', 'asc'); // defines the default order
- // parent::setCriteria($criteria) // define a standard filter
- parent::addFilterField('id', 'like', 'id'); // filterField, operator, formField
- parent::addFilterField('nome', 'like', 'nome'); // filterField, operator, formField
- // creates the form
- $this->form = new TQuickForm('form_search_Imagem');
- $this->form->class = 'tform'; // change CSS class
- $this->form = new BootstrapFormWrapper($this->form);
- $this->form->style = 'display: table;width:100%'; // change style
- $this->form->setFormTitle('Imagem');
- // create the form fields
- $id = new TEntry('id');
- $nome = new TEntry('nome');
- // add the fields
- //$this->form->addQuickField('Id', $id, '100%' );
- $this->form->addQuickField('Nome', $nome, '100%' );
- // keep the form filled during navigation with session data
- $this->form->setData( TSession::getValue('Imagem_filter_data') );
- // add the search form actions
- $btn = $this->form->addQuickAction(_t('Find'), new TAction(array($this, 'onSearch')), 'fa:search');
- $btn->class = 'btn btn-sm btn-primary';
- $this->form->addQuickAction(_t('New'), new TAction(array('ImagemForm', 'onEdit')), 'bs:plus-sign green');
- // creates a DataGrid
- $this->datagrid = new TDataGrid;
- $this->datagrid = new BootstrapDatagridWrapper($this->datagrid);
- $this->datagrid->style = 'width: 100%';
- $this->datagrid->datatable = 'true';
- // creates the datagrid columns
- $column_id = new TDataGridColumn('id', 'Id', 'left');
- $column_nome = new TDataGridColumn('nome', 'Nome', 'left');
- // define the transformer method over image
- //função para mostrar a imagem no grid
- $column_nome->setTransformer( function($image) {
- $imagem= new TImage($image);
- $imagem->style='width:100px';//tamanho da imagem no grid
- return $imagem;
- });
- // add the columns to the DataGrid
- $this->datagrid->addColumn($column_id);
- $this->datagrid->addColumn($column_nome);
- // create EDIT action
- $action_edit = new TDataGridAction(array('ImagemForm', 'onEdit'));
- //$action_edit->setUseButton(TRUE);
- //$action_edit->setButtonClass('btn btn-default');
- $action_edit->setLabel(_t('Edit'));
- $action_edit->setImage('fa:pencil-square-o blue fa-lg');
- $action_edit->setField('id');
- $this->datagrid->addAction($action_edit);
- // create the datagrid model
- $this->datagrid->createModel();
- // create the page navigation
- $this->pageNavigation = new TPageNavigation;
- $this->pageNavigation->setAction(new TAction(array($this, 'onReload')));
- $this->pageNavigation->setWidth($this->datagrid->getWidth());
- // vertical box container
- $container = new TVBox;
- $container->style = 'width: 90%';
- // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
- $container->add(TPanelGroup::pack('Imagem', $this->form));
- $container->add(TPanelGroup::pack('', $this->datagrid, $this->pageNavigation));
- parent::add($container);
- }
- public function onClear( $param )
- {
- $this->form->clear(TRUE);
- }
- }
- ?>
No exemplo acima, utilizei o template 4
Os arquivos podem ser baixados no formato .zip no link em anexo, eles contem as classes citadas acima, e as instruções de uso;
Podem também ser visualizados nos links abaixo:
https://ibb.co/fCVNST
imagizer.imageshack.us/a/img923/3059/WHqFqZ.gif
https://i.imgur.com/ewxHm4C.gifv
https://uploaddeimagens.com.br/imagens/amostra-gif-33f5ddd4-ed6f-463a-8dfb-f79263717155
Espero de alguma forma estar contribuindo com todos que gostarem deste componente, fiquem a vontade em postarem perguntas, boa sorte a todos.
Para quem quiser testar o componente, segue o link:
miullerfc.acessotemporario.net/index.php?class=ImagemList&method
parabéns !!!
Muito Legal, vou experimentar !!!
Boa noite.
Estou tentando usar este componente porem algumas duvidas surgem. 1 Tem como forçar o redimensionamento da imagem no tamanho que preciso?
2 O mesmo também esta a gerar um erro.
Fatal error: Uncaught Error: Class 'Slim' not found in C:wamp64wwwRealEstate2admappcontrolCorretoresForm.class.php on line 102
( ! ) Error: Class 'Slim' not found in C:wamp64wwwRealEstate2admappcontrolCorretoresForm.class.php on line 102
Não sei porque raios ele faz isso.
a linha 102 do código se refere há $images = Slim::getImages(); como tem no exemplo original
Segue código completo abaixo.
Ola amigo comprei este componente slim mas estou com problemas em salvar no servidor já fiz vários teste permissão de pasta etc. Se puder me ajudar por favor com este erro: error: connection falied. Este erro ocorro quando estou tentando salvar o arquivo com slim. Obrigado Anderson
Para corrigir o erro
Fatal error: Uncaught Error: Class 'Slim' not found in C:wamp64wwwRealEstate2admappcontrolCorretoresForm.class.php on line 102
( ! ) Error: Class 'Slim' not found in C:wamp64wwwRealEstate2admappcontrolCorretoresForm.class.php on line 102
Renomeie o arquivo da pasta
O slim está com "s" minusculo.
Caso alguém tenha alguma dúvida, deixe seu email de contato.