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 Ferreira



Neste 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!

Raphael Silva Ferreira

Raphael Silva Ferreira - Formado em Bacharelado em Ciência da Computação pela PUC-PR, atua como analista de sistemas na plataforma .NET. Desenvolve aplicações Web com C# e ASP.NET há cinco anos possuindo certificação da Microsoft MCP em .NET Framework 2.0.