Pregunta

Tengo que cargar una imagen desde un archivo XML. No hay información en el archivo XML sobre si la imagen es JPG / GIF / BMP. Después de cargar la imagen, lo que necesito para convertirlo en mapa de bits.

¿Alguien tiene alguna idea de cómo convertir imágenes de mapa de bits sin conocer el formato de archivo actual? Estoy usando Delphi 2007/2009

Gracias.

¿Fue útil?

Solución 2

He encontrado una manera más sencilla! Se carga etc. archivos JPG / GIF / BMP automáticamente sin siquiera saber / comprobar el formato de archivo, y convertir esa consecuencia. A mí me funcionó perfectamente.

Intercambio aquí:)

Uses
Classes, ExtCtrls, Graphics, axCtrls;

Procedure TForm1.Button1Click(Sender: TObject);
Var
     OleGraphic               : TOleGraphic;
     fs                       : TFileStream;
     Source                   : TImage;
     BMP                      : TBitmap;
Begin
     Try
          OleGraphic := TOleGraphic.Create; {The magic class!}

          fs := TFileStream.Create('c:\testjpg.dat', fmOpenRead Or fmSharedenyNone);
          OleGraphic.LoadFromStream(fs);

          Source := Timage.Create(Nil);
          Source.Picture.Assign(OleGraphic);

          BMP := TBitmap.Create; {Converting to Bitmap}
          bmp.Width := Source.Picture.Width;
          bmp.Height := source.Picture.Height;
          bmp.Canvas.Draw(0, 0, source.Picture.Graphic);

          image1.Picture.Bitmap := bmp; {Show the bitmap on form}
     Finally
          fs.Free;
          OleGraphic.Free;
          Source.Free;
          bmp.Free;
     End;
End;

Otros consejos

Delphi 2009 viene con soporte incorporado para JPEG, BMP, GIF y PNG.

En versiones anteriores de Delphi que pueda necesitar para encontrar las implementaciones de terceros para PNG y GIF, pero en Delphi 2009 sólo tiene que añadir las unidades Jpeg, pngimage y GIFImg a su cláusula de usos.

Si el archivo tiene una extensión puede utilizar el código siguiente, según lo observado por otros el TPicture.LoadFromFile mira a las extensiones registradas por las clases heredadas para determinar qué imagen se cargue.

uses
  Graphics, Jpeg, pngimage, GIFImg;

procedure TForm1.Button1Click(Sender: TObject);
var
  Picture: TPicture;
  Bitmap: TBitmap;
begin
  Picture := TPicture.Create;
  try
    Picture.LoadFromFile('C:\imagedata.dat');
    Bitmap := TBitmap.Create;
    try
      Bitmap.Width := Picture.Width;
      Bitmap.Height := Picture.Height;
      Bitmap.Canvas.Draw(0, 0, Picture.Graphic);
      Bitmap.SaveToFile('C:\test.bmp');
    finally
      Bitmap.Free;
    end;
  finally
    Picture.Free;
  end;
end;

Si la extensión del archivo no se conoce un método consiste en mirar a los primeros bytes para determinar el tipo de imagen.

procedure DetectImage(const InputFileName: string; BM: TBitmap);
var
  FS: TFileStream;
  FirstBytes: AnsiString;
  Graphic: TGraphic;
begin
  Graphic := nil;
  FS := TFileStream.Create(InputFileName, fmOpenRead);
  try
    SetLength(FirstBytes, 8);
    FS.Read(FirstBytes[1], 8);
    if Copy(FirstBytes, 1, 2) = 'BM' then
    begin
      Graphic := TBitmap.Create;
    end else
    if FirstBytes = #137'PNG'#13#10#26#10 then
    begin
      Graphic := TPngImage.Create;
    end else
    if Copy(FirstBytes, 1, 3) =  'GIF' then
    begin
      Graphic := TGIFImage.Create;
    end else
    if Copy(FirstBytes, 1, 2) = #$FF#$D8 then
    begin
      Graphic := TJPEGImage.Create;
    end;
    if Assigned(Graphic) then
    begin
      try
        FS.Seek(0, soFromBeginning);
        Graphic.LoadFromStream(FS);
        BM.Assign(Graphic);
      except
      end;
      Graphic.Free;
    end;
  finally
    FS.Free;
  end;
