Split INT color into RGB or ARGB in C# without System.Drawing

by lukiller: 4. March 2012 07:42

Often colors are encoded into byte or int arrays. When using byte arrays, each byte represents a component of the color: Red, Green and Blue. But when using int arrays, the three components are encoded into one int, even an extra byte called alpha (A) that represents the opacity, is also encoded into the same int value. The least significant bit of the array is the blue component, and the most significant bit is Red, or Alpha if present.
Let's make an example, using one known color and it's RGBA components. Color are represented in decimal, binary and hexadecimal notations:

Color DodgerBlue
Component Decimal Binary Hexa
A (alpha) 255 11111111 0xFF
R (red) 30 00011110 0x1E
G (green) 144 10010000 0x90
B (blue) 255 11111111 0xFF

The ARGB int color is encoded like this 11111111 00011110 10010000 11111111, which is the int number 4280193279. When storing this value into an int variable in C#, it may look like a negative number such as -14774017, since int numbers are signed.
Now, to decompose this int number back again into it´s ARGB bytes, you have to use a mask. Since each component is a byte, and a byte can hold values from 0 to 255, you have to use the value 255 as the mask. Sometimes you will find this mask in it's hexadecimal notation 0xFF.

int encoded = -14774017;
byte blue = encoded & 0xff; => 255

When using this mask, you can only extract the least significant bits off the int value, which is the blue component. To get the next color, you will have to move the following component (green) to the least significant position of the int. To accomplish this, the shift right operator (>>) is used, and you have to move eight bits to the right:

byte green = encoded >> 8 & 0xff; => 144

The same for the remaining components:

byte red = encoded >> 16 & 0xff; => 30
byte alpha = encoded >> 24 & 0xff; => 255

Bye:

Tags:

ASP.Net

Utilizando PageMethods con AJAX

by lukiller: 14. March 2010 09:05

Muchas veces se requiere hacer desde el lado cliente llamadas a métodos del lado servidor, sin necesidad de refrescar la página, incluso sin necesidad de disparar eventos. Gracias a AJAX esto es posible, pero con la programación convencional se requiere que un control dispare un evento, por ejemplo que un botón dispare un click, para trapearlo del lado servidor. En ocasiones queremos llamar a métodos del lado servidor sin necesidad de disparar eventos, incluso desde Javascript necesitamos poolear iterativamente alguna función que realice alguna validación contra una base datos, o solamente validar datos iungresados por el usuario. Con los PageMethods podemos disparar un método del lado servidor, directamente desde el código Javascript del lado cliente y obtener el resultado del mismo, e incluso trapear excepciones.
Lo indispensable para que esto funcione, es agregar el atributo EnablePageMethods="true" dentro del ScriptManager. Esto nos habilita un objeto PageMethods en Javascript, el cual contiene una llamada al método del lado servidor con el mismo nombre. Otro requisito es que el método del lado servidor, debe estar decorado con el atributo [WebMethod] y además debe ser obligatoriamente estático (static en C# y shared en VB).

<body onload="$get('TxtNombre').focus();">

<form id="FormDatos" runat="server">

<asp:ScriptManager ID="ScriptManager" runat="server" EnablePageMethods="true" />

Ingresá tu nombre: <input type="text" id="TxtNombre" onblur="Verificar(this.value);" /><span id="Resultado" />

<script language="javascript" type="text/javascript">
function Verificar(nombre) {
    PageMethods.VerificarValor(nombre, OnSucceeded, OnFailed);
}

function OnSucceeded(resultado) {
    $get("Resultado").innerText = resultado;
}

function OnFailed(error) {
    $get("Resultado").innerText = error.get_message();
}
</script>

</form>

</body>

Este es el código del lado aspx, la caja de texto dispara una función Javascript llamada Verificar cuando se pierde el foco (por ejemplo apretando TAB). Desde esta función se llama al método del lado servidor a través de la sentencia "PageMethods.VerificarValor". El método "VerificarValor" recibe un parámetro de tipo texto, y además se le deben agregar los nombres de las dos funciones Javascript que se disparan al retornar desde el servidor al cliente. La función "OnSucceeded" se dispara si anduvo todo bien, y recibe como parámetro el valor devuelto por el método. La función "OnFailed" se dispara si el método del lado servidor dispara una excepción, y recibe como parámetro el objeto "error".

[WebMethod]
public static string VerificarValor(string nombre)
{
    if (string.IsNullOrEmpty(nombre))
    {
        throw new Exception("ERROR: No ingresaste tu nombre.");
    }

    return "Tu nombre comienza con la letra " + nombre[0].ToString().ToUpper();
}

El código del lado servidor es muy sencillo, recuerden referenciar a "System.Web.Services" para que puedan utilizar web methods.

¿Porqué los métodos web deben ser estáticos?
Es una pregunta que a todos nos surgió al implementar PageMethods por primera vez. Esto se debe a que por un lado, tienen un comportamiento similar a los web services, de hecho el ScriptManager los llama de la misma manera que a un web service convencional. Además tienen una eficiencia muy superior a los postbacks de los UpdatePanels, y esto se debe fundamentalmente a que no envían la información del viewstate ni tampoco crean una instancia de la página, con lo cual tampoco pueden acceder directamente a los valores de los controles de la página, ni tampoco ejecutar otros métodos que dependan de la instancia.

Tags: ,

ASP.Net | BLOg

Guardar archivos (blob) en base de datos

by lukiller: 16. January 2010 17:05

El siguiente ejemplo muestra una forma sencilla de almacenar archivos (documentos, imagenes, etc) en una tabla en base de datos. El tipo de datos de SQL Server más recomendado para almacenar archivos es el varbinary. Existe otro tipo que se solía utilizar denominado image, pero ya es obsoleto y posiblemente deje de venir en futuras versiones de SQL.

Primero armamos la tabla y un stored procedure de inserción:

CREATE TABLE [dbo].[Archivos](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Nombre] [varchar](200) NOT NULL,
    [Archivo] [varbinary](max) NOT NULL,
    [Tipo] [varchar](30) NOT NULL,
CONSTRAINT [PK_Archivos] PRIMARY KEY CLUSTERED
(
    [Id] ASC
) ON [PRIMARY]
) ON [PRIMARY]

