Click here to Skip to main content
15,889,281 members
Articles / Programming Languages / C#
Article

A C# image enhancement filters library

Rate me:
Please Sign up or sign in to vote.
4.90/5 (51 votes)
11 May 2007LGPL32 min read 175.4K   4.1K   157   61
A set of filters to modify and style your images and photos

Library Home Page

Screenshot - box_colors2.png

Introduction

This project started from a need. A need to have a simple image/photo .NET filters functionality to style and enhance pictures to be displayed on the web (or any other place for that matter). True, there are some filter libraries scattered around the web for doing stuff like a WaterMark or a GrayScale or even a collection of those (ImageMagick). In most cases they are very basic or unhelpful for styling images. Furthermore, the .NET System.Drawing.* namespace doesn't provide any basic or sophisticated capabilities. For example, there isn't a proper rotate or resize functionality. So the goal was to collect all of the nice .NET filters that are out there into a single package and to extend it by providing more useful and styled filters.

Implementation

From the need that was described above I've created YAEL, which stands for: Yet Another Image Enhancement Library.

It is just a framework and filter classes. No UI (for now). The framework is very basic and simple so that extensions can easily be developed.

There is a basic IFilter interface and a BasicFilter abstract class. All of the filters derive from the BasicFilter class.

Current library filters consist of

  • Resize
  • Rotate
  • Grayscale
  • Rounded Corners
  • Boxing
  • Drop Shadow
  • Polaroid frame
  • Text and wartermark captions
  • Image watermark
  • Floor Reflection
  • FishEye
  • Skew
  • And more to come...

Here are some Samples:

Screenshot - grayScale_brighter.png

Screenshot - rotate_minus_30.png

Screenshot - rounded_35.png

Screenshot - box_colors2.png

Screenshot - dropShadow.png

Screenshot - dropShadow.png

Screenshot - text_water_middle_left.png

Screenshot - image_watermark_pacman.png

Screenshot - image_fisheye_default.png

Screenshot - image_floor_reflection.png

Screenshot - image_skew_plain.png

Usage

Usage is very straightforward. All you have to do is reference the library assemblies, load up an image, initialize a filter, execute the filter, and save back the transformed image.

Here is a sample:

C#
static void Main(string[] args)
{
    Image myImg = Bitmap.FromFile("cat.jpg");
    Image transformedImage;
    ZRLabs.Yael.BasicFilters.TextWatermarkFilter watermark = new 
        TextWatermarkFilter();
    ZRLabs.Yael.BasicFilters.BoxFilter box = new BoxFilter();
    ZRLabs.Yael.BasicFilters.BlackAndWhiteFilter blackAndWhite = new 
        BlackAndWhiteFilter();

    //A text watermark example
    watermark.Caption = "Test";
    watermark.AutomaticTextSize = true;
    transformedImage = watermark.ExecuteFilter(myImg);
    transformedImage.Save("cat_watermark.png", 
        System.Drawing.Imaging.ImageFormat.Png);

    //A boxing example
    transformedImage = box.ExecuteFilter(myImg);
    transformedImage.Save("cat_box.png", 
        System.Drawing.Imaging.ImageFormat.Png);

    //A grayscale example
    transformedImage = blackAndWhite.ExecuteFilter(myImg);
    transformedImage.Save("cat_blackAndWhite.png", 
        System.Drawing.Imaging.ImageFormat.Png);
}

