MS Access guarda las imagenes en campos de tipo objeto OLE. La informacion que guarda es el stream del archivo .bmp con una cabecera que contiene la aplicacion con la que tiene que abrir el stream. El stream entero es inservible para trabajar directamente con freepascal/Lazarus asi que lo que viene a continuacion es una manera de usar ese objeto OLE para incrustarlo en un Dbf y poder trabajar mas agilmente en Lazarus.
A continuacion vamos a mostrar distintos contenidos de streams para entender que vamos haciendo.
Archivo BMP :
Como se puede ver "BM" marca el inicio del stream.
Archivo BMP incrustado en un campo de tipo objeto OLE de MS Access :
Aqui se puede observar la cabecera que comentabamos antes.
Archivo BMP incrutado en un campo de tipo BLOB en un Dbf :
Observamos que la cabecera se reduce en comparacion al objeto OLE.
Para conseguir nuestro objetivo lo primero que tenemos que hacer es determinar la posicion del "BM" para poder extraer la informacion que nos interesa, para este fin usamos la siguiente funcion:
[sourcecode language='delphi']
function buscaPosicionBM(STmp : TStream) : Integer;
var
i : Integer;
begin
STmp.Seek(0,0);
for i:=0 to 100 do
begin
if STmp.ReadByte = 66 then
if STmp.ReadByte = 77 then
buscaPosicionBM:=STmp.Position-2;
end;
end;
[/sourcecode]
Y a continuacion toda la chicha, o sea, cargamos el objeto OLE en un stream, le quitamos la informacion innecesaria para nosotros y lo metemos en un campo blob de un Dbf.
[sourcecode language='delphi']
procedure carga;
var
Stream, StreamClean : TStream;
FieldStr : String;
PFieldStr : PChar;
posicion : Integer;
begin
// Cargamos el objeto OLE al Stream
Stream := TMemoryStream.Create;
Stream := q.CreateBlobStream(q.FieldByName('DIBUJO'), bmRead);
// Conseguimos la posicion del "BM"
posicion :=buscaPosicionBM(Stream);
// Creamos el stream para añadir despues al Dbf
StreamClean := TMemoryStream.Create;
// Añadimos la cabecera para el Dbf
StreamClean.WriteByte(3);
StreamClean.WriteByte(0);
StreamClean.WriteByte(0);
StreamClean.WriteByte(0);
StreamClean.WriteByte(98);
StreamClean.WriteByte(109);
StreamClean.WriteByte(112);
// Nos posicionamos correctamente y copiamos la informacion necesaria
Stream.Seek(posicion, soFromBeginning);
StreamClean.Position:=7;
StreamClean.CopyFrom(Stream,Stream.Size - posicion);
StreamClean.Seek(0,0);
SetLength(FieldStr, StreamClean.Size);
PFieldStr := PChar(FieldStr);
StreamClean.Read(PFieldStr^, StreamClean.Size);
// Volcamos el Stream creado al Dbf
reportDbf.Append;
reportDbf.FieldByName('Codigo').Assign(q.FieldByName('Codigo'));
reportDbf.FieldByName('descripcion').Assign(q.FieldByName('descripcion'));
reportDbf.FieldByName('dibujo').Value := FieldStr;
reportDbf.Post;
// Liberamos recursos
Stream.Free;
archivoLog.Free;
end;
[/sourcecode]
Comentar que q es un TSQLQuery de SQLdb, reportDbf es un TDbf y he usado el programa Hexplorer para ver los entresijos de los streams.
Si algo no ha quedado muy claro me dejais un comentario e intentare explicarme lo mejor que pueda O:)
Caregorias
Tags
- bitmap
- bmp
- freepascal
- lazarus
- ms-access
zurcarev (not verified) Wed, 01/21/2009 - 00:59
Hola.
He estado probando lo anterior y no me funciona, supongo que será al intentarlo en linux+lazarus+bd.mdd, pues según parece el unixodbc no tiene todavia soporte para mdb :-(.
Si estoy equivocado, necesito descubrir algo más, la solución pasa por pasar los datos de .mdb a .sql. jejejej.
saludos y gracias.
p.d. ¿tendrías algún ejemplo?
javivf Wed, 01/21/2009 - 21:23
unixODBC tiene un driver que soporta MS Access aunque es de pago, te dejan bajarte un Trial pero yo no lo he usado nunca. Desde linux puedes usar mdbtools o un plugin para kexi para importar la informacion y manejarla con otro SGBD
Suerte!
javivf Fri, 01/09/2009 - 10:04
Hola,
Tienes que usar el componente TODBCConnection del paquete SQLdb. En el atributo .Params del TODBConnection tienes que poner lo siguiente :
Driver=Microsoft Access Driver (*.mdb)
Dbq=\\path\donde\este\la\basededatos.mdb
Uid=Admin
Pwd=
Y deberia funcionar :)
zurcarev (not verified) Fri, 01/09/2009 - 00:22
Hola.
¿puedes abrir bases de datos .mdb ( msaccess ) con lazarus?. Bueno lo intente y no me salío, ¿me puedes dar algunos consejos para realizarlo?.
Gracias.
Fredycc (not verified) Tue, 12/29/2009 - 03:22
Muy interesante tu artículo, me ayudo mucho para incorporar una estructura de datos en memoria donde manejo un array de Streams blobs con firebird y Lazarus, sigue así; Gracias por el aporte ;)
Conectar Lazarus con Access
Vincent (not verified) Fri, 08/21/2015 - 23:26
Hola, podrias por favor publicar un tutorial de como conectar Lazarus a una Base de Datos de Ms Access. Gracias
Add new comment