Excelente Video... con un estupendo final
lunes, 26 de mayo de 2008
viernes, 18 de abril de 2008
Niño Matemático predice el fin del mundo el 13 de Abril del 2036

Segun la NASA, aproximadamente en el 2036, asteroide Apophis (Dios Egipcio de la Destrucción) pasará cerca de la tierra, casi a unos 32500 km, un distancia menor a la que hay entre nuestro planeta y la luna. Eso ocasionaría que a su paso impactará contra una enorme cantidad de satélites artificiales orbitandonos. Esto podría ocasionar el desvió de su trayectoria.

Ilustración del dios Apophis...
Si bien nos va, lo alejarían de nosotros. Si mal nos va, lo mandarían directamente a la tierra. Pero supongamos que el asteroide Apophis pasará sin hacernos daño. Siete años después, cuando le de la vuelta al sol, regresaría muy cerca de nosotros. La NASA calculó 2 entre 100,000 la probalidad de que nos impactará.
Pues el chaval, Nico Marquardt, desde el observatorio Instituto de Astrofísica de Postdam, calculó que en realidad las posibilidades son de 2 entre 1000, cien veces menor que la NASA. Esto significaría que en el 2029 el Apophis pasará muy cerca de la tierra, y 7 años despues podría impactarnos de lleno, matando millones de personas, lanzando un Tsunami devastador y cubriendo la tierra de una gruesa capa de polvo que no dejaría pasar la luz del sol en años... el resto ya se lo imaginan.
La NASA acepto su error, y reconoció los resultados de Nico como correctos. Esperemos que para ese tiempo Nico Marquardt pueda, con sus calculos matemáticos, encontrar una manera de salvarnos... si no tendremos que revivir a Bruce Willis para que vaya al asteroide y lo haga explotar otra vez.
miércoles, 19 de marzo de 2008
Gadgets Religiosos...la tecnología al servicio de la fé
Me encuentro con que la tecnología no esta peleada con la religión, como tal vez algunos pensarán. Al contrario, la iglesia católica ha demostrado muchas veces que es posible usarla para llevar la fe a cualquier parte del mundo... como el internet, tv de alta definición, entre otros.
Pero los siguientes gadgets son muy originales, listos para ser usados tanto en el ámbito religioso como para alguien que se sienta atraído por esta singular moda.

Con este singular gadget, podrás llevar este hermoso libre en formato digital a cualquier parte. Solo introducelo en un puerto USB y podrás leer cualquier pasaje.

Es un rosario que tiene sus propios auriculares y al conectarse con tu iPod, copiara en el el rosario todas las oraciones y misterios... ahora no hay excusa de que no me lo se.

Un singular Reproductor MP3 en forma de Cruz de 1 Gb de capacidad, minipantalla LED y controles para su cómodo manejo.

Dock para tu ipod schuffle, con el cual controlaras la reproducción de tu música.

Que no es posible casar en cualquier parte ya no es pretexto con esta iglesia inflable, lista para ser montada en un salón de fiestas, casa, jardín, etc. Cuenta con su propio organo.

Memoria USB de 1 Gb de capacidad, cuyo imagen se iluminará al conectarse al equipo y cuando escribas información en ella.
Este post es creado sin el áfan de molestar a nadie, sin importar la fe que profesen. Con información de http://multimedia.eluniversal.com.mx/fotogaleria.html
Pero los siguientes gadgets son muy originales, listos para ser usados tanto en el ámbito religioso como para alguien que se sienta atraído por esta singular moda.
Una Biblia USB

Con este singular gadget, podrás llevar este hermoso libre en formato digital a cualquier parte. Solo introducelo en un puerto USB y podrás leer cualquier pasaje.
iRosario

Es un rosario que tiene sus propios auriculares y al conectarse con tu iPod, copiara en el el rosario todas las oraciones y misterios... ahora no hay excusa de que no me lo se.
Cruz MP3

Un singular Reproductor MP3 en forma de Cruz de 1 Gb de capacidad, minipantalla LED y controles para su cómodo manejo.
iBelieve

Dock para tu ipod schuffle, con el cual controlaras la reproducción de tu música.
Iglesia Portátil