Update

  • 15-Dev-2006
    • V1.0.3.0 Released
      • Added the Fisheye, FloorReflection and Skew filters.
      • Added a pipeline helper class for easy and fluent transformations.
  • 28-Nov-2006
    • Added the ability to use images on the BoxFilter on the top and side panels.
      Check out the samples page for examples.
  • 27-Nov-2006
    • Added a KeepAspectRatio property to the ResizeFilter
  • 23-Nov-2006
    • Added an image watermark filter
    • Changed the license to LGPL

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionerror dat unsafe code may only appear if compiling with /unsafe Pin
gauravSushmita9-Oct-12 3:17
gauravSushmita9-Oct-12 3:17 
GeneralMy vote of 5 Pin
Aamer Alduais10-May-12 9:00
Aamer Alduais10-May-12 9:00 
QuestionI CAN NOT USING THE FILTERS IN VS2008. NET Framework 3.5 Pin
LuizItatiba21-Nov-11 14:47
LuizItatiba21-Nov-11 14:47 
Hello Roy has posted a long time doubts about the use of filters in VisualStudio2005 Yael this site they were working all right but now using them as examples of source code-behind and below them are not recognized in VisualStudio2008,. NET Framework 3.5
I remember the folders where the images are uploaded due to my upload page to be in an administrative folder. They are a level above the upload page that is inside the folder management can see how the code below
I tried several times but without success with the filters back into service in VS2008
You have a solution for me or what I need to correct the code below to work out
I'm in waiting and I thank
SOURCE.ASPX

<pre><%@ Page Language="C#" AutoEventWireup="true" CodeFile="testeuploadnoticias.aspx.cs" Inherits="manager_testeuploadnoticias" ViewStateEncryptionMode="Always" EnableViewStateMac="true" ValidateRequest="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body><asp:Label ID="lblTitulo" runat="server"></asp:Label>
<form id="form1" runat="server">
<div>

<asp:Panel id="panResultado" runat="server" Visible="False">
<hr /> <table class="style1" align="center">
<tr>
<td>
<asp:Label ID="Label2" runat="server" Text="Imagem Original da Noticia:" Visible="false"></asp:Label> <br />
<asp:image id="img1FotoNoticia" runat="server" Visible="false" /> <br /><br />Imagem Postada da Noticia: <br />
<asp:image id="img2FotoNoticia" runat="server" /><br /><br />
</td>
<td>
<td>

</td></td>
</tr>
</table><hr />
</asp:Panel>
Escolha a Foto da Notícia para enviar:<br />
<asp:FileUpload ID="arquivoFotoNoticia" runat="server" /><br />
<asp:Button ID="cmdEnviar" runat="server" Text="Enviar"
onclick="cmdEnviar_Click" />
<br />

<asp:Label ID="lblStatus" runat="server"></asp:Label>

</div>
</form>
</body>
</html>
</pre>

CODE-BEHIND

