Dev (Back & Front)ARTIGO

Upload de imagem com recorte usando Jquery e asp.net

Quem nunca quis disponibilizar,
em sua aplicação, a possibilidade de o usuário subir uma imagem e recortá-la, como vários sites já fazem? Dei uma pesquisada, estudei sobre o System.Drawing,  jquery e resolvi compartilhar aqui o que consegui. Veja só.

Bibliotecas

A primeira
coisa a ser feita aqui é baixar alguns arquivos, faça o download do jquery e do jcrop. 

Namespaces

Inclua os
seguintes namespaces em sua página:

  • System.IO
  • System.Drawing
  • System.Drawing.Imaging
  • System.Drawing.Drawing2D

O namespace System.Drawing sera utilizado
com apelido SD

Formulário

Adicione três controles do tipo Panel no formulário, conforme a
tabela abaixo:

ID Visible
UploadPanel True
ImagemOriginalPanel False
ImagemRecortadaPanel False

Dentro
do UploadPanel adicione os controles dessa forma:

Tipo ID Text Visible
FileUpload ArquivoFileUpload N/A True
Button UploadButton Upload True
Label ErroLabel “” False

Dentro
do ImagemOriginalPanel adicione os controles como mostrado:

Tipo ID Text
Image OriginalImage N/A
Button RecortarButton Recortar
HiddenField XHiddenField N/A
HiddenField YHiddenField N/A
HiddenField WHiddenField N/A
HiddenField HHiddenField N/A

Dentro
do ImagemRecortadaPanel adicione o seguinte controle:

Tipo ID Text
Image ImagemRecortadaImage N/A

O código da sua página deve estar bem parecido com este:

    <form id="form1" runat="server"><br />        <asp:Panel ID="UploadPanel" runat="server"><br />            <asp:FileUpload ID="ArquivoFileUpload" runat="server"/><br />            <asp:Button ID="UploadButton" runat="server" Text="Upload" /><br />        </asp:Panel><br />        <asp:Panel ID="ImagemOriginalPanel" runat="server" Visible="false"><br />            <asp:Image ID="OriginalImage" runat="server" /><br />            <asp:Button ID="RecortarButton" runat="server" Text="Recortar" /><br />            <asp:HiddenField ID="XHiddenField" runat="server" /><br />            <asp:HiddenField ID="YHiddenField" runat="server" /><br />            <asp:HiddenField ID="WHiddenField" runat="server" /><br />            <asp:HiddenField ID="HHiddenField" runat="server" /><br />        </asp:Panel><br />        <asp:Panel ID="ImagemRecortadaPanel" runat="server" Visible="false"><br />            <asp:Image ID="ImagemRecortadaImage" runat="server" /><br />        </asp:Panel>

Estrutura do site

Adicione
uma pasta com o nome imagens ao site.

Arquivos das bibliotecas

Adicione
os seguintes arquivos no site:

  • jquery.min.js
  • jquery.Jcrop.js
  • jquery.Jcrop.css

HTML

Inclua
as referências para os arquivos na sua página.

<script src="jquery.min.js" /></script><br /><script src="jquery.Jcrop.js" /></script><br /><link rel="stylesheet" href="jquery.Jcrop.css" type="text/css" />

Aplicando o Jcrop

Inclua as
seguintes funções na sua página:

        jQuery(document).ready(function(){<br />            jQuery('#OriginalImage').Jcrop({<br />                onSelect: marcaPontos<br />            });<br />        });<br /><br />        function marcaPontos(c) {<br />            jQuery('#XHiddenField').val(c.x);<br />            jQuery('#YHiddenField').val(c.y);<br />            jQuery('#WHiddenField').val(c.w);<br />            jQuery('#HHiddenField').val(c.h);<br />        };               

É realmente muito simples. Jcrop foi aplicado ao controle OriginalImage
que está dentro de ImagemOriginalPanel, e um handler foi adicionado ao evento de
selecionar a imagem. Isso acontecerá quando o usuário tiver acabado de
selecionar a área da imagem que deseja manter. O handler chamada a função
marcaPontos, que define os valores dos campos XHiddenField, HiddenField, WHiddenField
e HHiddenField passando as coordenadas.

Code Behind

O código
abaixo irá pegar o caminho físico da pasta imagens e guardá-lo na variável pasta,
declare-o no começo da classe da página.

string pasta = HttpContext.Current.Request.PhysicalApplicationPath + "imagens\\";

