6

我已经搜索和搜索,似乎找不到任何描述我在delphi代码中要做的事情。溶液有时很接近,但不够接近,我无法弄清楚。所以我在这里问..

我有很多位图,我正在从屏幕截图中提取。我一直在做的是保存到bitmaps_001.bmp,但是它需要很多存储空间,所以我升级了例程以保存为bitmaps_001.png,这样可以节省更多的空间,但是现在我想保存到一个文件中,一个 tfilestream,并使用 tprogressbar 从中读取,我可以在屏幕上显示图像时向左/向右拖动。

基本上,我正在尝试完成以下操作:

procedure SaveBMPtoStream(st: tfilestream; bmp: tbitmap);
procedure ReadBMPfrStream(st: tfilestream; bmp: tbitmap; bnum: integer);

到目前为止,代码(下面)按原样工作,(它在按下 tbutton 时写入和读取一个位图图像)但我只能写一个位图图像。我需要将每个会话所需的尽可能多的图像实时写入 tfilestream,可能使用 ttimer 控件并让它写入尽可能多的图像,直到我按下停止按钮。我该怎么做才能修改下面的代码来解决这个问题?谢谢你。

我正在运行 Windows XP,连接到带有 NTFS 文件系统的外部 usb3.0 1tb 驱动器。

type
  TMS = TFileStream; 
var
  MS:  TMS; 
  pos: int64;   // bnum for 0-99,999 images.
  sz:  integer; // size of the image/stream ?

//write bitmaps to stream
procedure SaveBMPtoStream(ms: TMS; Bmp: TBitmap; bnum: integer);
begin
  // create (or append to) stream
  if fileexists('d:\streams\s.stm') then MS := TFileStream.Create('d:\streams\s.stm', fmOpenReadWrite)
    else MS := TFileStream.Create('d:\streams\s.stm', fmCreate);
  //sz:=MS.Size; pos:=ms.Position;
  bmp.SaveToStream(MS); 
  // free stream
  ms.free;
end;

//read bitmaps from stream
procedure ReadBMPfrStream(ms: TMS; Bmp: TBitmap; bnum: integer);
begin
  // open stream.
  MS := TFileStream.Create ('d:\streams\s.stm', fmOpenReadWrite); 
  // read in bitmap from stream
  //sz:=MS.Size; pos:=ms.Position;
  bmp.LoadFromStream(MS);
  // free stream
  ms.free;
end;
4

2 回答 2

7
Function LoadBMPFromStream(const fn: String; Bmp: TBitmap; Nr: Integer):Boolean;
var // Nr is 0 based first Bitmap=0
  fs: TFileStream;
  ms: TMemoryStream;
  intNr: Integer;
  pos: Cardinal;
  size: DWord;
begin
  intNr := 0;
  if fileexists(fn) then
  begin
    Result := true;
    fs := TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
    try
      fs.Read(size, SizeOf(DWord)); // Read Size of first Bitmap
      while (Nr > intNr) and (fs.Position < fs.size) do
      begin
        fs.Seek(size, soFromCurrent);
        fs.Read(size, SizeOf(DWord)); // Read Size of  Bitmap with intNr
        inc(intNr);
      end;
      if fs.Position < fs.size then
      begin
        ms := TMemoryStream.Create;
        try
          ms.CopyFrom(fs, size);
          ms.Position := 0;
          Bmp.LoadFromStream(ms);
        finally
          ms.Free;
        end;
      end
      else Result := false;
    finally
      fs.Free;
    end;

  end;
end;


procedure SaveBMPtoStream(const fn: String; Bmp: TBitmap);
var
  fs: TFileStream;
  ms: TMemoryStream;
  pos: Cardinal;
  size: DWord;
begin
  if fileexists(fn) then
  begin
    fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareDenyNone);
    fs.Seek(0, soEnd);
  end
  else
  begin
    fs := TFileStream.Create(fn, fmCreate or fmShareDenyNone);
  end;
  try
    ms := TMemoryStream.Create;
    try
      Bmp.SaveToStream(ms);
      size := ms.size;
      ms.Position := 0;
      fs.Write(size, SizeOf(DWord)); // Write Size of next Bitmap first
      fs.CopyFrom(ms, size);
    finally
      ms.Free;
    end;
  finally
    fs.Free;
  end;

end;

procedure TForm6.Button2Click(Sender: TObject);
begin
  // load first Picture
  LoadBMPFromStream('C:\temp\test.str', Image3.picture.bitmap, 0);
  // load third picture
  // LoadBMPFromStream('C:\temp\test.str', Image3.picture.bitmap, 2);
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  SaveBMPtoStream('C:\temp\test.str', Image1.picture.bitmap);
  SaveBMPtoStream('C:\temp\test.str', Image2.picture.bitmap);
  SaveBMPtoStream('C:\temp\test.str', Image1.picture.bitmap);
end;
于 2012-12-16T08:04:02.463 回答
0

您想将所有图像保存到同一个文件吗?然后,您最简单的选择是使用 0 压缩(仅存储)的 7zip 文件,这将非常轻松地为您管理存档中文件的索引/保存/检索。

这是一个很好的免费组件,可以做到这一点:http ://www.rg-software.de/rg/index.php?option=com_content&view=article&id=29&Itemid=51

您现在也可以再次尝试仅使用位图,同时在 7zip 中使用快速压缩设置,这可能会获得比 PNG 更好的速度。

于 2012-12-16T03:47:25.533 回答