2011-06-06 7 views
8

Si lo entiendo correctamente, TImage.LoadFromFile determina el tipo de imagen de la extensión del archivo.¿Cómo cargar una imagen arbitraria de una secuencia BLOB en un TImage?

¿Hay alguna forma de detectar el tipo de imagen automáticamente desde un TBlobStream con una imagen cruda en él?

Mi código actual:

procedure LoadImageFromStream(AImage: TImage; ADataSet: TDataSet); 
var 
    Stream: TStream; 
begin 
    Stream := ADataSet.CreateBlobStream(Field, bmRead); 
    try 
    AImage.Picture.Graphic.LoadFromStream(Stream); 
    finally 
    Stream.Free; 
    end; 
end 

Respuesta

16

Consulte este SO answer para recuperar el contenido del archivo del encabezado.

O puede usar nuestro TSynPicture class, que manejará todo tipo de imágenes (bmp/​​gif/tiff/jpg/png) usando la biblioteca Gdi +, en una sola clase. Entonces su TPicture puede ser esta clase única, para cualquier tipo de imagen. Con menos sobrecarga de código que las unidades Jpeg o PNG Delphi.

var Pic: TSynPicture; 

Pic := TSynPicture.Create; 
Pic.LoadFromStream(aStream); // will load bmp/gif/tiff/jpeg/png content 
AImage.Picture.Graphic := Pic; 
.... 
+0

Si desea que TSynPicture cargue imágenes GIF/PNG/JPG/TIFF, comente una definición de NOTSYNPICTUREREGISTER en el código fuente de SynGdiPlus.pas. –

2

De hecho, es TPicture.LoadFromFile que detecta el tipo de archivo, y que sólo se utiliza la extensión de archivo. Por lo tanto, deberá leer el encabezado de la transmisión para detectar el tipo de archivo.

Por otro lado, si conoce el formato cuando coloca el BLOB en la base de datos, siempre puede incluir esa información como su propio encabezado privado en el BLOB.

+2

"leer el encabezado de la corriente" y hay una publicación en el blog de Chris Rolliston que resuelve el problema :) – RBA

0

aparentemente mágica TPicture manejo astuto de los formatos de imágenes arbitrarias en realidad es muy simple (por no decir en bruto). La carga de archivos depende de la extensión del archivo. Cargando desde el portapapeles - en el indicador de formato del portapapeles. ¿Ver? Siempre hay una etiqueta de formato que indica a TPicture qué TGraphicClass usar en los datos, y la clase base TGraphic en sí misma no proporciona ningún mecanismo para identificar flujos de datos "propios" con un enfoque de prueba y error. Uno podría ser curioso cómo TPicture se autocarga de flujo DFM, pero no es una excepción, aquí es extracto relevante de aplicación (código de derechos de autor previsto con fines ilustrativos):

procedure TPicture.ReadData(Stream: TStream); 
var 
    {...} 
    GraphicClass: TGraphicClass; 
    LClassName: string; 
    LBytes: TBytes; 
    LNameLen: Byte; 
begin 
    Stream.Read(LNameLen, 1); 
    SetLength(LBytes, LNameLen); 
    Stream.Read(LBytes{$IFNDEF CLR}[0]{$ENDIF}, LNameLen); 
    LClassName := TEncoding.UTF8.GetString(LBytes); 

    GraphicClass := FileFormats.FindClassName(LClassName); 
+0

... por lo que lee el nombre de clase TPicture correspondiente de la secuencia DFM, en lugar de usar el encabezado binario de Imagen. Así que no puedes mezclar, por ejemplo, bibliotecas de carga Jpeg, o tendrás que nombrar todas las implementaciones 'TJpegImage' (eso es lo que hice para que * SynGdiPlus * sea compatible con la unidad' Jpeg' estándar en el código de usuario y DFM cargando). –

Cuestiones relacionadas