No evento click do botão
upload adicione o seguinte código:

    protected void UploadButton_Click(object sender, EventArgs e)<br />    {<br />        bool extensaoPermitida = false;<br />        bool arquivoGravado = false;<br /><br />        if (ArquivoFileUpload.HasFile)<br />        {<br />            string extensaoArquivo = Path.GetExtension(ArquivoFileUpload.FileName);<br /><br />            string[] extensoesPermitidas = { ".png", ".jpg", ".gif", ".jpeg" };<br /><br />            for (int i = 0; i < extensoesPermitidas.Length; i++)<br />                if (extensoesPermitidas[i] == extensaoArquivo)<br />                    extensaoPermitida = true;<br /><br />            if (extensaoPermitida)<br />            {<br />                try<br />                {<br />                    ArquivoFileUpload.PostedFile.SaveAs(pasta + ArquivoFileUpload.FileName);<br />                    arquivoGravado = true;<br />                }<br />                catch (Exception ex)<br />                {<br />                    ErroLabel.Text = "Ocorreu um problema na tentativa de salvar o arquivo." + ex.ToString();<br />                    ErroLabel.Visible = true;<br />                    arquivoGravado = false;<br />                }<br />            }<br />            else<br />            {<br />                ErroLabel.Text = string.Format("Tipo de arquivo inválido. Tipo aceitos {0}.", extensoesPermitidas.ToString());<br />                ErroLabel.Visible = true;<br />            }<br /><br />            if (arquivoGravado)<br />            {<br />                ImagemOriginalPanel.Visible = true;<br />                OriginalImage.ImageUrl = "imagens/" + ArquivoFileUpload.FileName;<br />                Session["arquivo"] = ArquivoFileUpload.FileName;<br />            }<br />        }<br />    }

No evento click do botão recortar
adicione o seguinte código:

   <br />protected void RecortarButton_Click(object sender, EventArgs e)<br />    {<br />        string nomeArquivo = Session["arquivo"].ToString();<br /><br />        int eixoX = Convert.ToInt32(XHiddenField.Value);<br />        int eixoY = Convert.ToInt32(YHiddenField.Value);<br />        int largura = Convert.ToInt32(WHiddenField.Value);<br />        int altura = Convert.ToInt32(HHiddenField.Value);<br /><br /><br />        byte[] recorte = Recortar(pasta + nomeArquivo, largura, altura, eixoX, eixoY);<br /><br />        using (MemoryStream ms = new MemoryStream(recorte, 0, recorte.Length))<br />        {<br />            ms.Write(recorte, 0, recorte.Length);<br /><br />            using (SD.Image imagemRecortada = SD.Image.FromStream(ms, true))<br />            {<br />                string salvarEm = pasta + "crop" + nomeArquivo;<br />                imagemRecortada.Save(salvarEm, imagemRecortada.RawFormat);<br />                ImagemOriginalPanel.Visible = false;<br />                ImagemRecortadaPanel.Visible = true;<br />                ImagemRecortadaImage.ImageUrl = "imagens/crop" + nomeArquivo;<br />            }<br />        }<br />    }

Crie um método do tipo void conforme
abaixo.

  private byte[] Recortar(string nomeAbsolutoArquivo, int largura, int altura, int eixoX, int eixoY)<br />    {<br />        try<br />        {<br />            using (SD.Image imagemOriginal = SD.Image.FromFile(nomeAbsolutoArquivo))<br />            {<br />                using (SD.Bitmap bitmap = new System.Drawing.Bitmap(largura, altura))<br />                {<br />                    bitmap.SetResolution(imagemOriginal.HorizontalResolution, imagemOriginal.VerticalResolution);<br /><br />                    using (SD.Graphics grafico = SD.Graphics.FromImage(bitmap))<br />                    {<br />                        grafico.SmoothingMode = SmoothingMode.AntiAlias;<br />                        grafico.InterpolationMode = InterpolationMode.HighQualityBicubic;<br />                        grafico.PixelOffsetMode = PixelOffsetMode.HighQuality;<br />                        grafico.DrawImage(imagemOriginal, new System.Drawing.Rectangle(0, 0, largura, altura), eixoX, eixoY, largura, altura, SD.GraphicsUnit.Pixel);<br />                        MemoryStream ms = new MemoryStream();<br />                        bitmap.Save(ms, imagemOriginal.RawFormat);<br />                        return ms.GetBuffer();<br />                    }<br />                }<br />            }<br />        }<br />        catch (Exception ex)<br />        {<br /><br />            throw ex;<br />        }<br />    }

Agora é só colocar tudo para
rodar. Não é um bicho de sete cabeças, a questão é juntar tudo.

Referências

Espero que esse artigo sirva para
agregar conhecimento à comunidade. Até a próxima.

é técnico em Processamento de Dados pelo Colégio Técnico Elevação, tecnólogo em Desenvolvimento de Sistemas para Web no Instituto Brasileiro de Tecnologia Avançado (IBTA, agora Instituto Veris) e faz pós-graduação em Engenharia de Sistemas com ênfase em SOA, no Instituto Veris.

Ver perfil