Que no es posible casar en cualquier parte ya no es pretexto con esta iglesia inflable, lista para ser montada en un salón de fiestas, casa, jardín, etc. Cuenta con su propio organo.
Virgen USB

Memoria USB de 1 Gb de capacidad, cuyo imagen se iluminará al conectarse al equipo y cuando escribas información en ella.
Este post es creado sin el áfan de molestar a nadie, sin importar la fe que profesen. Con información de http://multimedia.eluniversal.com.mx/fotogaleria.html
jueves, 13 de marzo de 2008
Simbolos Mayor que > y Menor que < en Ubuntu
Busque y busque en la Web alguna ayuda acerca de como sacar los simbolos de Mayor que ">" y Menor que "<" en Ubuntu, pero nadie no encontre. Solo algunas burlas acerca de por que mi teclado no las traía... a razón de que era teclado de Laptop adaptado a EUA, es decir, la distribución de las teclas estaba en Ingles. Como rádico en México me era importante obtener esos símbolos.
En windows los obtenía mediante código ASCII, por que igual no era posible de la forma normal en un teclado de escritorio. Pero en Ubuntu no encontraba nada... ni siquiera en combinación de teclas.
Pero un día, jugando con las teclas salío:
En windows los obtenía mediante código ASCII, por que igual no era posible de la forma normal en un teclado de escritorio. Pero en Ubuntu no encontraba nada... ni siquiera en combinación de teclas.
Pero un día, jugando con las teclas salío:
< = Alt + Shift + z
> = Alt + Shift + x
> = Alt + Shift + x
Esto en idioma español latinoamericano. Espero que alguien le sirva esto.
viernes, 7 de marzo de 2008
Historia de una tabla autoreferenciada
Corrian los tiempos en que diseñaba una Base de Datos para un sistemita. La idea era una tabla que almacenará un catálogo de servicios con una descripción, un precio, etc. Al principio, no representaba mucho reto... era relativamente fácil la creación y edición de esta para después realizar las altas, bajas, consultas y modificaciones.
Pero sucedió lo que a muchos desarrolladores les tiene que pasar algún día. Los requerimientos cambiarón... y una sola tabla no sería suficiente. Ahora era necesario catálogar esos mismos servicios, y tal vez lo primero que viene a la cabeza es crear una tabla mas con los catálogos y relacionarlos con la tabla de servicios.
Sin embargo, en el caso de este desarrollador que se había dormido en sus clases de Base de Datos en los temas de Joins, SelfJoins, RigthJoins, etc., era algo que le complicaba su trabajo..., tener que crear esa clase de consultas SQL me ponía en un aprieto.
Tenía que encontrar una manera de resolver el problema sin complicar el acceso a los datos, sobre todo pensando a futuro que las consultas SQL podrían tardarse mucho en ejecutarse debido a la enorme cantidad de datos que algún día manejaría.
Así que, al método de prueba y error, se modificó el diseño de la tabla agregando dos columnas mas:

La columna TIPO y TIPO_RELACION resolvía mi problema. La idea era que cuando se agregará un cátalogo, este tendría automáticamente en su campo TIPO las letras CT que lo identifican como catálogo y en el campo TIPO_RELACION la letra T (o cualquier otra, incluso sin letra) concatenandole el ID del registro, que mas adelante sería utilizado.

Agregado el catálogo, ahora era posible agregar un servicio que pertenecierá a ese catálogo, relacionado por el campo TIPO_RELACION. La imágen muestra el registro 13, donde se agregó un catálogo, con TIPO CT y TIPO_RELACION C13. Posteriormente, agregando mediante el sistema un servicio, este pertenece al catálogo anterior, colocando en su campo TIPO C13. De esta manera "apuntamos" el servicio a directamente con el catálogo que lo contendrá. Cabe mencionar que el campo TIPO_RELACION se quedo vació ya que este servicio no contendrá a nadie mas.

