como almacenar correctamente unsigned *char a MSQL (Almacenar una imagen)

Iniciado por pedromigl010, 15 Octubre 2014, 04:24 AM

0 Miembros y 1 Visitante están viendo este tema.

pedromigl010

Buenas, soy nuevo en el foro y necesito ayuda con un problema que he tenido ya desde hace ya un tiempo, el asunto es el siguiente, en el programa que estoy creando decidi almacenar imagenes a la bdd (mysql, si ya se que no lo recomiendan pero igual lo necesito hacer así), estoy trabajando con wxwidgets para que tengan una idea primero mostrare como muestro imagenes en un marco:
______________________________________________________________________

Programa 1.

class MyFrame: public wxFrame
   {
   public:
   MyFrame();
   void OnPaint( wxPaintEvent &event );
   wxBitmap imagen_b;
   unsigned char *arreglo;
   int ancho, largo;
   
   private:
   
   DECLARE_EVENT_TABLE()
   };

MyFrame::MyFrame():wxFrame(NULL,wxID_ANY,"This is the thing")
{
   wxInitAllImageHandlers();
   SetBackgroundColour(* wxWHITE);
   
   wxImage image;
   
   if (!image.LoadFile( _T("Imagen.jpg")))
   wxLogError(wxT("Can't load JPG image"));
   
   /*else
   {
   imagen=wxBitmap(image);
   }*/
   //arreglo=image.GetData();
   
   
   arreglo=(unsigned char *) malloc (image.GetWidth() * image.GetHeight() * 3);
   memcpy (arreglo, image.GetData(), image.GetWidth() * image.GetHeight() * 3);
   ancho=image.GetWidth();
   largo=image.GetHeight();
   
   image.Destroy();
   
   wxImage nueva_imagen(ancho, largo, arreglo);
   imagen_b=wxBitmap(nueva_imagen);
   nueva_imagen.Destroy();
   
   this->Connect(wxEVT_PAINT, wxPaintEventHandler(MyFrame::OnPaint));
   //this->Centre();
   
}

void MyFrame::OnPaint(wxPaintEvent &event)
{
   wxPaintDC dc( this );
   PrepareDC( dc );
   
   //if (imagen.Ok())
   dc.DrawBitmap(imagen_b, 10, 100);
}
____________________________________________________________________


y perfecto aqui todo es una maravilla me muestra la imagen perfectamente en mi marco.

El problema surje cuando necesito almacenar los datos que conforman la imagen en la base de dato en este caso MYSQL, para ser mas especifico el problema se me presenta con el unsigned char *arreglo, les mostrare ahora el codigo pero queriendo almacenar los datos a la bdd:
_____________________________________________________________________

Programa 2.

arreglo=(unsigned char *) malloc (image.GetWidth () * image.GetHeight () * 3);
   memcpy(arreglo, image.GetData(), image.GetWidth() * image.GetHeight() * 3);
   int ancho=image.GetWidth();
   int largo=image.GetHeight();
image.Destroy();

sprintf(consulta, "INSERT INTO imagen VALUES('%hhu', '%d', '%d'),  *(arreglo++), ancho, alto);

if(mysql_query(conn, consulta)==0)
   wxMessageBox("\nDatos incertados con exito\n");
   
   else
   
   wxMessageBox("\nDATOS NO INCERTADOS\n");
___________________________________________________________________

El paso previo inserta correctamente los datos, el problema sucede aca:

Show();
wxInitAllImageHandlers();
MYSQL *conn;
   MYSQL_RES *res;
   MYSQL_ROW row;
   char *server="localhost";
   char *user="root";
   char *password="12345";
   char *base_de_datos="Programa";
   char consulta0[1024];
   conn=mysql_init(NULL);
   int numero_filas;
   
if(!mysql_real_connect(conn, server, user, password, base_de_datos, 3306, NULL, 0))
{
   wxMessageBox("No se pudo establecer Conexion con la base de datos");
   exit(1);
   }
   
   //sprintf(consulta0, "SELECT * FROM imagen");
   
   int ancho, largo;
   char *fa=strdup(factura.c_str());
   char f[100];
   strcpy(f, fa);

sprintf(consulta0, "SELECT * FROM imagen where num_f='%s'", f);
   
if(mysql_query(conn, consulta0)==0)
{
res=mysql_store_result(conn);
numero_filas=mysql_num_rows(res);
   
while((row=mysql_fetch_row(res)))
{
ancho=atoi(row[1]);
largo=atoi(row[2]);
unsigned char* arreglo= reinterpret_cast<unsigned char*>(row[0]);;

wxImage nueva_imagen(ancho, largo,arreglo);
imagen_b=wxBitmap(nueva_imagen);
nueva_imagen.Destroy();
}
}
   mysql_close(conn);
   this->Connect(wxEVT_PAINT, wxPaintEventHandler(VImagenProveedor::OnPaint));
   
}

