PDA

Ver la Versión Completa : Guardar Imagenes zeoslib+lazarus


keine1lust
08-04-2014, 16:48:32
Buen dia tengo un pequeño problema para guardar imágenes a la base de datos, eh vistos muchos ejemplos y temas relacionados con dicho asunto pero veo que funciona bien pero en usando delphi.

yo estoy programando un registro de personas en el cual debo guardar una foto que almaceno en un TImage aparte de guardar los datos esa persona lo quiero que se guarde junto con la imagen pero solo consigo error seguí este ejemplo que me brinda una guía básica de zeoslib:

Var TheStream : TMemoryStream;
Begin
TheStream := TMemoryStream.Create;
Try
Image1.Picture.Bitmap.Savetostream(TheStream);
With qryBlobInsert do
Begin
Sql.Text := 'INSERT INTO EVENTS (EventNo,EVENT_PHOTO) VALUES (100,:ThePicture)';
Params.Clear;
Params.CreateParam(ftBlob,'ThePicture', ptInput);
ParamByName('ThePicture').LoadfromStream(TheStream,ftBlob);
ExecSQL;
End;
Finally
TheStream.Free;
End;
End;

pero en lazarus no reconoce ftBlob y ptInput

mi forma de conectarme a una base de datos es llamando a una clase de conexión a base de datos

eh probado otros ejemplos donde solo se guarda la imagen y en realidad no me han funcionado. Si me guiar o recomendarme alguna guía que leer estaría muy agradecido que tengan buen dia

keine1lust
08-04-2014, 17:13:00
Buenas la solución es que se debe incluir en la unidad db y con eso el ejemplo anterior funciona perfecto y para mi parecer es bastante sencilla disculpen las molestias si alguien tiene duda me escriben y le puedo compartir el codigo

ecfisa
09-04-2014, 03:16:13
...
si alguien tiene duda me escriben y le puedo compartir el codigo
Hola keine1lust.

Podes compartirlo en este mismo hilo o mejor aún como aporte en un nuevo mensaje. Con seguridad tendrá mas alcance y los agradecidos seran muchos ;)

Saludos :)

keine1lust
09-04-2014, 15:27:37
1.
declarar el uso de unidad DB y componente Zeos
unit freg_per;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons,
StdCtrls, MaskEdit,ExtCtrls, ExtDlgs,conexionesbd, ZDataset,DB;

es importante declarar la unidad DB ya que el contiene las constantes para el manejo de varibles tipo blob ejemplo: ftBlob, ptInput si no la declaran el compilador no reconocerá dichas variables

2. este codigo es el que te da la guia de zeoslib:

Var TheStream : TMemoryStream;
Begin
TheStream := TMemoryStream.Create;
Try
Image1.Picture.Bitmap.Savetostream(TheStream);
With qryBlobInsert do
Begin
Sql.Text := 'INSERT INTO EVENTS (EventNo,EVENT_PHOTO) VALUES (100,:ThePicture)';
Params.Clear;
Params.CreateParam(ftBlob,'ThePicture', ptInput);
ParamByName('ThePicture').LoadfromStream(TheStream,ftBlob);
ExecSQL;
End;
Finally
TheStream.Free;
End;
End;

en mi caso lo adapte a lo que necesitaba:

TheStream := TMemoryStream.Create;
Try
Image1.Picture.Jpeg.Savetostream(TheStream);

conexiodb.Conectar_Mysql; //llamo a la base de datos para conectarme
sqlejecuta:=TZQuery.Create(nil);//creo un nuevo objeto

With sqlejecuta do
Begin
Connection:= Conexion;
Sql.Text:='INSERT INTO personal(cedula,nom_comp,direccion,telf_movil,'+
'tlf_local,cargo,foto,departamento_iddepart,'+
'parametro_idparametro,'+
'tip_empleado_idtip_emp,id_user) '+
'VALUES('+mcedula+','+ mnom_comp+','+mdireccion+
','+mtelf_movil+','+ mtlf_local+','+mcargo+',:foto'+
','+middepart+','+midparametro+','+midtip_emp+
','+QuotedStr(tid_user)+')';
Params.Clear;
Params.CreateParam(ftBlob,'foto', ptInput);
ParamByName('foto').LoadfromStream(TheStream,ftBlob);
ExecSQL;
End;
Finally
TheStream.Free;
End;

MessageDlg('Registro almacenado con exito',mtInformation,[mbOK], 0);

end
Conexion.Disconnect;

de igual forma como hice el insert lo adapto para hacer update

hice una pequeña combinación ya que por el momento tengo que investigar mas sobre el uso de Params

si alguien me puede sugerir como optimizar el código o que sea mas presentable para otros programadores se los agradecería

Casimiro Notevi
09-04-2014, 16:29:22
^\||/^\||/^\||/

ecfisa
09-04-2014, 17:10:30
Hola keine1lust.

