Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   JPG en record... tamaño variable? (https://www.clubdelphi.com/foros/showthread.php?t=44966)

marceloalegre 19-06-2007 15:39:41

JPG en record... tamaño variable?
 
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:
Código Delphi [-]
 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:
Código Delphi [-]
FileData.Read(unFileRecord,sizeof(TFileRecord));
pero esto no me alcanza ahora, porque tengo un dato variable, entonces despues agrego...
Código Delphi [-]
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í:
Código Delphi [-]
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:
Código Delphi [-]
  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...

Código Delphi [-]
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:
Código Delphi [-]
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!!!


La franja horaria es GMT +2. Ahora son las 04:03:13.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi