2016-04-29 43 views
1

MJPEGファイルを作成するDelphiプログラムを作成しました。このファイルは数GBにすることができます。 JPGは、DSPackを使用してDirectXカメラから取得されます。その部分は正常に動作し、JPG画像ファイルを次の形式で作成します。Delphi 7:TFileStreamからバイトブロックを読み込み、TMemorySTreamにコピーする

FF D8 ....(画像データ)... FF D9 FF D8 ....(画像データ)... FF D9 FF D8など

FF D8はJPGの開始を示し、FF D9は終了を示します。各JPGのサイズは約21KBです。

ここでは、一致するMJPEGプレーヤーを作成しようとしています。フォームの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を残すが、うまくいけば、その位置ポインタが保持されます。 フォーム上にボタンがありますが、一度に1つのJPGをジョグ送りすることを意図していますが、最初の「ジョグ」は1つの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; 

私はサードパーティMJPEGプレーヤーでチェックしていると私は、MJPEGファイルがOKである知っているので、それがフレーム毎にジョギングすることができます。なぜ私の手技がフレームごとに一様にステップしていないのかについての示唆は高く評価されます。

ありがとう、 ジョン。

+0

一度に2バイトを読み書きすることは非常に効率が悪くなります。バッファリングが必要です。 –

+0

少し遅いですが、2つのEndバイトの位置を失うことなく、大きなブロックを読み書きする方法がわかりません(ポインタを次のStartバイトに準備したままにしておきます)。それは遅いですが、私の思考は、私がこれを動作させることができなければ、もっと複雑なもので本当に苦労しているでしょう! – vwlowen

+3

イメージデータのバイト数は常に偶数であるのですか?そうでない場合は、終了マーカーが欠落します。 –

答えて

1

コメントと提案に感謝します。私はそれを整理することができたと思う。

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; 

end;

ジョグボタンの手順はほとんど同じです:

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 

おかげで再び正しい方向に私を指しているため。

ジョン。

関連する問題