Primero que nada te agradezco que hayas compartido tu código ^\||/

Siempre que sea posible, es aconsejable el uso de parámetros, entonces mi sugerencia es: Tratar de parametrizar todas las inserciones.

No he usado los componentes Zeos, aunque tengo entendido que son similares a los IBX, basándome en eso, con un TIBQuery lo haría de este modo:

var
MS: TMemoryStream;
begin
...
with sqlejecuta do
begin
Connection:= Conexion;
Close;
SQL.Clear;
SQL.Add('INSERT INTO PERSONAL(CEDULA,NOM_COMP,DIRECCION,TELF_MOVIL,');
SQL.Add('TLF_LOCAL,CARGO,FOTO,DEPARTAMENTO_IDDEPART,');
SQL.Add('PARAMETRO_IDPARAMETRO,TIP_EMPLEADO_IDTIP_EMP,ID_USER)');
SQL.Add('VALUES(:CEDULA,:NOM_COMP,:DIRECC,:MOVIL,:FIJO,:CARGO,');
SQL.Add(':FOTO,:DEPTO_ID,:PARAM_ID,:TIP_EMPL,:USER_ID)');
ParamByName('CEDULA').AsString:= mcedula;
ParamByName('NOM_COMP').AsString:= mnom_comp;
ParamByName('DIRECC').AsString:= mdireccion;
ParamByName('MOVIL').AsString:= mtelf_movil;
ParamByName('FIJO').AsString:= mtlf_local;
ParamByName('CARGO').AsString:= mcargo;
ParamByName('DEPTO_ID').AsString:= middepart;
ParamByName('PARAM_ID').AsString:= midparametro;
ParamByName('TIP_EMPL').AsString:= midtip_emp;
ParamByName('USER_ID').AsString:= tid_user;
MS:= TMemoryStream.Create;
try
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:= 0;
ParamByName('FOTO').LoadFromStream(MS, ftBlob);
finally
MS.Free;
end;
ExecSQL;
...

De este modo funciona correctamente (con IBX), ojalá sea igual para Zeos y la sugerencia te resulte útil.

Saludos :)

Casimiro Notevi
09-04-2014, 17:35:33
^\||/^\||/^\||/^\||/^\||/^\||/

keine1lust
09-04-2014, 18:14:04
Var MS : TMemoryStream;

begin

conexiodb.Conectar_Mysql;
sqlejecuta:=TZQuery.Create(nil);

with sqlejecuta do
begin
Connection:= Conexion;
Close;
SQL.Clear;
SQL.Add('INSERT INTO PERSONAL(CEDULA,NOM_COMP,DIRECCION,TELF_MOVIL,');
SQL.Add('TLF_LOCAL,CARGO,FOTO,DEPARTAMENTO_IDDEPART,');
SQL.Add('PARAMETRO_IDPARAMETRO,TIP_EMPLEADO_IDTIP_EMP,ID_USER)');
SQL.Add('VALUES(:CEDULA,:NOM_COMP,:DIRECC,:MOVIL,:FIJO,:CARGO,');
SQL.Add(':FOTO,:DEPTO_ID,:PARAM_ID,:TIP_EMPL,:USER_ID)');
ParamByName('CEDULA').AsString:= Trim(trif.Text);
ParamByName('NOM_COMP').AsString:= Trim(tnom_per.Text);
ParamByName('DIRECC').AsString:= Trim(mdir.Text);
ParamByName('MOVIL').AsString:= Trim(tmovil.Text);
ParamByName('FIJO').AsString:= Trim(tntlf.Text);
ParamByName('CARGO').AsString:= Trim(tnom_cargo.Text);
ParamByName('DEPTO_ID').AsInteger := middepart;
ParamByName('PARAM_ID').AsInteger:= midparametro;
ParamByName('TIP_EMPL').AsInteger:= midtip_emp;
ParamByName('USER_ID').AsString:= tid_user;
MS:= TMemoryStream.Create;
try
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:= 0;
ParamByName('FOTO').LoadFromStream(MS, ftBlob);
finally
MS.Free;
end;
try
ExecSQL;
MessageDlg('Registro Almacenado con exito',mtInformation,[mbOK], 0);
exit;
except
on E: Exception do
begin
//showmessage('Problemas con query ['+text+']');
MessageDlg('Problemas de conexion con la base de datos',mtWarning,[mbOK], 0);
exit;
end;
end;

end;


Muchas gracias ecfisa ^\||/^\||/funciona perfecto ya solo agregue otra excepcion a ExecSQL; y antes con Parametros no me funcionaba era por esta linea: Params.CreateParam(ftBlob,'foto', ptInput); como escribi anteriormente tengo que leer mas sobre el uso de parámetros de nuevo muchas Gracias estoy haciendo esto para tratar pasar un sistema hecho en vfp a pascal ya me falta los reportes que actualmente los estoy haciendo en fortesreport4lazarus claro ya poco a poco haré un código mas limpio