Fue así como conseguí, de pura casualidad una tabla autoreferenciada... o eso me lo dijo un cuate... e investigando me di cuenta que es algo muy útil, pero pocas veces utilizadas en las Bases de Datos. Analizando este método nos dimos cuenta que no solo se aplica en un solo nivel, si no que incluso se presta perfectamente para mas niveles de jerarquía, como por ejemplo, clasificar los catálogos, en otro catálogo, o incluso los servicios, podrían contener en su interior mas servicios y variantes... y a su vez estos. Un estilo de árbol jerarquíco cuya implementación es mas barata que utilizar un sin fín de tablas y relacionarlas todas entre ellas.
Al final, las tablas autoreferenciadas me han funcionando muy bien, sin ninguna clase de problemas hasta la fecha.
Pero sucedió lo que a muchos desarrolladores les tiene que pasar algún día. Los requerimientos cambiarón... y una sola tabla no sería suficiente. Ahora era necesario catálogar esos mismos servicios, y tal vez lo primero que viene a la cabeza es crear una tabla mas con los catálogos y relacionarlos con la tabla de servicios.
Sin embargo, en el caso de este desarrollador que se había dormido en sus clases de Base de Datos en los temas de Joins, SelfJoins, RigthJoins, etc., era algo que le complicaba su trabajo..., tener que crear esa clase de consultas SQL me ponía en un aprieto.
Tenía que encontrar una manera de resolver el problema sin complicar el acceso a los datos, sobre todo pensando a futuro que las consultas SQL podrían tardarse mucho en ejecutarse debido a la enorme cantidad de datos que algún día manejaría.
Así que, al método de prueba y error, se modificó el diseño de la tabla agregando dos columnas mas:

La columna TIPO y TIPO_RELACION resolvía mi problema. La idea era que cuando se agregará un cátalogo, este tendría automáticamente en su campo TIPO las letras CT que lo identifican como catálogo y en el campo TIPO_RELACION la letra T (o cualquier otra, incluso sin letra) concatenandole el ID del registro, que mas adelante sería utilizado.

Agregado el catálogo, ahora era posible agregar un servicio que pertenecierá a ese catálogo, relacionado por el campo TIPO_RELACION. La imágen muestra el registro 13, donde se agregó un catálogo, con TIPO CT y TIPO_RELACION C13. Posteriormente, agregando mediante el sistema un servicio, este pertenece al catálogo anterior, colocando en su campo TIPO C13. De esta manera "apuntamos" el servicio a directamente con el catálogo que lo contendrá. Cabe mencionar que el campo TIPO_RELACION se quedo vació ya que este servicio no contendrá a nadie mas.

