Uma das coisas que me decepciona muito no .Net é a falta do senso de comunidade.
Calma aí quem for dizer que há comunidade no universo .Net. Se você pensou isso todo empolgado, entre para o mundo Java e verás a gritante diferença!
Mas mesmo chorando a falta de boas listas e grupos de usuários como temos em Java, ainda há outra coisa que me decepciona muito que é a falta de bons componentes gratuitos para fazer determinadas coisas.
Se em Java você despacha para Pai Google “como fazer tal coisa em Java” e encontra 4 milhões de posts/artigos/papers/tutoriais e mais uns 1,5K componentes gratuitos para fazer tal coisa, em .Net...
Quando tu achas alguma coisa é um componente pago ou alguns poucos posts no stackoverflow.com.
Então eu estava querendo fazer algumas coisas com imagens e me debrucei no balcão de informações Google.com a procura de respostas para:
Recuperar um array de bytes a partir de um arquivo.
Gerar uma String base 64 deste array de bytes.
Redimensionar uma imagem via código.
Primeiro de tudo deixe-me explicar porque disso tudo.
Eu estou gravando imagens em um banco de dados direto do código c# da minha aplicação. Mas não quero gravar o binário do arquivo da imagem no banco e depois ter que recuperar o binário, jogar para algum lado interpretar isso para eu ter uma tag <img /> com o source apontando para um programa que vai ler o binário e me devolver um response do tipo image/{png, jpg, bmp}.
Então eu pego uma imagem, leio os bytes dela e transformo esses bytes em uma String de base 64 que eu posso utilizar diretamente na tag <img />:
<img alt="Embedded Image" src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD//gA8Q1... />
Então criei uma classe para a famigerada namespace útil, chamada ImageUtil:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace com.blogspot.jeanjmichel.util
{
/// <summary>
/// This class summarizes all possible operations applicable to an image.
/// </summary>
public class ImageUtil
{
/// <summary>
/// This method convert an image's bytes array to a based 64 String.
/// </summary>
/// <param name="bytesArray">Image's bytes in an array.</param>
/// <returns>Based 64 String.</returns>
public static String ConvertArrayOfBytesToStringBase64(byte[] bytesArray)
{
return System.Convert.ToBase64String(bytesArray, 0, bytesArray.Length);
}
/// <summary>
/// This method loads an image to an array of bytes.
/// </summary>
/// <param name="fileFullPath">Full path (path + file name) of the image.</param>
/// <returns>Image's bytes in an array.</returns>
public static byte[] ConvertImageToArrayOfBytes(String fileFullPath)
{
FileStream fS = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
byte[] imgBytes = new byte[fS.Length];
fS.Read(imgBytes, 0, (int)fS.Length);
fS.Close();
return imgBytes;
}
/// <summary>
/// This method returns the extension of the image's file.
/// </summary>
/// <param name="fileFullPath">Full path (path + file name) of the image.</param>
/// <returns>The extension of the image's file.</returns>
public static String GetImageExtension(String fileFullPath)
{
return Path.GetExtension(fileFullPath);
}
/// <summary>
/// This method generates an HTML <img /> tag with the embedded image data.
/// </summary>
/// <param name="fileExtension">The extension of the image's file.</param>
/// <param name="imgInBase64">The image's bytes in a based 64 String.</param>
/// <returns>An HTML <img /> tag with embedded image data.</returns>
public static String GenerateHTMLImgTag(String fileExtension, String imgInBase64)
{
return "<img alt=\"Embedded ImageUtil\" src=\"data:image/" + fileExtension + ";base64," + imgInBase64 + "\" />";
}
/// <summary>
/// This method resizes the image to a specified size.
/// </summary>
/// <param name="inFileFullPath">Full path (path + file name) of the original image.</param>
/// <param name="outFileFullPath">Full path (path + file name) of the resized image.</param>
/// <param name="newImagSize">Wanted size.</param>
/// <returns></returns>
public static Boolean ResizeImageTo(String inFileFullPath, String outFileFullPath, Size newImagSize)
{
System.Drawing.Image originalImage = new Bitmap(inFileFullPath);
int originalWidth = originalImage.Width;
int originalHeight = originalImage.Height;
if (originalWidth > newImagSize.Width || originalHeight > newImagSize.Height)
{
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)newImagSize.Width / (float)originalWidth);
nPercentH = ((float)newImagSize.Height / (float)originalHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(originalWidth * nPercent);
int destHeight = (int)(originalHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage(b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(originalImage, 0, 0, destWidth, destHeight);
g.Dispose();
b.Save(outFileFullPath, ImageFormat.Jpeg);
b.Dispose();
return true;
}
return false;
}
}
}
Essa classe tem métodos para retornar o array de bytes da imagem, a String base 64, gerar a tag HTML utilizando está String base 64 e ainda posso redimensiona a imagem.
Rodando um teste com a classe, onde eu tenho uma imagem em resolução 720x540 e irei:
Gerar um arquivo com a tag HTML embutindo os dados da imagem no source;
Gerar uma cópia da imagem em resolução de até 335x180 para utilizar neste post;
E gerar um arquivo com a tag HTML embutindo os dados da imagem redimensionada no source.
Eis a classe teste:
using System;
using System.IO;
using com.blogspot.jeanjmichel.util;
using System.Drawing;
namespace com.blogspot.jeanjmichel
{
public class Program
{
static void Main(string[] args)
{
String imagesDirectoryPath = @"C:\\WorkingWithImages\images\";
String originalImageName = "Anita.jpg";
String originalImageFullPath = imagesDirectoryPath + originalImageName;
String originalImageExtension = ImageUtil.GetImageExtension(imagesDirectoryPath + originalImageName).Replace(".", "").ToLower();
String originalImageOutTextFile = imagesDirectoryPath + originalImageName.Replace("." + originalImageExtension, ".txt");
String resizedImageName = originalImageName.Replace("." + originalImageExtension, " - resized.jpg");
String resizedImageFullPath = imagesDirectoryPath + resizedImageName;
String resizedImageOutTextFile = imagesDirectoryPath + resizedImageName.Replace(".jpg", ".txt");
Console.WriteLine("Generating HTML <img /> tag with embedded image data...");
byte[] originalImageBytes = ImageUtil.ConvertImageToArrayOfBytes(originalImageFullPath);
String originalImageInStringBase64 = ImageUtil.ConvertArrayOfBytesToStringBase64(originalImageBytes);
StreamWriter txtFile = new StreamWriter(originalImageOutTextFile);
txtFile.Write(ImageUtil.GenerateHTMLImgTag(originalImageExtension, originalImageInStringBase64));
txtFile.Flush();
txtFile.Dispose();
Console.WriteLine("Done!");
Console.WriteLine("Resizing the image to 335x180 resolution...");
if (ImageUtil.ResizeImageTo(originalImageFullPath, resizedImageFullPath, new Size(640, 480)))
{
Console.WriteLine("Done!");
Console.WriteLine("Generating HTML <img /> tag with embedded resized image data ...");
byte[] resizedImageBytes = ImageUtil.ConvertImageToArrayOfBytes(resizedImageFullPath);
String resizedImageInStringBase64 = ImageUtil.ConvertArrayOfBytesToStringBase64(resizedImageBytes);
StreamWriter txtFile2 = new StreamWriter(resizedImageOutTextFile);
txtFile2.Write(ImageUtil.GenerateHTMLImgTag("jpg", resizedImageInStringBase64));
txtFile2.Flush();
txtFile2.Dispose();
Console.WriteLine("Done!");
}
else
{
Console.WriteLine("The image is smaller than the new resolution!");
}
Console.ReadKey();
}
}
}
E a saída no console:
C:\WorkingWithImages\bin\Debug>WorkingWithImages.exe
Generating HTML <img /> tag with embedded image data...
Done!
Resizing the image to 335x180 resolution...
Done!
Generating HTML <img /> tag with embedded resized image data ...
Done!
Pronto, a imagem foi redimensionada e salva em disco, além de ter sido gerados dois arquivos txt com as tags HTML <img /> no mesmo diretório de imagens.
Original:
Redimensionada:
Está é a Anita, minha labradora ;)
Bom proveito para quem mais for útil ou possa interessar manipular imagens em c#. Lembrando que o código está no Git Hub também.
terça-feira, setembro 03, 2013
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário