Desenvolvimento - ASP. NET
Recorte de Imagens com C#, Asp.NET e jQuery
Neste artigo veremos como fazer o Recorte de Imagens,uma ferramenta muito interessante que pode facilitar a vida de nossos clientes que utilizam muitas fotos em seus sites.
por Raphael Silva FerreiraNeste artigo iremos ver como implementar uma galeria de imagens utilizando C#, Asp.NET e jQuery. Para iniciarmos o artigo vamos baixar a versão mais recente do plugin chamado jCrop que pode ser baixado aqui.
Agora é a hora de colocarmos a mão na massa! Vamos abrir o Visual Studio e criar um projeto do tipo Web Site.
Em seguida vamos selecionar o tipo do projeto que será um Asp.NET Web Site, iremos chamá-lo de “Recorte” e definir o local onde ficará o projeto.
Criado nosso projeto vamos agora criar uma estrutura de pastas para separarmos os arquivos de javascript, os arquivos de estilo e as imagens dos demais. Este passo é mais questão de organização (com exceção da pasta de imagens que deve ser criada), quem quiser poderá avançar a próxima etapa.
Para adicionar uma nova pasta, clique com o botão direito do mouse e em seguida na opção “New Folder”. Crie três pastas “Css” ,“JavaScript” e “Imagens”., e na pasta de “Imagens” crie uma pasta “recortadas” (onde irão ficar as imagens recortadas) A solution deve ficar como a figura a seguir:
Criadas as pastas vamos adicionar os arquivos referentes ao jCrop. Primeiro vamos à pasta Css e adicionaremos todos os arquivos que estão na pasta “css” dentro da pasta jCrop que foi descompactada. Em seguida faremos o mesmo na pasta JavaScript adicionando os arquivos “jquery.min.js” e “jquery.Jcrop.min.js” presentes na pasta “js” da pasta descompactada do jCrop.
Agora adicionamos os scripts do jQuery e do jCrop, além do css na nossa página Default.aspx:
<link href="css/jquery.Jcrop.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="JavaScript/jquery.min.js"></script> <script type="text/javascript" src="JavaScript/jquery.Jcrop.min.js"> </script>
|
Além deles vamos adicionar o script a seguir que será responsável por fazer a marcação do recorte e mostrá-lo na miniatura ao lado da imagem original. Lembrando que “#original” corresponde ao ID da imagem de origem e “#preview” o ID da imagem prévia do recorte.
<script type="text/javascript"> $(function() { $("#original").Jcrop ( { onChange: showPreview, onSelect: showPreview, aspectRatio: 1 } ); function showPreview(coords) { if (parseInt(coords.w) > 0) { jQuery("#X").val(coords.x); jQuery("#Y").val(coords.y); jQuery("#W").val(coords.w); jQuery("#H").val(coords.h);
var rx = 100 / coords.w; var ry = 100 / coords.h;
var largura = $("#original").width(); var altura = $("#original").height();
$("#preview").css ( { width: Math.round(rx * largura) + "px", height: Math.round(ry * altura) + "px", marginLeft: "-" + Math.round(rx * coords.x) + "px", marginTop: "-" + Math.round(ry * coords.y) + "px" } ); } }; }); </script> |
Agora vamos criar a estrutura de nossa página com uma tabela contendo três linhas e duas colunas. Na primeira coluna vamos adicionar um fileUpload, um botão para carregar a imagem, um label identificando possível erro e um botão que será responsável por efetuar o recorte ficando da seguinte maneira:
<tr> <td> <asp:FileUpload ID="Upload" runat="server" /> <asp:Button ID="btnCarregar" runat="server" Text="Carregar" OnClick="btnCarregar_Click" /> </td> <td> <asp:Label runat="server" ID="lblErro" Visible="false"></asp:Label> <asp:Button ID="btnRecorte" runat="server" OnClick="btnRecortar_Click" visible="false" Text="Recortar" /> </td> </tr> |
Na segunda linha vamos adicionar duas imagens uma que será nossa origem e outra a preview conforme abaixo:
<tr> <td> <asp:Image ID="original" Visible="false" runat="server" ImageUrl="" /> </td> <td> <div style="width:87px;height:87px;overflow:hidden;margin-left:5px;"> <asp:Image ID="preview" Visible="false" runat="server" ImageUrl=""/> </div> </td> </tr> |
Na terceira e última linha iremos adicionar quatro Hiddens que serão responsáveis por armazenar altura, largura e as coordenadas para efetivação do recorte e ainda vamos adicionar uma imagem que irá nos mostrar o resultado do recorte.
<tr> <td> <asp:HiddenField ID="X" runat="server" /> <asp:HiddenField ID="Y" runat="server" /> <asp:HiddenField ID="W" runat="server" /> <asp:HiddenField ID="H" runat="server" /> </td> <td> <asp:Image ID="resultado" Visible="false" runat="server" ImageUrl=""/> </td> </tr> |
Como vocês devem ter notado, já adicionei os eventos dos botões e coloquei tem a visibilidade para cada etapa do processo. Agora vamos efetivamente para o codebehind.
Primeiramente vamos adicionar os seguintes namespaces:
using System.IO; using SD = System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; |
Optei por renomear para SD o System.Drawing para facilitar a chegada até algumas classes. Agora vamos fazer a parte de carregamento da imagem que será recortada, adicionando ao evento do click do carregar o seguinte código:
// Variável que contém o caminho da imagem string path = HttpContext.Current.Request.PhysicalApplicationPath + "Imagens\\";
// Variáveis auxiliares bool FileOK = false, FileSaved = false;
// Verifica se tem arquivo if (Upload.HasFile) { // Adiciona o nome da imagem que está sendo utilizada na session Session.Add("WorkingImage", Upload.FileName); // Pega a extensão da imagem string FileExtension = Path.GetExtension(Session["WorkingImage"].ToString()).ToLower(); // Array de extensões permitidas (configurável) string[] allowedExtensions = { ".png", ".jpeg", ".jpg", ".gif" };
// Verifica se a extensão da imagem é permitida for (int i = 0; i < allowedExtensions.Length; i++) { if (FileExtension == allowedExtensions[i]) { FileOK = true; } } // Se a extensão é permitida salva o arquivo if (FileOK) { try { Upload.PostedFile.SaveAs(path + Session["WorkingImage"]); FileSaved = true; } catch (Exception ex) { FileSaved = false; lblErro.Text = ex.Message; } } else { lblErro.Text = "Tipo de arquivo inválido."; lblErro.Visible = true; btnRecorte.Visible = preview.Visible = original.Visible = resultado.Visible = false; } if (FileSaved) { // Se a operação de save ocorrer com sucesso carrega as imagens preview.ImageUrl = original.ImageUrl = "Imagens/" + Session["WorkingImage"].ToString(); btnRecorte.Visible = preview.Visible = original.Visible = true; resultado.Visible = false; } |
Agora vamos adicionar ao evento click do botão de Recorte o seguinte código:
// Variável que contém o caminho da imagem string path = HttpContext.Current.Request.PhysicalApplicationPath + "Imagens\\";
// Recebe o caminho da imagem string ImageName = Session["WorkingImage"].ToString();
// Recebe os valores de altura,largura e coordenadas int w = Convert.ToInt32(W.Value); int h = Convert.ToInt32(H.Value); int x = Convert.ToInt32(X.Value); int y = Convert.ToInt32(Y.Value);
// Realiza o recorte da foto e salva a imagem byte[] CropImage = Crop(path + ImageName, w, h, x, y); using (MemoryStream ms = new MemoryStream(CropImage, 0,CropImage.Length)) { ms.Write(CropImage, 0, CropImage.Length); using (SD.Image CroppedImage = SD.Image.FromStream(ms, true)) { string caminho = path + "recortadas\\" + ImageName; CroppedImage.Save(caminho, CroppedImage.RawFormat); resultado.ImageUrl = "Imagens/recortadas/" + ImageName; resultado.Visible = true; original.Visible = preview.Visible = false; } } |
E em seguinte o algoritmo que irá fazer o recorte efetivamente:
/// <summary> /// Método responsável pelo recorte da foto /// </summary> /// <param name="Img">Imagem a ser recortada</param> /// <param name="Width">Largura</param> /// <param name="Height">Altura</param> /// <param name="X">Coordenada X</param> /// <param name="Y">Coordenada Y</param> /// <returns></returns> static byte[] Crop(string Img, int Width, int Height, int X, int Y) { try { using (SD.Image OriginalImage = SD.Image.FromFile(Img)) { using (SD.Bitmap bmp = new SD.Bitmap(Width, Height, OriginalImage.PixelFormat)) { bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution); using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp)) { Graphic.SmoothingMode = SmoothingMode.AntiAlias; Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality; Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel); MemoryStream ms = new MemoryStream(); bmp.Save(ms, OriginalImage.RawFormat); return ms.GetBuffer(); } } } } catch (Exception Ex) { throw (Ex); } } |
Por fim executamos a aplicação com F5, carregaremos a imagem que desejamos e poderemos recortar em qualquer parte desejada. Podendo aumentar ou diminuir a miniatura conforme desejarmos.
Bom pessoal é isso, espero que tenham gostado.
Até a próxima!