Fue así como conseguí, de pura casualidad una tabla autoreferenciada... o eso me lo dijo un cuate... e investigando me di cuenta que es algo muy útil, pero pocas veces utilizadas en las Bases de Datos. Analizando este método nos dimos cuenta que no solo se aplica en un solo nivel, si no que incluso se presta perfectamente para mas niveles de jerarquía, como por ejemplo, clasificar los catálogos, en otro catálogo, o incluso los servicios, podrían contener en su interior mas servicios y variantes... y a su vez estos. Un estilo de árbol jerarquíco cuya implementación es mas barata que utilizar un sin fín de tablas y relacionarlas todas entre ellas.
Al final, las tablas autoreferenciadas me han funcionando muy bien, sin ninguna clase de problemas hasta la fecha.
jueves, 6 de marzo de 2008
Conectando PostgreSQL con Java
En este mini tutorial intentaré explicar la manera en conectar nuestra aplicación hecha en JAVA con la Base de Datos de PostgreSQL.
Primero, es necesario descargarse el JDBC Driver para PostgreSQL. Este se encuentra en la página http://jdbc.postgresql.org/index.html Obviamente, será necesario contar con nuestra Base de Datos funcionando para realizar las consultas necesarias.
Posteriormente hay que determinar la manera de agregar este Driver a nuestro proyecto. NetBeans ofrece una manera mas que sencilla.
Conociendo la ubicación de nuestro Driver y con el proyecto abierto, en el Panel de Proyectos, ubicamos en el Árbol de Proyecto la opción Libraries, clic Derecho en ella y seleccionamos Add JAR / Folder..., de esta manera estaremos
agregando ej .JAR del Driver que descargamos. Esto nos crea en nuestro proyecto una carpeta llamada "dist" y en ella otra de nombre "lib" donde esta nuestro Driver.
Ahora, teniendo lo necesario, podemos probar nuestra conexión con PostgreSQL y realizar lo que nos concierne, Altas, Bajas y Modificaciones a nuestras tablas.
Para empezar, debemos de importar lo siguiente:
import java.sql.*;
Cabe mencionar que hay una gran diferencia entre Select y Update, Insert o Delete, ya que no se aplican de igual manera. A continuación muestro el proceso para realizar un Select (en idioma geek, vamos a selectear)
public class Main{
public static void main(String[] args){
/*Variable para almacenar la URL de conexión a nuestra Base de Datos, si esta estuviera en otra máquina, necesitariamos estar registrados en ella y contar con su IP*/
String url = "jdbc:postgresql://localhost/moo";
try{
//Acceso al Driver
Class.forName("org.postgresql.Driver");
//La conexión con los parámetros necesarios
Connection con = DriverManager.getConnection( url,"postgres","postgres");
//Abrimos la conexión y la iniciamos
Statement stmt = con.createStatement();
/*Un ResultSet es como en .NET un DataSet, un arreglo temporal donde se almacenará el resultado de la consulta SQL*/
ResultSet rs;
//Una variable String para almacenar la sentencia SQL
String query = "select id as ID from moo.usuarios";
//En el ResultSet guardamos el resultado de ejecutar la consulta
rs = stmt.executeQuery(query);
//En un ciclo while recorremos cada fila del resultado de nuestro Select
while ( rs.next()){
/*Aqui practicamente podemos hacer lo que deseemos con el resultado, en mi caso solo lo mande a imprimir*/
System.out.println(rs.getString("ID") + "\t" + rs.getString("ID"));
}
//Cerramos la conexión
stmt.execute("END");
stmt.close();
con.close();
}
catch( Exception e ){
//Por si ocurre un error
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Para realizar todo aquello diferente a un Select, utilzaremos lo siguiente:
/*Variable para almacenar la URL de conexión a nuestra Base de Datos, si esta estuviera en otra máquina, necesitariamos estar registrados en ella y contar con su IP*/
String url = "jdbc:postgresql://localhost/moo";
try{
//Acceso al Driver
Class.forName("org.postgresql.Driver");
//La conexión con los parámetros necesarios
Connection con = DriverManager.getConnection( url,"postgres","postgres");
//Abrimos la conexión y la iniciamos
Statement stmt = con.createStatement();
//Una variable String para almacenar la sentencia SQL
String query = "update moo.usuarios set nombre = 'Mauricio' where id = '1'";
//Ejecutamos la consulta SQL
stmt.executeQuery(query);
//Cerramos la conexión
stmt.execute("END");
stmt.close();
con.close();
}
catch( Exception e ){
//Por si ocurre un error
System.out.println(e.getMessage());
e.printStackTrace();
}
Es muy importante tener en cuenta que si este método lo utilizas en una función para hacerla llamar cuando lo necesites, y quieras enviarle tanto argumentos como retornar resultados, en la función de Select las líneas siguientes NO deben de estar presentes:
stmt.execute("END");
stmt.close();
Y en la parte de Update, Insert o Delete, solo la siguiente línea:
stmt.execute("END");
Espero que sea útil esta información.
Primero, es necesario descargarse el JDBC Driver para PostgreSQL. Este se encuentra en la página http://jdbc.postgresql.org/index.html Obviamente, será necesario contar con nuestra Base de Datos funcionando para realizar las consultas necesarias.
Posteriormente hay que determinar la manera de agregar este Driver a nuestro proyecto. NetBeans ofrece una manera mas que sencilla.
Conociendo la ubicación de nuestro Driver y con el proyecto abierto, en el Panel de Proyectos, ubicamos en el Árbol de Proyecto la opción Libraries, clic Derecho en ella y seleccionamos Add JAR / Folder..., de esta manera estaremos
agregando ej .JAR del Driver que descargamos. Esto nos crea en nuestro proyecto una carpeta llamada "dist" y en ella otra de nombre "lib" donde esta nuestro Driver.
Ahora, teniendo lo necesario, podemos probar nuestra conexión con PostgreSQL y realizar lo que nos concierne, Altas, Bajas y Modificaciones a nuestras tablas.
Para empezar, debemos de importar lo siguiente:
import java.sql.*;
Cabe mencionar que hay una gran diferencia entre Select y Update, Insert o Delete, ya que no se aplican de igual manera. A continuación muestro el proceso para realizar un Select (en idioma geek, vamos a selectear)
public class Main{
public static void main(String[] args){
/*Variable para almacenar la URL de conexión a nuestra Base de Datos, si esta estuviera en otra máquina, necesitariamos estar registrados en ella y contar con su IP*/
String url = "jdbc:postgresql://localhost/moo";
try{
//Acceso al Driver
Class.forName("org.postgresql.Driver");
//La conexión con los parámetros necesarios
Connection con = DriverManager.getConnection( url,"postgres","postgres");
//Abrimos la conexión y la iniciamos
Statement stmt = con.createStatement();
/*Un ResultSet es como en .NET un DataSet, un arreglo temporal donde se almacenará el resultado de la consulta SQL*/
ResultSet rs;
//Una variable String para almacenar la sentencia SQL
String query = "select id as ID from moo.usuarios";
//En el ResultSet guardamos el resultado de ejecutar la consulta
rs = stmt.executeQuery(query);
//En un ciclo while recorremos cada fila del resultado de nuestro Select
while ( rs.next()){
/*Aqui practicamente podemos hacer lo que deseemos con el resultado, en mi caso solo lo mande a imprimir*/
System.out.println(rs.getString("ID") + "\t" + rs.getString("ID"));
}
//Cerramos la conexión
stmt.execute("END");
stmt.close();
con.close();
}
catch( Exception e ){
//Por si ocurre un error
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Para realizar todo aquello diferente a un Select, utilzaremos lo siguiente:
/*Variable para almacenar la URL de conexión a nuestra Base de Datos, si esta estuviera en otra máquina, necesitariamos estar registrados en ella y contar con su IP*/
String url = "jdbc:postgresql://localhost/moo";
try{
//Acceso al Driver
Class.forName("org.postgresql.Driver");
//La conexión con los parámetros necesarios
Connection con = DriverManager.getConnection( url,"postgres","postgres");
//Abrimos la conexión y la iniciamos
Statement stmt = con.createStatement();
//Una variable String para almacenar la sentencia SQL
String query = "update moo.usuarios set nombre = 'Mauricio' where id = '1'";
//Ejecutamos la consulta SQL
stmt.executeQuery(query);
//Cerramos la conexión
stmt.execute("END");
stmt.close();
con.close();
}
catch( Exception e ){
//Por si ocurre un error
System.out.println(e.getMessage());
e.printStackTrace();
}
Es muy importante tener en cuenta que si este método lo utilizas en una función para hacerla llamar cuando lo necesites, y quieras enviarle tanto argumentos como retornar resultados, en la función de Select las líneas siguientes NO deben de estar presentes:
stmt.execute("END");
stmt.close();
Y en la parte de Update, Insert o Delete, solo la siguiente línea:
stmt.execute("END");
Espero que sea útil esta información.
viernes, 22 de febrero de 2008
Subir imágenes al Servidor y Guardarlas en tu Base de Datos
Llega el momento de cualquier desarrollador Web... en la que tiene la necesidad de dar la oportunidad al cliente de subir imagenes al Servidor, tal vez su foto, avatar, etc. Así mismo, aquel que trabaje con Bases de Datos tambien buscará la oportunidad de guardar archivos de imágen en una tabla, para no tener problemas al momento de respaldar y no cargar con todos los archivos.
En el siguiente Post se presenta la forma básica de hacer estas dos cosas, utilizando .NET y C# aunque facilmente puede ser aplicado en cualquier lenguaje o BD.
En primer lugar, necesitamos agregar a nuestro código las siguientes referencias:
using System.IO;
using System.Text;
using System.Drawing;
Posteriormente, necesitamos el control FileUpload, el clásico cuadro de texto y botón para seleccionar la ruta del archivo que se desea.
El procedimiento se divide en dos partes, subir la imagen al servidor y codificarla para su almacenamiento en la Base de Datos. Esta codificación se realizará en Base64, lista para almacenarse en un campo tipo texto.
Iniciemos con el evento de un botón para subir la imagen:
protected void bt_agregar_Click(object sender, EventArgs e)
{
//Variable que almacenará el nombre de la imagen
string imagen = "";
//Determinamos si se tiene un archivo que subir, una vez ya seleccionado.
if (this.FileUpload1.HasFile)
{
//Se separa la extensión del nombre del archivo para validarla
string[] nomExt = this.FileUpload1.FileName.Split('.');
string tipoFile = nomExt[nomExt.Length - 1];
//Revisamos si el archivo cuenta con una extension valida, pudiendo agregar o quitar.
if ((tipoFile == "jpg") || (tipoFile == "png"))
{
/*Si se cuenta con la extensión válida, procedemos a guardarla en el Servidor. FileUpload1.SaveAs solicita una cadena de texto con la ruta y el nombre del archivo. Server.MapPath("~/") determina la ruta de nuestra aplicación en el servidor. Si deseamos, le concatenamos otra carpeta, previamente creada*/
this.FileUpload1.SaveAs(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
//Guardamos el nombre de la imagen
imagen = this.FileUpload1.FileName;
//Obtenemos su tamaño en bytes una vez que esta ya en el servidor
System.IO.FileInfo info_img = new System.IO.FileInfo(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
//Lo convertimos a double y calculamos su peso en KB.
double b_img = Convert.ToDouble(info_img.Length);
//Limitamos el peso del archivo
if (b_img <= (512*1024))
{
/*Si el tamaño es válido, codificamos la imagen en Base64, un previo antes de guardarla en la base de datos. Esto se hace mediante la funcion CodificarFoto. Le enviaremos a la funcion la ruta completa de la imagen en el Servidor. Nos retornara una variable con la imagen ya codificada en Base64*/
string img_bin = CodificarFoto(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
/*Guardamos la informacion en la Base de Datos. La variable img_bin contiene la imagen, pero codificada en texto, lista para almacenarse en un campo de tipos Texto o String de la Base de Datos. En esta parte puedes utilizar el método que desees para guardarla*/
//Si lo deseamos, borramos del servidor la imagen, una vez que ya esta en la BD
File.Delete(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
}
}
}
}
}//Fin del evento del boton
Ahora veamos la función para Codificar la Foto
public string CodificarFoto(string sNombreArchivo)
{
//Variable para almacenar la imagen codificada
string sBase64 = "";
//Utilizamos un FileStream para acceder a la imagen en el Servidor
FileStream fs = new FileStream(sNombreArchivo, FileMode.OpenOrCreate, FileAccess.Read);
//Utilizamos un BinaryReader para pasar los datos de la imagen a un arreglo de bytes
BinaryReader br = new BinaryReader(fs);
byte[] bytes = new byte[(int)fs.Length];
br.Read(bytes, 0, bytes.Length);
En el siguiente Post se presenta la forma básica de hacer estas dos cosas, utilizando .NET y C# aunque facilmente puede ser aplicado en cualquier lenguaje o BD.
En primer lugar, necesitamos agregar a nuestro código las siguientes referencias:
using System.IO;
using System.Text;
using System.Drawing;
Posteriormente, necesitamos el control FileUpload, el clásico cuadro de texto y botón para seleccionar la ruta del archivo que se desea.
El procedimiento se divide en dos partes, subir la imagen al servidor y codificarla para su almacenamiento en la Base de Datos. Esta codificación se realizará en Base64, lista para almacenarse en un campo tipo texto.
Iniciemos con el evento de un botón para subir la imagen:
protected void bt_agregar_Click(object sender, EventArgs e)
{
//Variable que almacenará el nombre de la imagen
string imagen = "";
//Determinamos si se tiene un archivo que subir, una vez ya seleccionado.
if (this.FileUpload1.HasFile)
{
//Se separa la extensión del nombre del archivo para validarla
string[] nomExt = this.FileUpload1.FileName.Split('.');
string tipoFile = nomExt[nomExt.Length - 1];
//Revisamos si el archivo cuenta con una extension valida, pudiendo agregar o quitar.
if ((tipoFile == "jpg") || (tipoFile == "png"))
{
/*Si se cuenta con la extensión válida, procedemos a guardarla en el Servidor. FileUpload1.SaveAs solicita una cadena de texto con la ruta y el nombre del archivo.
this.FileUpload1.SaveAs(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
//Guardamos el nombre de la imagen
imagen = this.FileUpload1.FileName;
//Obtenemos su tamaño en bytes una vez que esta ya en el servidor
System.IO.FileInfo info_img = new System.IO.FileInfo(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
//Lo convertimos a double y calculamos su peso en KB.
double b_img = Convert.ToDouble(info_img.Length);
//Limitamos el peso del archivo
if (b_img <= (512*1024))
{
/*Si el tamaño es válido, codificamos la imagen en Base64, un previo antes de guardarla en la base de datos. Esto se hace mediante la funcion CodificarFoto. Le enviaremos a la funcion la ruta completa de la imagen en el Servidor. Nos retornara una variable con la imagen ya codificada en Base64*/
string img_bin = CodificarFoto(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
/*Guardamos la informacion en la Base de Datos. La variable img_bin contiene la imagen, pero codificada en texto, lista para almacenarse en un campo de tipos Texto o String de la Base de Datos. En esta parte puedes utilizar el método que desees para guardarla*/
//Si lo deseamos, borramos del servidor la imagen, una vez que ya esta en la BD
File.Delete(Server.MapPath("~/") + "//moo//" + this.FileUpload1.FileName);
}
}
}
}
}//Fin del evento del boton
Ahora veamos la función para Codificar la Foto
public string CodificarFoto(string sNombreArchivo)
{
//Variable para almacenar la imagen codificada
string sBase64 = "";
//Utilizamos un FileStream para acceder a la imagen en el Servidor
FileStream fs = new FileStream(sNombreArchivo, FileMode.OpenOrCreate, FileAccess.Read);
//Utilizamos un BinaryReader para pasar los datos de la imagen a un arreglo de bytes
byte[] bytes = new byte[(int)fs.Length];
br.Read(bytes, 0, bytes.Length);
//Guardamos el arreglo de bytes
sBase64 = Convert.ToBase64String(bytes);
//Retornamos la variable
return sBase64;
//Se libera memoria
fs.Close();
fs = null;
br = null;
bytes = null;
}
Por ultimo les dejo el código para descodificar la imagen. Se entiende que ya se habrá leido la Base de Datos y recuperado la cadena (imagen codificada)
private void DecodificarFoto(string sBase64, string nombre_file)
{
/*Guardamos en una cadena la ruta de la imagen donde se descodificará. Es decir, despues de este proceso, estara guardada en el disco duro del servidor*/
string sImagenTemporal = Server.MapPath("~/") + "moo//" + nombre_file;
//Utilizamos un FileStream para crear un nuevo archivo temporal
FileStream fs = new FileStream(sImagenTemporal, FileMode.CreateNew, FileAccess.Write);
Por ultimo les dejo el código para descodificar la imagen. Se entiende que ya se habrá leido la Base de Datos y recuperado la cadena (imagen codificada)
private void DecodificarFoto(string sBase64, string nombre_file)
{
/*Guardamos en una cadena la ruta de la imagen donde se descodificará. Es decir, despues de este proceso, estara guardada en el disco duro del servidor*/
string sImagenTemporal = Server.MapPath("~/") + "moo//" + nombre_file;
//Utilizamos un FileStream para crear un nuevo archivo temporal
//Un BinaryWriter para escribir la imagen descodificada
BinaryWriter bw = new BinaryWriter(fs);
//Un arreglo de Bytes para descodificar la imagen
byte[] bytes;
bytes = Convert.FromBase64String(sBase64);
//Escribimos la imagen
bw.Write(bytes);
//Liberamos memoria
fs.Close();
bytes = null;
bw = null;
sBase64 = null;
}
Suscribirse a:
Entradas (Atom)