PDA

Ver la Versión Completa : JPG en record... tamaño variable?


marceloalegre
19-06-2007, 15:39:41
Buenos días amigos,
Me encuentro hoy con la siguiente cuestión:
resulta que tengo que leer de un memorystream que contiene datos varios entre ellos un archivo jpg de tamaño variable.

este es mi registro:

TFileRecord = packed record
Dato1: Cardinal;
Dato2: SmallInt;
Dato3: Byte; //datos varios....
PhotoSize: Cardinal; //largo en bytes de la foto...
//Photo: Este campo es variable que me gustaria tener???!!!
end;


normalmente yo leo de la siguiente manera:

FileData.Read(unFileRecord,sizeof(TFileRecord));

pero esto no me alcanza ahora, porque tengo un dato variable, entonces despues agrego...

FileData.Read(photoBuffer, unFileRecord.PhotoSize); //no se de que tipo sera el photobuffer!

ahora ya he leido la foto (como aclare no se que tipo seria este photobuffer :) )...

Ahora bien, existe algun tipo de datos para que pueda trabajar con el registro en forma directa (creo que para los bmp hay un tipo de datos tbitmap si no me equivoco... pero esto es jpg...) mi idea es no hacer ese read de ser posible (el porque? tengo clases armadas en las que paso el registro en forma directa para ser procesado y bueno me genera varias modificaciones...), y tener todo encapsulado en un registro donde Photo sea de algun tipo jpg o algo asi... no se si esto esta inventado o no queda otra que leerlo "artesanalmente"..

Espero se entienda mi pregunta!... Muchas gracias

seoane
19-06-2007, 16:06:25
Creo que la forma en la que lo estas haciendo es correcta. Primero lees un record, con un tamaño conocido, y una vez obtienes el tamaño de la imagen que viene a continuación lees la imagen. Es el mismo método que yo mismo usaría.

Lo que no entiendo muy bien es donde esta problema, aunque añadieras un campo mas (TBitmap o TJPEGImage) este solo seria un puntero a ese objeto, tu tendrías que crear el objeto y leer la imagen desde el fichero. Yo creo que deberías de ir un poco mas allá y empezar a utilizar clases (objetos) en vez de records para manejar estas estructuras un poco complicadas.

Por último, y si mi consejo de utilizar objetos no te convence, utiliza un record con un tamaño variable, gracias al milagro de los punteros. Declara un record tal que así:

TFileRecord = packed record
Dato1: Cardinal;
Dato2: SmallInt;
Dato3: Byte; //datos varios....
PhotoSize: Cardinal; //largo en bytes de la foto...
Photo: array[0..0] of Byte;
end;


Y un puneto como este:

PFileRecord = ^TFileRecord;


Ahora solo tienes que leer los primeros campos como hacias antes, obtener el tamaño de la imagen, reservar tanta memoria como necesites para guardar los campos y la imagen, y guardar en ella los campos y la imagen. Ahora a través de los campos del puntero tendrás acceso a todos los campos del record y a los datos de la imagen.

Perdona que no te ponga código, pero ando un poco ocupado. :(

marceloalegre
19-06-2007, 17:15:38
Oks!, a ver... en cuanto al tema de la clase... es factible implementar algo como esto? (perdon, no se si estaremos bien, si es lo que me querias decir...)

Veamos...


unit uClaseTest;
interface
uses classes,jpeg;

type
TFileRecord = packed record
Dato1: Cardinal;
Dato2: SmallInt;
Dato3: Byte; //datos varios....
PhotoSize: Cardinal; //largo en bytes de la foto...
//Photo ... no puedo :)
end;

TFileClass = class (TObject)
public
Dato1: Cardinal;
Dato2: SmallInt;
Dato3: Byte; //datos varios....
PhotoSize: Cardinal; //largo en bytes de la foto...
Photo: TJPEGImage;
constructor create(FileRecord:TFileRecord;StreamData:TmemoryStream);
end;

implementation
uses DateUtils, uUtil;
{ TDeposit }
constructor TFileClass.create(FileRecord:TFileRecord;StreamData:TmemoryStream);
begin
inherited create;
Dato1:=FileRecord.Dato1;
Dato2:=FileRecord.Dato2;
Dato3:=FileRecord.Dato3;
PhotoSize:=FileRecord.PhotoSize;
Photo:= TJPEGImage.Create;
Photo.LoadFromStream(StreamData);
end;
end.


Con esto, si es que funciona podria cargar la foto dentro de la clase llamandola así, desde el metodo que recorro el memorystream:

var
unFileClassData:TFileClass;
unFileRecord:TFileRecord;
StreamData:TMemoryStream;
begin
//Imaginemos que estoy dentro del while recorriendo el Memorystream..
StreamData.Read(unFileRecord,sizeof(TFileRecord));
unFileClassData:=TFileClassData.create(unFileRecord,StreamData);//Le paso el registro, y el memorystream para que extraiga la foto al hacer el create...


Bueno... no se si alcanzo a explicarme de acuerdo a lo que me dices domingo...

Fijate que te parece, sin apuros, y cuando puedas!!(logicamente todos estamos ocupados en nuestras cuestiones ...!), me gustaria ver ese "poco de codigo" que siempre aportas :D donde las cosas quedan totalmente claras.

Saludos!!!