簡體   English   中英

Delphi 7:從 TFileStream 中讀取一個字節塊並復制到 TMemorySTream

[英]Delphi 7: Reading a block of Bytes from a TFileStream & copying to TMemorySTream

我寫了一個 Delphi 程序,它創建 MJPEG 文件,它的長度可以是幾 GB。 JPG 是使用 DSPack 從 DirectX 相機中抓取的。 該部分工作正常並以以下格式創建 JPG 圖像文件:

FF D8 ....(圖像數據)... FF D9 FF D8 ....(圖像數據)... FF D9 FF D8 等

FF D8 標記 JPG 的開始,FF D9 標記結束。 每個 JPG 大小約為 21KB。

現在,我正在嘗試編寫一個匹配的 MJPEG 播放器。

在 Form 的 FormCreate 過程中,我創建了一個 FileStream 並顯示第一個工作正常的 JPG:

procedure TForm1.FormCreate(Sender: TObject);
var
  b: Array[0..1] of Byte;
  jpg: TJPEGImage;
begin
 :
 :
   MemoryStream:= TMemoryStream.Create;
   jpg:= TJPEGImage.Create;

   MJPEGStream:= TFileStream.Create(MJPEGFileName, fmOpenRead);

   MJPEGStream.Position:= 0;

   repeat                                   
      MJPEGStream.Read(b[0], 2);            // Find end of first jpg
      MemoryStream.Write(b[0], 2);          // and write to memory
   until (b[0] = $FF) and (b[1] = $D9);

   MemoryStream.Position:= 0;
   jpg.LoadFromStream(memoryStream);
   Image1.Picture.Assign(jpg);
   MemoryStream.Free;
   jpg.Free;
end;

我將 FileStream 保持打開狀態,因此希望保留它的位置指針。 我在表單上有一個按鈕,目的是一次慢速前進一個 JPG,但是,雖然第一個“慢速”前進了一個 JPG,但隨后的慢速前進了隨機次數。 這是程序:

procedure TForm1.btnJogForwardClick(Sender: TObject);
var
   b: Array[0..1] of Byte;
   jpg: TJPEGImage;

begin
    MemoryStream:= TMemoryStream.Create;
    try
       repeat
          MJPEGStream.Read(b[0], 2);
          MemoryStream.Write(b[0], 2);
       until ((b[0] = $FF) and (b[1] = $D9));

       MemoryStream.Position:= 0;
       jpg:= TJPEGImage.Create;
       try
         try
           jpg.LoadFromStream(MemoryStream);
           Image1.Picture.Assign(jpg);
         except
         end;
       finally
         jpg.Free;
       end;
    finally
       MemoryStream.Free;
  end;

我已經檢查過 3rd Party MJPEG 播放器,它可以逐幀運行,所以我知道 MJPEG 文件沒問題。 關於為什么我的程序沒有逐幀統一步進的任何建議將不勝感激。

謝謝,約翰。

感謝您的意見和建議。 我想我已經設法對其進行了排序。

const
  JPGSizeMax = 100000;

procedure TForm1.FormCreate(Sender: TObject);
var
   b: Array[0..JPGSizeMax] of Byte;
 :
 :
begin
 :
 :
MJPEGStream:= TFileStream.Create(MJPEGFileName, fmOpenRead);
MJPEGStream.Position:= 0;

MJPEGStream.Read(b[0], JPGSizeMax);
for i:= 0 to JPGSizeMax do
begin
   if (b[i] = $D9) and (b[i-1] = $FF) then
   begin
     Count:= i;
     break;
   end;
end;

MemoryStream.Write(b[0], Count);
FilePosition:= Count + 1;

MemoryStream.Position:= 0;
jpg.LoadFromStream(memoryStream);
Image1.Picture.Assign(jpg);

MemoryStream.Free;
jpg.Free;

結尾;

Jog 按鈕的操作步驟大致相同:

MJPEGStream.Position:= FilePosition;

MJPEGStream.Read(b[0], JPGSizeMax);
for i:= 0 to JPGSizeMax do
begin
   if (b[i] = $D9) and (b[i-1] = $FF) then
   begin
     Count:= i;
     break;
   end;
end;

  memoryStream.Write(b[0], Count);
  FilePosition:= FilePosition + count + 1;

// etc

再次感謝您為我指明了正確的方向。

約翰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM