Si bien no comparto la idea de guardar imagenes en MySql, parece ser un problema algo frecuente, asi que hagamoslo!
Lo primero y mas obvio que haremos, es crear una nueva base de datos en MySql.
La mia se llama "test"
Creamos una tabla, en mi caso la llamare "imagenes"
y tiene 2 columnas, "Nombre" para obtener la imagen asociada a su nombre, e "Image" que mantendra la imagen
"Nombre" lo guardo como "TinyText"
"Image" lo guardo como "MediumBlob"
como en la imagen
Ahora dividiremos el Codigo en partes para hacerlo mas entendible
const string
MySqlConnecionString = "Server=localhost;
Database=test; Username=root; Password=XXXX;";
Ahora creamos un metodo, el cual nos regresara una conexion a MySql ya abierta.
static
MySqlConnection GetNewConnection()
{
var
conn = new MySqlConnection(MySqlConnecionString);
conn.Open();
return conn;
}
Teniendo ya todo listo en cuanto a conexion MySql, vamos con lo importante
El metodo que use para guardar y cargar las images es a travez de arrays de bytes (byte[]), ya que pueden ser manipulados facilmente por las clases que heredan "Stream" y ademas porque las clases de Imagenes soportan el cambio de stream a image y vice-versa.
No comentare el codigo porque no es nada del otro mundo, gracias a que C# tambien es muy intuitivo
Guardar una imagen:
static void GuardarImagen(Image
imagen, string Nombre)
{
using
(MemoryStream ms = new
MemoryStream())
{
imagen.Save(ms, ImageFormat.Gif);
byte[]
imgArr = ms.ToArray();
using
(MySqlConnection conn = GetNewConnection())
{
using
(MySqlCommand cmd = new
MySqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO imagenes(Nombre, Image) VALUES
(@Nombre, @imgArr)";
cmd.Parameters.AddWithValue("@Nombre", Nombre);
cmd.Parameters.AddWithValue("@imgArr",
imgArr);
cmd.ExecuteNonQuery();
}
}
}
}
lo unico que hicimos fue crear una conexion a MySql, crear un MemoryStream, usar Image.Save(Stream, Formato), convertir el stream a byte[] y guardarlo en MySql.
El formato lo pueden cambiar de gif al que quieran, yo simplemente lo use porque
hasta donde se, ocupan menor espacio, pero no lo he comprobado en este tipo de
casos.
Ahora vamos con el como cargar una Imagen:
static Image CargarImagen(string
Nombre)
{
using
(MySqlConnection conn = GetNewConnection())
{
using
(MySqlCommand cmd = new
MySqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT Image FROM imagenes WHERE Nombre =
@nombre";
cmd.Parameters.AddWithValue("@nombre", Nombre);
byte[] imgArr
= (byte[])cmd.ExecuteScalar();
imgArr = (byte[])cmd.ExecuteScalar();
using
(var stream = new
MemoryStream(imgArr))
{
Image img = Image.FromStream(stream);
return img;
}
}
}
}
Aqui lo que hicimo, fue crear una conexion, hacer EXACTAMENTE EL MISMO COMANDO
QUE PARA CUALQUIER SITUACION, solo que usamos ExecuteScalar() que nos devuelve
el objeto en ese lugar en vez de un MySqlDataReader, y convertirlo a byte[]
explicitamente, luego creamos un stream envolviendo el byte[], y usamos
Image.FromStream(stream);
El codigo que nos queda es bastante portable.
ejemplo si quieres cargar una imagen de MySql a un pictureBox, usamos
nombrePictureBox.Image = CargarImagen("prueba");
Como dije al comienzo, no me gusta esta manera, MySql tiene una mejor escalabilidad,
pero es un poco mas lento que un archivo, por lo que en mi opinion personal, digo
que seria conveniente guardar la imagen en un archivo comun y corriente, y en la
base de datos, en vez de guardar el archivo en si, guardar la ubicacion de la imagen.
Suerte con sus proyectos! :)
Muy bueno tu código, me ha servido mucho, pero tengo una duda, ya comprobe que tu codigo guarda GIF animados, ¿Cómo puedo sacarlos GIF animados de la BD?, cada vez que lo intento me manda error.
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarMuchisimas Gracias Brother, me fue super util esta informacion, aunque si me costo muchisimo que funcionara a mi porque tenia que validar que no fuera null (tanto en GuardarImagen como en CargarImagen), pero si pude, muchas gracias brother (y)
ResponderEliminarMe ayudas
EliminarEsta muy bien lo unico que necesitaria saber es el create table del mysql gracias :)
ResponderEliminarOla muy bueno tu codigo , sabes necesito ayuda necesito guardar una imagen en Mysql pero no de un windows form si no de WPF podrias ayudarme :) porfavor
ResponderEliminarcomo desplazarse con el enter
ResponderEliminarprivate void Textbox1_KeyPress(object sender, KeyPressEventArgs e)
Eliminar{
if((int)e.KeyChar == (int)Keys.Enter)
{
//aqui codigo
}
}
Amigo, hola. una consulta, la imagen la seleccionas de un openfiledialog????
ResponderEliminarHola Amigo
ResponderEliminar¿Como puedo contactarte?
si puedes dejarme tu Correro o tu Gmail para estar en contacto,
te dejo mi correo fer_olea@hotmail.com
Gmail fer.karen1@gmail.com
Facebook fer.olea
contactarme xfavor
Buenas uso tu codigo pero No guarda la imagen, NO marca Error
ResponderEliminarResolví el error es en @imgArr se debe poner asi ?imgArr
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarEste comentario ha sido eliminado por el autor.
Eliminarhola, tengo un problema similar y no he podido solucionar la cosa es que no me quiere guardar bien el archivo en un campo tipo blob en la base de datos, tengo el siguiente código:
ResponderEliminareste es el método guardar, mi problema esta en la parte de asignar los bytes, no me guarda el numero correcto de bytes que tiene el archivo y no he podido entender el porque; solamente guarda algo como System.byte[]
protected void GUARDAR(object sender, EventArgs e)
{
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
string contentype = FileUpload1.PostedFile.ContentType;
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
byte[] bytes = br.ReadBytes(Convert.ToInt32(fs.Length));
string sql = "insert into TABLE1 values(11, '" + filename + "','" + contentype + "',utl_raw.cast_to_raw('" + bytes + "'))";
string info = IngresarBD(sql);
TextBox3.Text = info;
}
La parte de la conexión a la base de datos y lo demás están bien, si alguien me puede ayudar con esto les agradecería mucho