<pre lang="c#">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ProporcaoVB.WebProdutos.ProporcaoVB;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using ZRLabs.Yael.BasicFilters;
using ZRLabs.Yael.Common;
public partial class manager_testeuploadnoticias : System.Web.UI.Page
{
//Variaveis privadas e publicas para sistema de UPLOAD PROPORCIONAL
//MÓDULO DE NOTÍCIAS COM VARIAS RESOLUÇÕES
private string FolderOriginalNoticias;
private string FolderMiniaturaNoticias1024;
private string FolderGrandesNoticias1024;
private long Width1024 = 400;//EQUIVALENTE A RESOLUCAO WIDTH
private long Height1024 = 400;//EQUIVALENTE A RESOLUVAO HEIGHT
private long Widthpeq1024 = 220;
private long Heightpeq1024 = 220;
//static int maxsize;
public string Ext = "jpg";//TIPO DE EXTENSÃO ACEITA
//METODO DELFILE
static string deletado;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// FolderOriginal = Server.MapPath("~/uploadmatriz/");
// FolderMiniatura = Server.MapPath("~/uploadtransformed/");
FolderOriginalNoticias = "..\\fotosnoticiasmatriz\\";//SEMPRE TERÁ QUE HAVER UMA FOLDER PARA AS FOTOS ORIGINAIS
FolderMiniaturaNoticias1024 = "..\\fotosnoticiasmatriz\\fotosnoticiaspeq1024\\";//FOLDERS MINIATURAS PODERÃO SER GRANDES E PEQUENAS COM AS DEVIDAS ADAPTERS
FolderGrandesNoticias1024 = "..\\fotosnoticiasmatriz\\fotosnoticiasgde1024\\";
//Cria Diretorio
//Directory.CreateDirectory((FolderOriginalNoticias));
//Directory.CreateDirectory((FolderMiniaturaNoticias1024));
//Directory.CreateDirectory((FolderGrandesNoticias1024));
}
}
protected void cmdEnviar_Click(object sender, EventArgs e)
{
//PAREI AQUI - AQUI INICIO DO METODO DE ENVIO DE UPLOAD
// FolderOriginal = Server.MapPath("~/uploadmatriz/");
// FolderMiniatura = Server.MapPath("~/uploadtransformed/");
FolderOriginalNoticias = "..\\fotosnoticiasmatriz\\";//SEMPRE TERÁ QUE HAVER UMA FOLDER PARA AS FOTOS ORIGINAIS
FolderMiniaturaNoticias1024 = "..\\fotosnoticiasmatriz\\fotosnoticiaspeq1024\\";//FOLDERS MINIATURAS PODERÃO SER GRANDES E PEQUENAS COM AS DEVIDAS ADAPTERS
FolderGrandesNoticias1024 = "..\\fotosnoticiasmatriz\\fotosnoticiasgde1024\\";
string NomeArquivoFotoNoticias;
//Faz Upload da Foto
//Pega o nome do Arquivo
NomeArquivoFotoNoticias = arquivoFotoNoticia.PostedFile.FileName.Substring(arquivoFotoNoticia.PostedFile.FileName.LastIndexOf("\\") + 1, arquivoFotoNoticia.PostedFile.FileName.Length - arquivoFotoNoticia.PostedFile.FileName.LastIndexOf("\\") - 1);
// maxsize = 4194304;
NomeArquivoFotoNoticias = NomeArquivoFotoNoticias.ToLower();
#region uploadnoticias
if (arquivoFotoNoticia.HasFile != false) // //Verifica se Arquivo foi Uploadado ou não Retornando True ou False
{
//Método para Recuperar Extensão do Arquivo
int totaldoarquivo;
string extensao;
totaldoarquivo = NomeArquivoFotoNoticias.Length;
totaldoarquivo = totaldoarquivo - 3;
// try
// {
extensao = NomeArquivoFotoNoticias.Remove(0, totaldoarquivo);
//Response.Write(extensao);
//SE ARQUIVO JÁ EXISTE RENOMEIA O ARQUIVO UPLOADADO
#region renomeiarquivosejaexistir
Random rnd = new Random();
string valor = string.Empty;
for (int i = 0; i < 12; i++)
{
if (rnd.Next(0, 2) == 1) // Caso seja 1, sorteia letras
{
valor += Convert.ToChar(rnd.Next(65, 91));
}
else
{
valor += Convert.ToChar(rnd.Next(48, 58));
}
}
valor = valor + DateTime.Now;
valor = valor.Replace(@"/", string.Empty);
valor = valor.Replace(":", string.Empty);
valor = valor.Replace(" ", string.Empty);
NomeArquivoFotoNoticias = NomeArquivoFotoNoticias.Replace("." + Ext, valor + "." + Ext);
#endregion
//try
//{
#region tamanhoarquivo
/// if (arquivoFotoNoticia.PostedFile.ContentLength < maxsize)//Método que verifica se Arquivo é maior que 4096 kbs(4mb)
/// {
//pronto para decisões
//baseado na variavel extensao para comparação
//com a string de entrada ext;
#region Extensao1
if (Ext != null || Ext != string.Empty || Ext != "" || Ext != " ")
{
if (Ext == extensao)
{
try
{
//Aqui criar o nome do arquivo file com algum tipo de replace
//para gerar nomearquivodatahoraournd.ext
//algo parecido com isto
//file = file.Replace("." + ext, Convert.ToString(width) + Convert.ToString(height) + "." + ext);
//ou usar file = nomeupload

arquivoFotoNoticia.PostedFile.SaveAs(Server.MapPath("../fotosnoticiasmatriz/") + NomeArquivoFotoNoticias); //Grava o nome original do Arquivo

}
catch
{
}
//PAREI AQUI EM 20/10/2011
//Verifica E RECUPERA O TAMANHO DA FOTO UPLOADADA
#region verificafotopedeitada
// Cria temporariamnte a imagem
System.Drawing.Image imagemTemp = System.Drawing.Image.FromFile(Server.MapPath("../fotosnoticiasmatriz/") + NomeArquivoFotoNoticias);

// Variáveis contendo o tamanho
int srcWidth = imagemTemp.Width;
int srcHeight = imagemTemp.Height;

Response.Write("Largura:" + srcWidth + "Altura:" + srcHeight);
#endregion
#region decisaofotopedeitada
if (srcWidth > srcHeight)
{
//Inicio Metodo de Filtros
//Filtro AddIn ProporcaoVB

//Gera a miniatura da noticia
//para a resolucao 1024x768 peq
ProporcaoUpload proporcaopeq1024 = new ProporcaoUpload();
proporcaopeq1024.GerarMiniatura(NomeArquivoFotoNoticias, FolderOriginalNoticias, FolderMiniaturaNoticias1024, Widthpeq1024, Heightpeq1024, panResultado, img1FotoNoticia, img2FotoNoticia, lblTitulo, lblStatus);
//AQUI PARA CADA RESOLUÇÃO, CRIAR ROTINA FILTROS OU METODO YAEL Á SEREM USADOS
//Inicio do uso do Filtro
System.Drawing.Image transformed1024;
//Captura o Caminho+Arquivo Carregado
System.Drawing.Image myImg1024 = System.Drawing.Image.FromFile(Server.MapPath("../fotosnoticiasmatriz/fotosnoticiaspeq1024/"+NomeArquivoFotoNoticias+"") );
System.Drawing.Image myImg1024 =
//Utiliza o Filtro Rounded para as fotos pequenas
RoundedCorners rounded = new RoundedCorners();
rounded.BackGroundColor = System.Drawing.ColorTranslator.FromHtml("#FFFFFF");
rounded.CornerRadius = 35;
transformed1024 = rounded.ExecuteFilter(myImg1024);


//para a resolucao 1024x768 gde
ProporcaoUpload proporcaogde1024 = new ProporcaoUpload();
FolderGrandesNoticias1024.Replace(@"//", "/");
proporcaogde1024.GerarMiniatura(NomeArquivoFotoNoticias, FolderOriginalNoticias, FolderGrandesNoticias1024, Width1024, Height1024, panResultado, img1FotoNoticia, img2FotoNoticia, lblTitulo, lblStatus);
//AO FINAL AQUI GRAVAR DADOS BASE DE DADOS
Response.Write(NomeArquivoFotoNoticias);
}
else
{
//lblStatus.Text = "Por favor faça upload apenas de fótos [DEITADAS].Para não enxer sua pasta de fotos.Clique no Botão [DELETAR] para deletar o arquivo " + NomeArquivoFotoNoticias;
HttpContext.Current.Response.Write(@"<script language='javascript'>alert( 'Por favor faça upload apenas de fótos [DEITADAS]!!!' );</script>");

//COLOCAR AQUI MYSQL BD TABLE PARA INSERÇÃO DA FOTO DO ARQUIVOMATRIZ
//E NO INICIO DA PASTA ADMIN OU DESTA CRIAR UM ORDER BY DESC
//PEGANDO O ULTIMO ARQUIVO INSERIDO PARA DELEÇÃO E DELETANDO-O AUTOMATICAMENTE
//COM ROTINA TRY CATCH PARA EVITAR ERRO CASO NÃO HAJA MAIS REGISTROS NO BD

//MÉTODO DE DESTRUIÇÃO DA FOTO ARQUIVO NA PASTA
//DelFile(NomeArquivoFotoNoticias, "../fotosnoticiasmatriz/", lblStatus);

}
#endregion
}

}

#endregion
/// }
#endregion

}
#endregion



}
</pre>

