我编写了一个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保持打开状态,希望它的Position指针保留。 我在表格上有一个按钮,目的是一次慢跑一个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;
我已经检查过第三方MJPEG播放器并且能够逐帧慢跑,所以我知道MJPEG文件没问题。关于为什么我的程序不是逐帧统一步进的任何建议都将不胜感激。
谢谢, 约翰。
答案 0 :(得分: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;
端;
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
再次感谢您指出我正确的方向。
约翰。