Recortando imagens com as bibliotecas jCrop e Image Manipulation no CodeIgniter

Recortando imagens com as bibliotecas jCrop e Image Manipulation no CodeIgniter

02/04/2016 5 Por Jonathan Lamim

Recortar imagens para torná-las compatíveis com o layout onde elas serão exibidas é um recurso muito utilizado hoje em dia, e esse tutorial vai ter mostrar como fazer isso de maneira bem simples.

Nesse tutorial você aprenderá a integrar a biblioteca javascript jCrop e as bibliotecas Image Manipulation e File Upload do CodeIgniter.

Passo 1 – Montando o ambiente

Monte o ambiente da aplicação CodeIgniter utilizando o modelo tradicional (download manual dos arquivos e cópia para o diretório em seu servidor) ou via Composer.

Para utilizar a biblioteca jCrop você precisará do jQuery em sua aplicação. Você pode utilizar um link direto via CDN para adicioná-lo ao projeto ou pode fazer o download manual e armazenar o arquivo em assets/js que deve estar localizado na raiz da aplicação.

Você pode fazer o download do arquivo no site http://jquery.com/, salvá-lo em assets/js e fazer a chamada dele no HTML apontando para o esse arquivo salvo em assets/js.

Ou então pode apenas fazer a chamada do jQuery no HTML usando o link direto do CDN do jQuery (https://code.jquery.com/jquery-3.4.1.min.js).

O importante é que ele seja chamado na sua página, pois o jCrop precisa dele pra funcionar.

Faça o download do jCrop em http://deepliquid.com/content/Jcrop_Download.html e após concluí-lo descompacte os arquivos, localize os diretórios ‘css’ e ‘js’ e copie os arquivos desses diretórios para assets/js e assets/css, respectivamente.

Após esse procedimento, não se esqueça de chamar no HTML tanto o CSS quanto os JavaScripts.

Para arquivos salvos no diretório do projeto:

<!-- jQuery -->
<script src="<?=base_url('assets/js/jquery-3.4.1.min.js')?>"></script></scrip>;

<!-- Plugin jCrop -->;
<script src="<?=base_url('assets/js/jquery.Jcrop.js')?>"></script>;

Para arquivos via CDN:

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script></scrip>;

<!-- Plugin jCrop -->;
<script src="<?=base_url('assets/js/jquery.Jcrop.js')?>"></script>;

Repare que foi utilizada a função base_url() para definir o caminho. Essa função retorna a URL absoluta da aplicação concatenada com o path passado como parâmetro para ela.

Diretórios

Na raiz da aplicação, no mesmo nível de application, crie um diretório chamado uploads com permissão de leitura e escrita, e dentro dele crie um outro diretório chamado crops, com as mesmas permissões.

Esses diretórios serão utilizados para armazenar as imagens originais gravadas através do processo de upload e as imagens recortadas, gravadas através do processo de recorte.

Passo 2 – Configurações

Vamos precisar configurar o carregamento do helper Url no arquivo application/config/autoload.php e as rotas no arquivo application/config/routes.php.

Autoload

Abra o arquivo application/config/autoload.php e adicione o helper url para carregamento automático.

$autoload['helper'] = array('url');

Rotas

Abra o arquivo application/config/routes.php e atualize-o conforme o código abaixo:

$route['default_controller'] = 'Base';
$route['recortar'] = 'Base/Recortar';
  • default_controller: definido como Base (que será criado mais adiante)
  • recortar: chama o método Recortar do controller Base, que processará o recorte da imagem

Passo 3 – Criando as views

Vamos criar 2 views, uma para a home e outra para a visualização da imagem recortada e os dados da imagem e do recorte.

Home

Crie um arquivo chamado home.php dentro do diretório application/views e adicione a ele o código abaixo.

Esse código é apenas o HTML dos elementos principais, você deverá adicionar a ele os cabeçalhos HTML e as chamadas aos arquivo CSS e JavaScript, conforme mostrado anteriormente.

<div>
    <div>
        <h1>Recortando imagens com as bibliotecas jCrop e Image Manipulation no CodeIgniter</h1>
    </div>
    <div>
        <div>
            <?php if(isset($error)):?>
                <div><?=$error?></div>
            <?php endif; ?>
            <form action="<?=base_url('recortar')?>" method="POST" enctype="multipart/form-data">
                <div>
                    <label>Selecione uma imagem em formato jpg ou png</label>
                    <input type="file" name="imagem" id="seleciona-imagem"/>
                </div>
        </div>
        <div>
            <p id="texto-informativo">Selecione uma imagem para recortar</p>
            <div id="imagem-box">
                <img src="" style="display:none;width:100%;" id="visualizacao_img" />
            </div>
            <input type="hidden" id="x" name="x" />
            <input type="hidden" id="y" name="y" />
            <input type="hidden" id="wcrop" name="wcrop" />
            <input type="hidden" id="hcrop" name="hcrop" />
            <input type="hidden" id="wvisualizacao" name="wvisualizacao" />
            <input type="hidden" id="hvisualizacao" name="hvisualizacao" />
            <input type="hidden" id="woriginal" name="woriginal" />
            <input type="hidden" id="horiginal" name="horiginal" />
            <div>
                <input type="submit" value="Recortar" id="recortar-imagem"/>
            </div>
            </form>
        </div>
    </div>
</div>

Temos uma view com uma verificação de mensagens de erro logo no início, que será exibida caso seja encontrado algum erro durante o processo de upload e recorte da imagem. Além disso ela possui uma formulário que chama a rota recortar, que irá processar os dados contidos no formulário, que envia para o controller as informações de tamanho da imagem na área de exibição, posicionamento e tamanho do ponto de corte e tamanho da imagem original.

Visualização

Crie um arquivo chamado visualizacao.php dentro do diretório application/views e adicione a ele o código abaixo.

Esse código é apenas o HTML dos elementos principais, você deverá adicionar a ele os cabeçalhos HTML e as chamadas aos arquivo CSS e JavaScript, conforme mostrado anteriormente.

<div>
    <div>
        <h1>Recortando imagens com as bibliotecas jCrop e Image Manipulation no CodeIgniter</h1>
    </div>
    <div>
        <div>
            <h3>Imagem Recortada</h3>
            <hr />
                <div id="imagem-box">
                    <img src="<?=$urlImagem?>" class="img-fluid"/>
                </div>
                <p><a href="<?=base_url()?>">Nova Imagem</a></p>
        </div>
        <?php if($dadosImagem == TRUE): ?>
        <div>
            <h3>Informações da Imagem</h3>
            <hr />
            <ul>
                <?php foreach($dadosImagem as $key => $value): ?>
                    <li><strong><?=$key?></strong> => <?=$value?></li>
                <?php endforeach; ?>
            </ul>
            <hr/>
            <h3>Informações do Recorte</h3>
            <hr />
            <ul>
                <?php foreach($dadosCrop as $key => $value): ?>
                    <li><strong><?=$key?></strong> => <?=$value?></li>
                <?php endforeach; ?>
            </ul>
        </div>
        <?php endif; ?>
    </div>
</div>

Assim como a home, essa é uma view simples, ela exibe a imagem que foi recortada e através de dois loops foreach exibe as informações sobre a imagem recortada e sobre o ponto de corte.

Passo 4 – Criando o controller

O controller é onde fica toda a codificação das operações a serem realizadas. Crie um arquivo chamado Base.php em application/controllers e adicione o código abaixo:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Base extends CI_Controller {

    // Classe construtora
    public function __construct(){
        parent::__construct();
        // Carrega as libraries necessárias: session, upload e image_lib
        $this->load->library(['session','upload','image_lib']);
    }

    // Acionando para exibir a home
    public function Index()
    {
        // Carrega a view da home
        $this->load->view('home');
    }

    // Executa o processo de recorte da imagem
    public function Recortar(){

        // Configurações para o upload da imagem
        // Diretório para gravar a imagem
        $configUpload['upload_path']   = "uploads";
        // Tipos de imagem permitidos
        $configUpload['allowed_types'] = 'jpg|png';
        // Usar nome de arquivo aleatório, ignorando o nome original do arquivo
        $configUpload['encrypt_name']  = TRUE;

        // Aplica as configurações para a library upload
        $this->upload->initialize($configUpload);

        // Verifica se o upload foi efetuado ou não
        // Em caso de erro carrega a home exibindo as mensagens
        // Em caso de sucesso faz o processo de recorte
        if ( ! $this->upload->do_upload('imagem'))
        {
            // Recupera as mensagens de erro e envia o usuário para a home
            $data= array('error' => $this->upload->display_errors());
            $this->load->view('home',$data);
        }
        else
        {
            // Recupera os dados da imagem
            $dadosImagem = $this->upload->data();

            // Calcula os tamanhos de ponto de corte e posição
            // de forma proporcional em relação ao tamanho da
            // imagem original
            $tamanhos = $this->CalculaPercetual($this->input->post());

            // Define as configurações para o recorte da imagem
            // Biblioteca a ser utilizada
            $configCrop['image_library'] = 'gd2';
            //Path da imagem a ser recortada
            $configCrop['source_image']  = $dadosImagem['full_path'];
            // Diretório onde a imagem recortada será gravada
            $configCrop['new_image']     = 'uploads/crops';
            // Proporção
            $configCrop['maintain_ratio']= FALSE;
            // Qualidade da imagem
            $configCrop['quality']             = 100;
            // Tamanho do recorte
            $configCrop['width']         = $tamanhos['wcrop'];
            $configCrop['height']        = $tamanhos['hcrop'];
            // Ponto de corte (eixos x e y)
            $configCrop['x_axis']        = $tamanhos['x'];
            $configCrop['y_axis']        = $tamanhos['y'];

            // Aplica as configurações para a library image_lib
            $this->image_lib->initialize($configCrop);

            // Verifica se o recorte foi efetuado ou não
            // Em caso de erro carrega a home exibindo as mensagens
            // Em caso de sucesso envia o usuário para a tela
            // de visualização do recorte
            if ( ! $this->image_lib->crop())
            {
                // Recupera as mensagens de erro e envia o usuário para a home
                $data = array('error' => $this->image_lib->display_errors());
                $this->load->view('home',$data);
            }
            else
            {   
                // Alimenta o array com as informações sobre a imagem original e as informações do recorte para exibir na tela
                $data['urlImagem'] = base_url('uploads/crops/'.$dadosImagem['file_name']);
                $data['dadosImagem'] = $dadosImagem;
                $data['dadosCrop'] = $tamanhos;               

                $this->load->view('visualizacao',$data);
            }
        }
    }

    // Método privado responsável por calcular os tamanhos de forma proporcional
    private function CalculaPercetual($dimensoes){
        // Verifica se a largura da imagem original é
        // maior que a da área de recorte, se for calcula o tamanho proporcional
        if($dimensoes['woriginal'] > $dimensoes['wvisualizacao']){
            $percentual = $dimensoes['woriginal'] / $dimensoes['wvisualizacao'];

            $dimensoes['x'] = round($dimensoes['x'] * $percentual);
            $dimensoes['y'] = round($dimensoes['y'] * $percentual);
            $dimensoes['wcrop'] = round($dimensoes['wcrop'] * $percentual);
            $dimensoes['hcrop'] = round($dimensoes['hcrop'] * $percentual);
        }

        // Retorna os valores a serem utilizados no processo de recorte da imagem
        return $dimensoes;
    }
}

Agora todas as operações a serem realizadas no servidor já foram codificadas, falta apenas fazer a codificação do JavaScript para que o jCrop funcione.

Passo 5 – Código JavaScript para o jCrop

Crie um arquivo chamado scripts.js no diretório assets/js que deve ter sido criado na raiz do projeto – no mesmo nível de application – no primeiro passo desse tutorial.

Coloque o código abaixo no arquivo:

$(document).ready(function(){

  // Ao selecionar uma imagem, ela é exibida
  // sem a necessidade de envio para o servidor
  // através e um upload
  $("#seleciona-imagem").change(function(){
    if (this.files && this.files[0]) {
        var reader = new FileReader();

        // Define o que será executado após o carregamento da imagem
        reader.onload = function (e) {
            // Passa para os elementos no DOM as informações
            // sobre a imagem a ser exibida e os textos
            $('#visualizacao_img').attr('src', e.target.result);
            $('#visualizacao_img').removeClass('hidden');
            $('#recortar-imagem').removeClass('hidden');
            $('#texto-informativo').html('Arraste o cursor sobre a imagem para selecionar a área de corte.');
            $('#texto-informativo').removeClass('alert-info').addClass('alert-success');

            // Ativa o recurso de recorte
            $('#visualizacao_img').Jcrop({
              aspectRatio: 1,
              onSelect: atualizaCoordenadas,
              onChange: atualizaCoordenadas
            });

            // Calcula o tamanho da imagem
            defineTamanhoImagem(e.target.result,$('#visualizacao_img'));
        }

        // Carrega a imagem e chama o 'reader.onload'
        reader.readAsDataURL(this.files[0]);
    }
  });

  // Ao tentar clicar o botão recortar
  // verifica se foi definida alguma área de corte
  $('#recortar-imagem').click(function(){
    if (parseInt($('#wcrop').val())) return true;
    alert('Selecione a área de corte para continuar.');
    return false;
  });
})

// Faz a atualização das coordenadas em relação ao ponto de corte
// cada vez que esse é modificado
// É chamado nos eventos onSelect e onChange do jCrop
function atualizaCoordenadas(c)
{
  $('#x').val(c.x);
  $('#y').val(c.y);
  $('#wcrop').val(c.w);
  $('#hcrop').val(c.h);
};

// Faz a verificação e define o tamanho da imagem original
// e da imagem na área de visualização para o recorte
function defineTamanhoImagem(imgOriginal, imgVisualizacao) {
  var image = new Image();
  image.src = imgOriginal;

  image.onload = function() {
    $('#wvisualizacao').val(imgVisualizacao.width());
    $('#hvisualizacao').val(imgVisualizacao.height());
    $('#woriginal').val(this.width);
    $('#horiginal').val(this.height);
  };
}

Não se esqueça de atualizar as views adicionando a chamada a esse novo arquivo JavaScript, conforme mostrado no primeiro passo.

Pronto! A codificação para o recorte de imagens usando jCrop e as bibliotecas do CodeIgniter File Upload e Image Manipulation está pronta e você já pode aplicar em seus projetos.

Você pode fazer o download do código-fonte completo em nosso GitHub.

Download do código-fonte

Bons Estudos!!!