alter procedure [dbo].[spInsertarArchivo]
    @Nombre as varchar(200),
    @Archivo as varbinary(MAX),
    @Tipo as varchar(30)
as

insert into archivos (nombre, archivo, tipo)
values (@nombre, @archivo, @tipo)

Ahora armamos el aspx con un control FileUpload y un botón:

<div>
Imagen <asp:FileUpload runat="server" ID="FupArchivo" />
<asp:Button runat="server" ID="BtnUpload" Text="Upload" onclick="BtnUpload_Click" />
</div>

Y este es el códgio que hace todo. Lo que hacemos es convertir el stream de entrada que nos provee el control FileUpload, a un array de bytes, que es el tipo soportado para insertar en el campo varbinary:

    protected void BtnUpload_Click(object sender, EventArgs e)
    {
        byte[] archivoBuffer = new byte[FupArchivo.PostedFile.ContentLength];
        FupArchivo.PostedFile.InputStream.Read(archivoBuffer, 0, FupArchivo.PostedFile.ContentLength);
        
        using (SqlConnection cn = new SqlConnection(_cadenaConexion))
        {
            cn.Open();
            SqlCommand cm = new SqlCommand("spInsertarArchivo", cn);
            cm.CommandType = CommandType.StoredProcedure;
            
            cm.Parameters.Add(new SqlParameter("@Nombre", Path.GetFileName(FupArchivo.PostedFile.FileName)));
            cm.Parameters.Add(new SqlParameter("@Tipo", FupArchivo.PostedFile.ContentType));
            
            SqlParameter paramBlob = new SqlParameter("@Archivo", SqlDbType.VarBinary);
            paramBlob.Direction = ParameterDirection.Input;
            paramBlob.Size = FupArchivo.PostedFile.ContentLength;
            paramBlob.Value = archivoBuffer;
            cm.Parameters.Add(paramBlob);
            
            cm.ExecuteNonQuery();
        }
    }

En el próximo post voy a armar un ejemplo de como obtener un archivo ya guardado en base de datos, para mostrarlo en una página web.

Tags:

ASP.Net

Generar imagen Captcha con Generic Handler

by lukiller: 3. December 2009 09:40

El siguiente código sirve para generar una imagen Captcha desde un Generic Handler. Es bastante sencillo, se crea un objeto Bitmap y se escribe un texto en el y se envìa hacia el browser mediante Response. También le agregué unos círculos de fondo a modo de ejemplo para engañar a los reconocedores automáticos de captchas. Así como los círculos se pueden agregar cualquier tipo de dibujos o imagenes. La forma de invocar al captcha es desde un objeto IMG de HTML.

using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;

namespace Captcha
{
    public class GetCaptcha : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            MemoryStream mem = new System.IO.MemoryStream();
            Bitmap bmp = CrearCaptcha("8765ABC1", 80, 25); //Generar el código aleatoriamente.
            bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg);
            context.Response.ContentType = "image/jpeg";
            mem.WriteTo(context.Response.OutputStream);
            bmp.Dispose();
        }

        private Bitmap CrearCaptcha(string code, int ancho, int altura)
        {
            Bitmap bmp = new Bitmap(ancho, altura);
            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            SolidBrush relleno = new SolidBrush(Color.DeepSkyBlue);
            g.FillRectangle(relleno, 0, 0, ancho, altura);

            Pen pen = new Pen(Color.Yellow, 2);
            g.DrawArc(pen, 10, 5, 20, 10, 0, 360);
            g.DrawArc(pen, 40, 10, 20, 10, 0, 360);

            relleno = new SolidBrush(Color.Navy);
            fuente = new span("arial", 11, spanStyle.Bold, GraphicsUnit.Point);
            g.DrawString(code, fuente, relleno, 2, 2);

            return bmp;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Invocación desde el archivo ASPX:

<img src="GetCaptcha.ashx" alt="Captcha code" />

Pueden mejorarlo utilizando otros tipos de fuentes, también obteniendo los códigos desde un diccionario prearmado y/o cambiando los colores a gusto. Así queda mostrado en un browser: 

Tags: , ,

ASP.Net

about lukiller

Me la paso programando y aprendiendo nuevas tecnologías. En mi tiempo libre me dedico a trabajar...

RecentPosts

Powered by BlogEngine.NET 1.5.0.7 - Eco Theme by n3o Web Designers