Imagenes en SQL Server

03/11/2004 - 09:23 por Miguel Ortiz Falcón | Informe spam
Hola grupo, trabajando con imágenes y SQL Server me dí
cuenta de algunas cosas, asi que decidí poner un nuevo
post para exponerlas.

Una columna en SQL Server que ha sido declarada del tipo
Image realmente no puede contener una imagen, no se cual
sea el fundamento de haberla llamado Image, solo puede
contener 16 bytes. Realmente suena ilógico que una imágen
pueda albergarse en ese espacio, quizás allá cosas como
iconos o cosas asi, pero en fin...

Y bueno obviamente la imágen debe almacenarse como un
binario, pero lamentablemente los binarios que tenemos en
SQL Server (binary y varBinary) sus logintudes máximas
son de 8000 bytes. Asi que llegué a la conclusión que si
queremos almacenar una imágen para un registro X solo
puede ser de un tamaño de no más de 8 kb apox. un poco
menos para ser sinceros.

Todo esto me dí cuenta porque aparentementemente cuando
guardaba la imagen cuando todavía mi columna era del tipo
Image segun todo estaba bien lo guardaba (lo que
realmente hacía es solo guardar máximo 16 bytes de mi
imágen)...entonces al tratar de recuperar la imágen (en
bytes) de la bd y lo siguiente: flujo a memoria, bytes al
flujo, e imagen a partir del flujo...siempre me marcaba
un error.

Entonces lo que hice fue primeramente cambiar mi columna
a varBinary, realmente da lo mismo que sea binary, ambos
su tamaño máximo es de 8000b. Para mayor comodidad hice
una clase Serializadora de imágenes y entonces Serializar
la imagen y guardarla en la bd. y para recuperarla
obtener los bytes de la bd y ponerlos en memoria para de
ahí deserializar la imágen y obtenerla de nuevo. Y
funcionó a la perfección, pero nuevamente les repito con
la gran desventaja de que solo pueden almacenarse
imágenes de no más de 8000bytes.

No sé igual y puedan hacerse trucos como guardar los
bytes como cadenas y convertirlas, etc etc...Pero a mi
parecer consumiría mucho tiempo... así que estoy pensando
seríamente utilizar el camino más facil solo almacenar la
ruta y tener las imágenes en una carpeta...

Qué piensan de esto?...algún comentario?

Saludos
Miguel Ortiz Falcón
michaelof@hotmail.com

Preguntas similare

Leer las respuestas

#1 Enrique
03/11/2004 - 12:18 | Informe spam
Hola, yo pude poner imagenes grandes en una base SqlServer en el campo
imagen, el codigo seria asi:

...
MemoryStream stream = new MemoryStream();
imgFoto.Save(stream, ImageFormat.Jpeg); //La variable imgFoto es una
variabla Image que contiene la imagen que queres guardar.
sqlCmd.Parameters.Add("@Foto",stream.GetBuffer()); //sqlCmd es una variable
SqlCommand


Y para leerla:

byte[] _byte = (byte[])sqlDs.Tables[strTabla].Rows[i]["Foto"];
stream = new MemoryStream(_byte);
pbx.Image = Image.FromStream(stream);//pbx es un PictureBox
pbx.SizeMode = PictureBoxSizeMode.StretchImage;
Respuesta Responder a este mensaje
#2 Miguel Ortiz Falcón
03/11/2004 - 16:41 | Informe spam
Hola, probé tu método y no se que pasa, tengo el mismo
código, pero tan parece que no se guarda completa la
imágen, porque al leerla no me muestra la imagen completa
original sino que una parte de ella se muestra nula en
negro...Asumo que es porque pues ahí se acabo la
secuencia de bytes...Lo probé tanto en PNG como en JPG y
ninguno

Saludos
Miguel Ortiz Falcón

Hola, yo pude poner imagenes grandes en una base


SqlServer en el campo
imagen, el codigo seria asi:


MemoryStream stream = new MemoryStream();
imgFoto.Save(stream, ImageFormat.Jpeg); //La variable


imgFoto es una
variabla Image que contiene la imagen que queres guardar.
sqlCmd.Parameters.Add("@Foto",stream.GetBuffer


()); //sqlCmd es una variable
SqlCommand
.