void VImagenProveedor::OnPaint(wxPaintEvent &WXUNUSED(event)){   
   wxPaintDC dc(this);
   PrepareDC(dc);

   //if (imagen.Ok())
   dc.DrawBitmap(imagen_b, 10, 100);
}
____________________________________________________________________

bien les describire entonces mi problema:

al agregar la variable arreglo al objeto nueva_imagen (wxImage nueva_imagen(ancho, largo,arreglo))

El resultado es que no me muestra la imagen como lo hacia anteriormente en el programa 1, el problema se origina en el inserción de la variable unsigned *char arreglo a la bdd ya que me altera la codificación de la variable y debido a ello me vienen varias preguntas que serian:
1)¿En MYSQL unsigned char* esta representado por un tipo de dato blob, binary, varchar?
2)¿Como se inserta correctamente la variable arreglo a la base de dato, asi:
sprintf("%hhu", *(arreglo++)) como lo tengo en el programa o es %c o %u?
3)he intentado hacer lo siguiente para evitarme problemas:

arreglo=(unsigned char *) malloc (image.GetWidth () * image.GetHeight () * 3);
memcpy(arreglo, image.GetData(), image.GetWidth() * image.GetHeight() * 3);

char* ch=reinterpret_cast<char*>(arreglo);

sprintf(consulta, "INSERT INTO imagen VALUES('%s', '%d', '%d'),  arreglo, ancho, alto);


en este caso es peor ya que ni siquiera se almacenan los datos, en cambio si lo intento con (%c, arreglo) me inserta el valor.

este son las preguntas que me vienen a la mente las cuales me podrian ayudar a resolver este problema que tengo, otro dato para que tengan en cuenta es que intente lo siguiente:

supongase que quiero insertar el valor arreglo pero como un char *.

char* ch=reinterpret_cast<char*>(arreglo);
wxMessagebox(*ch);

y me muestra solamente el caracter especial ÿ (a lo mejor ese el problema que no esta respresentada por valores Assci) yo pensaba que me iba a mostrar un conjunto de caracteres pero solo me muestra ese.

Pero cuando logro insertar la variable arreglo de la siguiente forma:

sprintf(consulta, "INSERT INTO imagen VALUES('%huu'),  *(arreglo++). [(no coloco %s porque no me deja almacenar el dato de esa forma, al  almacenarlo el programa se queda guindado, pero con %huu no sucede eso, el problema que he notado con eso es que solo me toma un caracter)]

y en el siguiente segmento del programa donde quiero tomar la variable almacenada que es:
unsigned char* arreglo= reinterpret_cast<unsigned char*>(row[0]);

en esta parte como dije anteriormente es la que tiene el problema ya que en esta oportunidad no me muestra la imagen.

Entonces como método de prueba quiero mostrar en pantalla el valor de (row[0]) que es la variable almacenada arreglo, pero de la forma por defecto char* ya que MYSQL convierte todo las variables almacenadas a la forma char* así la haya almacenado de la forma %huu, el valor es el siguiente:

wxMessagebox(*row[0]);
me muestra 255.

De esta manera logro corroborar que si hubo una modificación de mi variable inicial ya que
char* ch=reinterpret_cast<char*>(arreglo);
wxMessagebox(*ch); me muestra el caracter especial ÿ

mientras que wxMessagebox(*row[0]); me muestra 255.

Se supone que si quiero mostrar la imagen correspondiente el valor que tomo de la bdd debe ser igual ÿ ni siquiera me esta haciendo eso.

son dudas que espero me ayuden a solucionar les doy gracias de antemano por la ayuda que me puedan ofrecer, ya que este tema me ha costado solucionarlo y así me ayudarían a comprender mas de mysql y c++, ya que como pueden observar tengo muchas dudas con respecto a este tema.

eferion

Edita el código y utiliza las etiquetas GeSHi de C++ para que el código se pueda leer sin dejarnos la vista, por favor.