Dev (Back & Front)ARTIGO

Upload e Recorte de imagens com PHP & jQuery

Hoje vou ensinar você como utilizar o plug-in Image Area Select
plugin de Michal Wojciechowski, para criar uma interface bastante
intuitiva onde o usuário possa escolher uma área da fotografia, fazer o
recorte e então fazer utilizar upload da imagem sendo ela JPG, GIF ou
PNG.

Requisitos

Resumo de funcionamento

1. Vamos usar uma variável de sessão para guardar
um nome randômico para o arquivo (neste caso o timestamp). Depois,
guardamos a extensão do arquivo para ser passado através do script para
assegurarmos de que ele irá lidar com o tipo certo da imagem.

//Apenas grava o novo timestamp caso a variavel esteja vazia.<br />if (strlen($_SESSION['random_key'])==0){<br />	$_SESSION['random_key'] = strtotime(date('Y-m-d H:i:s')); //Grava o timestamp para uma variavel de sessão<br />	$_SESSION['user_file_ext']= "";<br />}

Nota: Uma vez que a thumbnail foi criada, setamos a
variável de sessão igual a nada, vazia. Isso permite que uma nova
imagem seja enviada com um novo nome.

2. Capturamos, renomeamos e redimencionamos a imagem carregada. Nesta parte, fazemos a validação do arquivo que foi feito o upload para validar se o mime type da imagem corresponde com a extensão do arquivo para fazer deste um sistema mais seguro.

foreach ($allowed_image_types as $mime_type => $ext) {<br />	//Faz um loop pelos mime types permitidos e se eles baterem com a imagem que foi enviado o loop é interrompido.<br />	//Se tudo estiver ok, ele prossegue e verifica o tamanho do arquivo.<br />	if($file_ext==$ext && $userfile_type==$mime_type){<br />		$error = "";<br />		break;<br />	}else{<br />		$error = "Somente imagens <strong>".$image_ext."</strong> são aceitas para o upload";<br />	}<br />}<br />//Verifica se o tamanho do arquivo tem um tamanho permitido.<br />if ($userfile_size > ($max_file*1048576)) {<br />	$error.= "Imagens devem ser menores que ".$max_file."MB em seu tamanho";<br />}

3. Ainda no passo anterior, pegamos as cordenadas (x1,y1,x2,y2) utilizando o Image Area Select plugin e mandamos os detalhes para o servidor.

Descrição das coordenadas

  • x1, y1 = Coordenadas do topo esquerdo da área de seleção.
  • x2, y2 = Coordenadas da parte inferior direta a partir da seleção.
  • width = Largura do recorte.
  • height = Altura do recorte.

Estas são as coordenadas que são manipuladas pelo plugin, como você
pode ver mais a frente. Optei por um aspect ratio de 1:1 (Largura e
altura de 100px) no modo de visualização quando estamos selecionando a
área de recorte da imagem.

Nota: Utilizando o cálculo php mais a frente, faz o
script muito mais dinâmico. Tudo o que você deve fazer é setar a
altura e a largura do seu thumbnail e o script vai calcular os tamanhos
de ratio/preview para você!

$(window).load(function () {<br />	$("#thumbnail").imgAreaSelect({ aspectRatio: "1:thumb_height/thumb_width", onSelectChange: preview });<br />});

A função a seguir roda quando fazemos nossa seleção. Ela pega a área
exata da seleção e coloca dentro da área de preview. A segunda função
popula os hidden fields que serão passados para o servidor.

function preview(img, selection) {<br />	var scaleX =  / selection.width;<br />	var scaleY =  / selection.height; <br /><br />	$('#thumbnail + div > img').css({<br />		width: Math.round(scaleX * ) + 'px',<br />		height: Math.round(scaleY * ) + 'px',<br />		marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',<br />		marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'<br />	});<br />	$('#x1').val(selection.x1);<br />	$('#y1').val(selection.y1);<br />	$('#x2').val(selection.x2);<br />	$('#y2').val(selection.y2);<br />	$('#w').val(selection.width);<br />	$('#h').val(selection.height);<br />}

Essa função não é obrigatória, mas ajuda a verificar se o usuário
fez um recorte. No nosso caso, a seleção é obrigatória. O formulário é
submetido e se os valores existirem (ou se a seleção for feita),
prosseguimos.

$(document).ready(function () {<br />	$("#save_thumb").click(function() {<br />		var x1 = $("#x1").val();<br />		var y1 = $("#y1").val();<br />		var x2 = $("#x2").val();<br />		var y2 = $("#y2").val();<br />		var w = $("#w").val();<br />		var h = $("#h").val();<br />		if(x1=="" || y1=="" || x2=="" || y2=="" || w=="" || h==""){<br />			alert("Você precisa fazer uma seleção!");<br />			return false;<br />		}else{<br />			return true;<br />		}<br />	});<br />});

4. Finalmente, pegamos as novas coordenadas e geramos uma nova e redimencionada thumbnail.

if (isset($_POST["upload_thumbnail"])) {<br />	//Pega as novas coordenadas para recortar a imagem.<br />	$x1 = $_POST["x1"];<br />	$y1 = $_POST["y1"];<br />	$x2 = $_POST["x2"]; // Não é obrigatório<br />	$y2 = $_POST["y2"]; // Não é obrigatório<br />	$w = $_POST["w"];<br />	$h = $_POST["h"];<br />	//Escala a imagem para 100px por 100px<br />	$scale = $thumb_width/$w;<br />	$cropped = resizeThumbnailImage($thumb_image_location, $large_image_location,$w,$h,$x1,$y1,$scale);<br />	//Recarrega a imagem para ver a thumbnail<br />	header("location:".$_SERVER["PHP_SELF"]);<br />	exit();<br />}

Dê uma olhada na demo e faça o download do código completo funcionando.

Ao longo do tempo testamos o script no Firefox 2 e 3, Internet Explorer 6 e 7 e no Safari 3.1.2,
resultados muito bons, o único problema que encontramos foi quando
fizemos o upload de um gif transparente, os testes resultaram em uma
thumbnail com o fundo preto.

Demo

Clique aqui para ver o script em ação

Download

Clique aqui para fazer o download da versao 1.2

*

Este texto é uma adaptação e tradução do texto PHP & jQuery image upload and crop v1.2.

é formado em Desenvolvimento de Sistemas para Internet pela Faculdade Véris IBTA, Zend PHP 5 Certified Engineer, blogueiro e colunista iMasters, WebInsider e IBM DeveloperWorks.

Ver perfil