Y para leerla:
.
byte[] _byte = (byte[])sqlDs.Tables[strTabla].Rows[i]


["Foto"];
stream = new MemoryStream(_byte);
pbx.Image = Image.FromStream(stream);//pbx es un


PictureBox
pbx.SizeMode = PictureBoxSizeMode.StretchImage;
.


.

Respuesta Responder a este mensaje
#3 Pedro Luna Montalvo, MVP
03/11/2004 - 16:49 | Informe spam
Una columna en SQL Server que ha sido declarada del tipo
Image realmente no puede contener una imagen, no se cual
sea el fundamento de haberla llamado Image, solo puede
contener 16 bytes. Realmente suena ilógico que una imágen
pueda albergarse en ese espacio, quizás allá cosas como
iconos o cosas asi, pero en fin...





Estas en un error. Lo que se guarda es un puntero de 16 bytes a las paginas
de datos donde se guardan realmente los datos binarios de la imagen.

Segun los libros de ayuda de SQL: El tipo image son "Datos binarios de
longitud variable, desde 0 hasta 231-1 (2.147.483.647) bytes".

Saludos
Pedro Luna, [MVP VB.NET]
Gye, Ecu
Respuesta Responder a este mensaje
#4 Pedro Luna Montalvo, MVP
03/11/2004 - 17:32 | Informe spam
Tengo algunas observaciones acerca de este codigo:

/**************** Lectura ***********************/

// Cargar la imagen recuperada

if (Convert.IsDBNull(ds.Tables[0].Rows[0]["imagen"])) {
// Nunca olvides de verificar si el campo es NULL
imagenLeida = null;
}
else {
byte[] bufferImagen = (byte[]) ds.Tables[0].Rows[0]["imagen"];
MemoryStream buffer = new MemoryStream(imagen);
imagenLeida = new Bitmap(buffer);
}



/**************** Escritura***********************/

// Cargar la imagen recuperada
MemoryStream buffer = new MemoryStream();
imagen.Save(buffer, imagen.RawFormat); // Guarda la imagen en su
formato original

// Especifica el parametro con su tipo de dato como Image
cmd.Parameters.Add("@imagen", SqlDbType.Image);
cmd.Parameters["@imagen"].Value = buffer.GetBuffer();

...

Ciertos formatos, como GIF y PNG, soportan transparencias, que otros
formatos, como JPG no. Si una imagen PNG es guardada en formato JPG, se
realizara una conversion de formato donde como resultado, la imagen perdera
su transparencia y al leerla aparecera diferente, con zonas oscurecidas.

Si quieres que la imagen permanezca igual que como originalmente fue
guardada, guardala en el mismo formato. Si tu preocupacion es el tamaño (y
si no lo es, deberia serlo!), limita el tamaño de las imagenes a transmitir
por codigo. Por ejemplo, yo siempre uso un limite de 32KB para imagenes que
guardo en bases de datos.

Saludos
Pedro Luna, [MVP VB.NET]
Gye, Ecu
Respuesta Responder a este mensaje
#5 Miguel Ortiz Falcón
03/11/2004 - 17:42 | Informe spam
No no no no...que tonto, perdon estaba en mis 5 min de
estupidez, me faltó cambiarle al parámetro a que fuera
del tipo Image =( por eso no la almacenaba completa...

Muchas gracias por la info...

Miguel Ortiz Falcón


Hola, yo pude poner imagenes grandes en una base


SqlServer en el campo
imagen, el codigo seria asi:


MemoryStream stream = new MemoryStream();
imgFoto.Save(stream, ImageFormat.Jpeg); //La variable


imgFoto es una
variabla Image que contiene la imagen que queres guardar.
sqlCmd.Parameters.Add("@Foto",stream.GetBuffer


()); //sqlCmd es una variable
SqlCommand
.

Y para leerla:
.
byte[] _byte = (byte[])sqlDs.Tables[strTabla].Rows[i]


["Foto"];
stream = new MemoryStream(_byte);
pbx.Image = Image.FromStream(stream);//pbx es un


PictureBox
pbx.SizeMode = PictureBoxSizeMode.StretchImage;
.


.

email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida