Search code examples
delphimemoryzipjpegdelphi-xe2

Extracting images from zip into memory delphi


I'm wanting to extract a zip file loaded with images into memory in some way. I don't really care what type of stream they go into, as long as I can load them afterwards. I do not have that great of an understanding with streams, and explanations on the subject don't seem to go into much detail.

Essentially, what I am doing now is extracting the files to (getcurrentdir + '\temp\'). This works, but isn't quite what I am wanting to do. I would be more happy to have the jpg's end up in memory and then be able to read from memory into a TImage.bitmap.

I am currently using jclcompresion to handle zips and rars, but was considering moving back to system.zip because I really only need to be able to handle zip files. If it would be easier to stay with jclcompression though that would work for me.


Solution

  • The read method of the TZipFile class can be used with a stream

    procedure Read(FileName: string; out Stream: TStream; out LocalHeader: TZipHeader); overload;
    procedure Read(Index: Integer; out Stream: TStream; out LocalHeader: TZipHeader); overload;
    

    from here you can access the compressed file using the index or the filename.

    Check this sample which uses a TMemoryStream to hold the uncompressed data.

    uses
      Vcl.AxCtrls,
      System.Zip;
    
    procedure TForm41.Button1Click(Sender: TObject);
    var
      LStream    : TStream;
      LZipFile   : TZipFile;
      LOleGraphic: TOleGraphic;
      LocalHeader: TZipHeader;
    begin
      LZipFile := TZipFile.Create;
      try
        //open the compressed file
        LZipFile.Open('C:\Users\Dexter\Desktop\registry.zip', zmRead);
        //create the memory stream
        LStream := TMemoryStream.Create;
        try
          //LZipFile.Read(0, LStream, LocalHeader); you can  use the index of the file
          LZipFile.Read('SAM_0408.JPG', LStream, LocalHeader); //or use the filename 
          //do something with the memory stream
          //now using the TOleGraphic to detect the image type from the stream
          LOleGraphic := TOleGraphic.Create;
          try
             LStream.Position:=0;
             //load the image from the memory stream
             LOleGraphic.LoadFromStream(LStream);
             //load the image into the TImage component
             Image1.Picture.Assign(LOleGraphic);
          finally
            LOleGraphic.Free;
          end;
        finally
          LStream.Free;
        end;
      finally
       LZipFile.Free;
      end;
    end;