end;

No se puede utilizar TPicture.LoadFromFile si usted no sabe qué formato al gráfico tiene, ya que este método utiliza la extensión de archivo para determinar cuál de los formatos gráficos registrados necesita ser cargado. Hay una razón por la que no existe un método TPicture.LoadFromStream juego.

Una biblioteca externa que puede examinar los datos y determinar el formato gráfico en tiempo de ejecución sería la mejor solución. Se podría utilizar el efg página como punto de partida de su investigación .

Una solución rápida y sucia es tratar los pocos formatos que usted necesita para manejar hasta que uno tiene éxito:

function TryLoadPicture(const AFileName: string; APicture: TPicture): boolean;
const
  GraphicClasses: array[0..3] of TGraphicClass = (
    TBitmap, TJPEGImage, TGIFImage, TPngImage);
var
  FileStr, MemStr: TStream;
  ClassIndex: integer;
  Graphic: TGraphic;
begin
  Assert(APicture <> nil);
  FileStr := TFileStream.Create('D:\Temp\img.dat', fmOpenRead);
  try
    MemStr := TMemoryStream.Create;
    try
      MemStr.CopyFrom(FileStr, FileStr.Size);
      // try various
      for ClassIndex := Low(GraphicClasses) to High(GraphicClasses) do begin
        Graphic := GraphicClasses[ClassIndex].Create;
        try
          try
            MemStr.Seek(0, soFromBeginning);
            Graphic.LoadFromStream(MemStr);
            APicture.Assign(Graphic);
            Result := TRUE;
            exit;
          except
          end;
        finally
          Graphic.Free;
        end;
      end;
    finally
      MemStr.Free;
    end;
  finally
    FileStr.Free;
  end;
  Result := FALSE;
end;

Editar

El GraphicEx biblioteca tiene un ejemplo Convertir que los usos

GraphicClass := FileFormatList.GraphicFromContent(...);

para determinar el formato gráfico. Esto parece muy similar a la forma de hacer esto VB6 que lo mencionas. Tal vez usted puede utilizar esta biblioteca para su propósito.

No tengo Delphi 2007 o 2009 para ver si esto va a funcionar en cualquiera de esas versiones. Sin embargo, en XE2, hay otra clase de Vcl.Graphics llamada TWICImage capaz de manejar imágenes soportados por el Microsoft Imaging Component , que incluye BMP, GIF, ICO, JPEG, PNG, TIF y Windows Media Photo . Es capaz de detectar el tipo de imagen de una corriente. Asumiendo que tiene un TImage en el formulario llamado Image1

procedure LoadImageFromStream(Stream: TStream; Image: TImage);
var
  wic: TWICImage;
begin
  Stream.Position := 0;
  wic := TWICImage.Create;
  try
    wic.LoadFromStream(Stream);
    Image.Picture.Assign(wic);
  finally
    wic.Free;
  end;
end;

procedure RenderImage(const Filename: string);
var
  fs: TFileStream;
begin
  fs := TFileStream.Create(Filename, fmOpenRead);
  try
    LoadImageFromStream(fs, Image1);
  finally
    fs.Free;
  end;
end;

Funciona sin añadir PNGImage, GIFImg o JPEG a su declaración uses.

Las otras respuestas muestran cómo convertir la TImage a una BMP, así que no estoy incluyendo aquí. Sólo estoy mostrando otra forma de cargar varios tipos de gráficos en un TImage sin conocer de antemano el tipo de imagen, o la extensión del archivo ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top