Criando miniaturas proporcionais
Walter Amorim (e-mail) é programador em ASP.net e VB.net desde 2003. Atualmente trabalha como Programador Web na agência AM4, em Barra Mansa/RJ. É cursando de Engenharia da Computação do Centro Universitário de Barra Mansa, unidade Cicuta (UBM-Cicuta).
Olá pessoal! Após algum tempo afastado do iMasters, estou voltando com um novo artigo, o qual espero que seja de ajuda à toda comunidade.
Pois bem. Veja a imagem abaixo, e imagine que ela tem 740px de altura e 1120px de altura:
Agora, imagine o quanto tempo essa imagem irá demorar a carregar, principalmente se o usuário estiver usando linha discada.
Como desenvolvedores, devemos estar atentos à este fato, principalmente quando damos ao nosso cliente a opção de ele fazer o upload das fotos. O que devemos fazer é mostrar ao visitante uma imagem menor, que carregue mais rapidamente, e dar ao visitante a opção de ver a imagem em seu tamanho original.
Isso é importante, pois você não quer ter que tratar cada imagem que seu cliente fizer upload no site, e o visitante do site também não quer esperar uma imagem gigantesca carregar.
Muita gente já escreveu sobre como criar miniaturas (thumbnails) de imagens, principalmente em ASP.net. Mas o que também trago para vocês é uma forma de redimensionar a imagem de forma proporcional, isto é, mantendo a proporção entre altura e largura da imagem, evitando que ela fique distorcida.
Um código normal, sem esse ajuste, iria criar a miniatura assim:
Iremos fazer com que a imagem fique assim:
Para entender melhor o que estou dizendo, acesse o exemplo on-line. Ou faça o download completo aqui.
Então, vamos programar. O código completo está abaixo.
<script language="VB" runat="server">
'Se desejar, pode alterar o caminho onde a imagem é salva, e o tamanho mínimo e máximo da imagem.
Private PastaOriginal As String = "imagens" 'Pasta onde está a imagem a ser redimensionada
Private PastaMiniatura As String = "imagens\miniaturas" 'Pasta onde ficará a miniatura
Private MaxLargura As Long = 50 'Largura MÁXIMA da miniatura (em pixels)
Private MaxAltura As Long = 50 'Altura MÁXIMA da miniatura (em pixels)
Private Function GerarMiniatura(ByVal NomeArquivo As String) As Boolean
'Gera a miniatura da imagem
Try
Response.Write("Detalhes da imagem")
Dim CaminhoInicial As String = PastaOriginal & "\" & NomeArquivo
Dim CaminhoFinal As String = PastaMiniatura & "\" & NomeArquivo
'Objetos usados para criar a imagem
Dim ImgOriginal As Drawing.Image = Drawing.Image.FromFile(Server.MapPath(CaminhoInicial))
Dim ImgFinal As Drawing.Image
Dim Graf As Graphics
'Define o novo tamanho da imagem
Dim dimensaoFinal As Size = NovoTamanho(ImgOriginal.Size, New Size(MaxLargura, MaxAltura))
'Define o novo formato da imagem
Dim Formato As Drawing.Imaging.ImageFormat = ImgOriginal.RawFormat
'Cria a nova imagem
ImgFinal = New Bitmap(dimensaoFinal.Width, dimensaoFinal.Height)
Graf = Graphics.FromImage(ImgFinal)
'Opções relativas à qualidade da nova imagem
Graf.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
Graf.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
Graf.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
'Desenha a imagem no objeto gráfico oGraf
Graf.DrawImage(ImgOriginal, New Rectangle(0, 0, dimensaoFinal.Width, dimensaoFinal.Height))
'Fecha a imagem original e salva a imagem final
ImgOriginal.Dispose()
ImgFinal.Save(Server.MapPath(CaminhoFinal), Formato)
ImgFinal.Dispose()
'Mostra a imagem original e a miniatura
Response.Write("
Imagem '" & CaminhoFinal.ToLower & "' salva com sucesso!
")
panResultado.Visible = True
img1.Src = CaminhoInicial
img2.Src = CaminhoFinal
Catch ex As Exception
Response.Write("Não foi possível salvar a imagem!
Erro completo: " & ex.ToString & "
")
Return False
End Try
End Function
Private Function NovoTamanho(ByVal Original As Size, ByVal Nova As Size) As Size
'Define o melhor tamanho para a nova imagem, de acordo com a
'proporção entre largura e altura da imagem original
Dim ProporcaoOriginal As Decimal = ((Original.Height * 100) / Original.Width) / 100
If ProporcaoOriginal > 1 Then
ProporcaoOriginal = ((Original.Width * 100) / Original.Height) / 100
NovoTamanho.Height = Nova.Height
NovoTamanho.Width = Nova.Height * ProporcaoOriginal
Else
NovoTamanho.Width = Nova.Width
NovoTamanho.Height = Nova.Width * ProporcaoOriginal
End If
Response.Write("
Tamanho original: " & Original.Width & "x" & Original.Height & "
")
Response.Write("Novo Tamanho: " & NovoTamanho.Width & "x" & NovoTamanho.Height & "
")
End Function
Protected Sub cmdEnviar_Click(ByVal sender As Object, ByVal e As System.EventArgs)
'Faz o upload da foto
'Pega o nome do arquivo
Dim NomeArquivo = arquivo.PostedFile.FileName.Substring(arquivo.PostedFile.FileName.LastIndexOf("\") + 1, arquivo.PostedFile.FileName.Length - arquivo.PostedFile.FileName.LastIndexOf("\") - 1)
arquivo.PostedFile.SaveAs(Server.MapPath("imagens/") & NomeArquivo)
'Gera a miniatura da foto
GerarMiniatura(NomeArquivo)
End Sub
SCRIPT>
<html><head><title>Walter Amorim - Upload e Redimensionamento de Imagens - iMasters.com.brtitle>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">head>
<body>
<form runat="server">
<asp:Panel id="panResultado" runat="server" Visible="False">
<hr />Imagem Original: <br />
<img id="img1" runat="server" /> <br /><br />Miniatura: <br />
<img id="img2" runat="server" /><br /><br /><hr />
asp:Panel>
Escolha a imagem para criar a miniatura:<br />
<input id="arquivo" type="file" runat="server" />
<asp:Button ID="cmdEnviar" runat="server" Text="Enviar" OnClick="cmdEnviar_Click" />
form>
body>html>
As linhas que você provavelmente irá querer alterar estão em negrito, e irei explicá-las a seguir.
01. Tamanho da imagem
Logo no começo, declaramos 2 variáveis importantes:
Private MaxLargura As Long = 50
Private MaxAltura As Long = 50
Estas duas variáveis definem a largura e a altura da miniatura, em pixels.
Este é o tamanho máximo da imagem. Ou seja, isto não significa que a imagem realmente fique com este tamanho.
Por exemplo:
Se a imagem original tiver 100x200px, a proporção será de 2 (200÷100 = 0.5).
Ou seja, a altura será de 2 vezes a largura da imagem. Portanto, a imagem será de 50x25px.
Se a imagem original tiver 200x100px, a proporção será de 0.5 (100÷200 = 0.5). A imagem terá 25x50px.
Se a imagem original tiver 800x600, a proporção será de 0.75 (600÷800 = 0.75). A imagem terá 50x38px.
02. Formato da imagem
Também podemos definir o formato de saída da imagem. Procure a linha:
Dim Formato As Drawing.Imaging.ImageFormat = ImgOriginal.RawFormat
Nela, nós informamos o formato de imagem que irá ser criado. Neste caso, será o mesmo formato da imagem original (imgOriginal.RawFormat|). Mas você pode definir outros formatos.
É isso. Por hoje é só. Espero que o código possa ajudar a todos. Caso você tenha alguma dúvida, não hesite em escrever para meu e-mail. Abraço.