LADEF
QuestionGDI because it gives error in my ASP.NET AJAX ENABLED WEB APPLICATION when using AC # image enhancement filters library published in the WEB Pin
LuizItatiba17-Jan-09 1:57
LuizItatiba17-Jan-09 1:57 
QuestionUsing the FileUpload Control with AC # image enhancement filters library Pin
LuizItatiba16-Jan-09 18:37
LuizItatiba16-Jan-09 18:37 
QuestionDropShadow Pin
adsaero28-Oct-08 5:50
adsaero28-Oct-08 5:50 
AnswerRe: DropShadow Pin
Roiy Zysman31-Oct-08 12:28
Roiy Zysman31-Oct-08 12:28 
Questionhow to use the textWaterMark so that the text is upright? Pin
LuizItatiba15-Oct-08 8:14
LuizItatiba15-Oct-08 8:14 
AnswerRe: how to use the textWaterMark so that the text is upright? Pin
Roiy Zysman15-Oct-08 23:44
Roiy Zysman15-Oct-08 23:44 
GeneralRe: how to use the textWaterMark so that the text is upright? Pin
LuizItatiba16-Oct-08 6:17
LuizItatiba16-Oct-08 6:17 
GeneralFilters are available for online editing at http://www.imgtoys.com Pin
Roiy Zysman14-Oct-08 10:38
Roiy Zysman14-Oct-08 10:38 
QuestionAssigning two lines of Caption Pin
LuizItatiba21-Jul-08 18:51
LuizItatiba21-Jul-08 18:51 
QuestionWhat the Validation component of the examples Pin
LuizItatiba21-Jul-08 9:25
LuizItatiba21-Jul-08 9:25 
QuestionDoubts in relation to the background color of the filter Rounded Corners Filter Pin
LuizItatiba20-Jul-08 19:06
LuizItatiba20-Jul-08 19:06 
AnswerRe: Doubts in relation to the background color of the filter Rounded Corners Filter Pin
Roiy Zysman21-Jul-08 5:30
Roiy Zysman21-Jul-08 5:30 
GeneralRe: Doubts in relation to the background color of the filter Rounded Corners Filter Pin
LuizItatiba21-Jul-08 7:23
LuizItatiba21-Jul-08 7:23 
AnswerRe: Doubts in relation to the background color of the filter Rounded Corners Filter Pin
Roiy Zysman21-Jul-08 8:11
Roiy Zysman21-Jul-08 8:11 
GeneralRe: Doubts in relation to the background color of the filter Rounded Corners Filter Pin
LuizItatiba21-Jul-08 8:31
LuizItatiba21-Jul-08 8:31 
GeneralWorking with Drop Shadow filter in dark pages with funds Pin
LuizItatiba20-Jul-08 13:37
LuizItatiba20-Jul-08 13:37 
QuestionDoubts over its code example Pin
LuizItatiba20-Jul-08 12:46
LuizItatiba20-Jul-08 12:46 
AnswerRe: Doubts over its code example Pin
Roiy Zysman21-Jul-08 5:32
Roiy Zysman21-Jul-08 5:32 
QuestionRe: Doubts over its code example Pin
LuizItatiba21-Jul-08 7:20
LuizItatiba21-Jul-08 7:20 
GeneralI saw your link in Samples of http://www.dotnetclan.com/zrlabs/yael/YaelMain.htm Pin
LuizItatiba18-Jul-08 16:48
LuizItatiba18-Jul-08 16:48 
AnswerRe: I saw your link in Samples of http://www.dotnetclan.com/zrlabs/yael/YaelMain.htm Pin
Roiy Zysman18-Jul-08 23:51
Roiy Zysman18-Jul-08 23:51 
QuestionRe: I saw your link in Samples of http://www.dotnetclan.com/zrlabs/yael/YaelMain.htm Pin
LuizItatiba19-Jul-08 7:04
LuizItatiba19-Jul-08 7:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.