Cortar imagens no navegador ANTES de carregar

Muitas bibliotecas que eu encontrei, como o Jcrop, não fazem o corte, apenas cria uma interface de usuário de corte de imagem. Depende então do servidor fazer o recorte real.

Como posso fazer a imagem cortar o lado do cliente usando algum recurso HTML5 sem usar qualquer código do lado do servidor.

Se sim, existem alguns exemplos ou dicas?

Sim, isso pode ser feito.
Ele é baseado no novo atributo “download” do html5 das tags de âncora.
O stream deve ser algo assim:

  1. carregar a imagem
  2. desenhe a imagem em uma canvas com os limites de colheita especificados
  3. obter os dados da imagem da canvas e torná-lo um atributo href para uma tag de âncora no dom
  4. adicione o atributo de download ( download="desired-file-name" ) para que a elemento é isso. tudo que o usuário tem a fazer é clicar no seu “link de download” e a imagem será baixada para o seu pc.

Eu voltarei com uma demonstração quando tiver a chance.

Atualizar
Aqui está a demonstração ao vivo como prometi. Leva o logotipo jsfiddle e colhe 5px de cada margem.
O código é assim:

 var img = new Image(); img.onload = function(){ var cropMarginWidth = 5, canvas = $('') .attr({ width: img.width - 2 * cropMarginWidth, height: img.height - 2 * cropMarginWidth }) .hide() .appendTo('body'), ctx = canvas.get(0).getContext('2d'), a = $(''), cropCoords = { topLeft : { x : cropMarginWidth, y : cropMarginWidth }, bottomRight :{ x : img.width - cropMarginWidth, y : img.height - cropMarginWidth } }; ctx.drawImage(img, cropCoords.topLeft.x, cropCoords.topLeft.y, cropCoords.bottomRight.x, cropCoords.bottomRight.y, 0, 0, img.width, img.height); var base64ImageData = canvas.get(0).toDataURL(); a .attr('href', base64ImageData) .text('cropped image') .appendTo('body'); a .clone() .attr('href', img.src) .text('original image') .attr('download','original-image') .appendTo('body'); canvas.remove(); } img.src = 'some-image-src'; 

Atualizar II
Esqueci de mencionar: claro que há uma desvantagem :(.
Por causa da política de mesma origem que é aplicada às imagens também, se você quiser acessar os dados de uma imagem (através do método de canvas para toDataUrl ).
Assim, você ainda precisaria de um proxy do lado do servidor que exibisse sua imagem como se estivesse hospedada em seu domínio.

Update III Embora eu não possa fornecer uma demonstração ao vivo para isso (por razões de segurança), aqui está um código de amostra do php que resolve a política de mesma origem:

arquivo proxy.php :

 $imgData = getimagesize($_GET['img']); header("Content-type: " . $imgData['mime']); echo file_get_contents($_GET['img']); 

Desta forma, em vez de carregar a imagem externa diretamente de sua origem:

 img.src = 'http://some-domain.com/imagefile.png'; 

Você pode carregá-lo através do seu proxy:

 img.src = 'proxy.php?img=' + encodeURIComponent('http://some-domain.com/imagefile.png'); 

E aqui está um exemplo de código php para salvar os dados da imagem (base64) em uma imagem real:

arquivo save-image.php :

 $data = preg_replace('/data:image\/(png|jpg|jpeg|gif|bmp);base64/','',$_POST['data']); $data = base64_decode($data); $img = imagecreatefromstring($data); $path = 'path-to-saved-images/'; // generate random name $name = substr(md5(time()),10); $ext = 'png'; $imageName = $path.$name.'.'.$ext; // write the image to disk imagepng($img, $imageName); imagedestroy($img); // return the image path echo $imageName; 

Tudo o que você precisa fazer é postar os dados da imagem nesse arquivo e salvar a imagem em disco e retornar o nome de arquivo da imagem existente.

É claro que tudo isso pode parecer um pouco complicado, mas eu queria mostrar a você que o que você está tentando alcançar é possível.

A biblioteca Pixastic faz exatamente o que você quer . No entanto, ele só funcionará em navegadores que tenham suporte a canvas. Para os navegadores mais antigos, você precisará:

  1. fornecer um fallback do lado do servidor, ou
  2. diga ao usuário que você sente muito, mas ele precisará de um navegador mais moderno.

Claro, a opção 2 não é muito fácil de usar. No entanto, se sua intenção for fornecer uma ferramenta exclusiva para clientes e / ou você não puder oferecer suporte a um criador de back-end de fallback (por exemplo, talvez esteja escrevendo uma extensão de navegador ou aplicativo off-line do Chrome ou talvez não possa pagar um provedor de hospedagem decente que forneça bibliotecas de manipulação de imagens), então provavelmente é justo limitar sua base de usuários a navegadores modernos.

EDIT : Se você não quer aprender Pixastic, eu adicionei um aparador muito simples no jsFiddle aqui . Deve ser possível modificar e integrar e usar a function drawCroppedImage com o Jcrop.

#change-avatar-file é uma input de arquivo #change-avatar-file é uma tag img (o alvo do jcrop) A “chave” é o evento FR.onloadend https://developer.mozilla.org/en-US/docs / Web / API / FileReader

 $('#change-avatar-file').change(function(){ var currentImg; if ( this.files && this.files[0] ) { var FR= new FileReader(); FR.onload = function(e) { $('#avatar-change-img').attr( "src", e.target.result ); currentImg = e.target.result; }; FR.readAsDataURL( this.files[0] ); FR.onloadend = function(e){ //console.log( $('#avatar-change-img').attr( "src")); var jcrop_api; $('#avatar-change-img').Jcrop({ bgFade: true, bgOpacity: .2, setSelect: [ 60, 70, 540, 330 ] },function(){ jcrop_api = this; }); } } }); 

Se você ainda usar o JCrop, precisará apenas das funções do php para recortar o arquivo:

 $img_src = imagecreatefromjpeg($src); $img_dest = imagecreatetruecolor($new_w,$new_h); imagecopyresampled($img_dest,$img_src,0,0,$x,$y,$new_w,$new_h,$w,$h); imagejpeg($img_dest,$dest); 

lado do cliente:

 jQuery(function($){ $('#target').Jcrop({ onChange: showCoords, onSelect: showCoords, onRelease: clearCoords }); }); var x,y,w,h; //these variables are necessary to crop function showCoords(c) { x = cx; y = cy; w = cw; h = ch; }; function clearCoords() { x=y=w=h=0; }