{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}
03/08/2012
Dando continuidado ao post de Upload + Progressbar + JCrop assíncrono agora nós vamos fazer o download do JCrop e referenciá-lo em nossa view. Descompacte o zip e referencie estes arquivos um javascript:
<script src='@Url.Content("~/Scripts/jquery.Jcrop.min.js")' type="text/javascript"></script>
E um stylesheet:
<link rel="stylesheet" href='@Url.Content("~/Content/jcrop/jquery.Jcrop.min.css")' type="text/css" />
Feito isso vamos adicionar um novo formulário em nossa página. Eu optei por um novo formulário para deixar as coisas bem separadas, vejam abaixo:
@using (Html.BeginForm("Crop", "Upload", null, FormMethod.Post, new { enctype = "multipart/form-data", name = "crop" })) {
<input type="hidden" name="url" />
<input type="hidden" name="x1" id="x1" />
<input type="hidden" name="x2" id="x2" />
<input type="hidden" name="y1" id="y1" />
<input type="hidden" name="y2" id="y2" />
<input type="submit" value="Recortar" class="hidden" id="recortar" />
}
<img src="" class="hidden" id="imagem_final"></img>
Reparem que tudo que temos aí são campos hidden. O primeiro deles irá guardar a URL da imagem que queremos recortar e com isso eu não farei o upload de uma nova imagem para o servidor. Os outros campos são as coordenadas para o recorte.
Todas estas informações serão alimentadas pelo javascript e pelo próprio JCrop. Vejam como configuraremos o JCrop:
1 function showCoords(c) {
2 $("#x1").val(c.x);
3 $("#x2").val(c.x2);
4 $("#y1").val(c.y);
5 $("#y2").val(c.y2);
6
7 $("#recortar").removeClass("hidden");
8 }
9 function ativarJCrop() {
10 $('#imagem_crop').Jcrop({
11 bgColor: 'black',
12 bgOpacity: .4,
13 aspectRatio: 1,
14 onSelect: showCoords
15 });
16 }
Estas duas funções são tudo o que precisamos. E eu vou chamar a função ativarJCrop dentro do success do upload da imagem (confira aqui no artigo anterior).
Para realizarmos o crop no servidor teremos algo parecido com isso:
1 [HttpPost]
2 public ActionResult Crop() {
3 var imagem_url = Request.Form["url"];
4 var x1 = int.Parse(Request.Form["x1"]);
5 var x2 = int.Parse(Request.Form["x2"]);
6 var y1 = int.Parse(Request.Form["y1"]);
7 var y2 = int.Parse(Request.Form["y2"]);
8 var nomeFinal = "../uploads/imagem_crop" + Path.GetExtension(imagem_url);
9
10 using (var response = new StreamReader(Server.MapPath(imagem_url))) {
11 Bitmap imagem = new Bitmap(response.BaseStream);
12
13 int largura = x2 - x1;
14 int altura = y2 - y1;
15
16 Bitmap target = new Bitmap(largura, altura);
17 Rectangle cropRect = new Rectangle(x1, y1, largura, altura);
18
19 using (Graphics g = Graphics.FromImage(target)) {
20 g.DrawImage(imagem, new Rectangle(0, 0, largura, altura), cropRect, GraphicsUnit.Pixel);
21 using (var fileStream = new FileStream(Server.MapPath(nomeFinal), FileMode.OpenOrCreate)) {
22 target.Save(fileStream, imagem.RawFormat);
23 fileStream.Flush();
24 }
25 }
26 }
27
28 return Json(new { imagem_recortada = nomeFinal });
29 }
Basicamente o que esse código faz é recortar uma imagem. É um código padrão então vou vou explicá-lo. Reparem apenas que ao final retornamos um json. É com isto que exibiremos a imagem recortada após o trabalho do server.
Para isso vamos adicionar o ajaxForm ao nosso formulário de crop:
1 $('form[name=crop]').ajaxForm({
2 dataType: 'json',
3 success: function (data) {
4 jcrop.destroy();
5 $(".progress").addClass("hidden");
6 $("#imagem_crop").addClass("hidden");
7 $("#imagem_crop").removeAttr("style");
8 $("#recortar").addClass("hidden");
9
10 $("#imagem_final").attr("src", data.imagem_recortada);
11 $("#imagem_final").removeClass("hidden");
12 }
13 });
Pronto! Agora tudo está feito e funcionando:
Com isso terminamos nosso upload e crop assíncrono com Jquery, JCrop e ASP.NET MVC. Até que é uma tarefa simples depois de ter entendido tudo que é necessário. Eu fiz algumas firulas para esconder e exibir uma série de componentes na tela e tudo o mais, mas pode ser que vocês não precisem disso.
O código completo está no github https://github.com/vquaiato/upload-crop-async-sample