連続したJPEGストリームデータの読み込みで1ファイルづつ読み込むには?

解決


Toji  2004-11-24 07:53:56  No: 11896

JPEGファイルの連続したデータをストリームで保存したのですが
読み込みがどうしても上手くいきません

var  FolderThu: TFileStream;
     con,i: integer;
begin
FolderThu := TFileStream.Create(Path+'\test.dat',fmCreate);
//conにはファイル数が入ってます
//JPEGのファイル数を書き込み
FolderThu.Write(con,SizeOf(integer));

jpg := TJPEGImage.Create;
Bmp := TBitmap.Create;
jpg.JPEGNeeded;
jpg.CompressionQuality := 30;
jpg.Compress;

for i := 0 to con do
begin
  (省略・・・・画像を読み込んで縮小したものがpic.Bitmapに入ります)
  jpg.Assign(Pic.Bitmap);
  jpg.SaveToStream(FolderThu);
end;
  (省略・・・オブジェクトの解放)
  
データはこのように作成されます
バイナリで確認しても確かに連続して書き込まれていました

個数を読み込んだあと
jpg.LoadFromStream(FolderThu);
このようにして読み込ませたのですが
FolderThu.Positionを確認するとストリームの一番最後まで読み込んでいました
結果的に次のファイルが読み込めず困っています
読み込み前に必ずseekしなければならないのでしょうか?
(しかし1ファイル目を読み込むときのポジションは間違いなくJPEGファイルの先頭でしたし・・・


りおりお  2004-11-24 08:28:01  No: 11897

まず、フォーマットを自分で決めることですね。
各ファイルのサイズが分からないと分離できないでしょう。

[画像の数:integer][1番目のサイズ][一番目の内容]...[n番目のサイズ][n番目の内容]

と、いうふうにすると、シークエンシャルにアクセスして分離できますね。

個々の分離はもう一つ TMemoryStream などをつくって読みとってください。


りおりお  2004-11-24 09:09:42  No: 11898

画像が三つの場合の例をあげておきます。

uses
  Jpeg;

//  ファイルに書き込む
procedure TForm1.Button1Click(Sender: TObject);
var
  i,con,size:integer;
  jpegfile: Array[0..2] of string;
  ms:TMemoryStream;
  fs:TFileStream;
begin
  jpegfile[0] := 'C:\JPG\flower.jpg';
  jpegfile[1] := 'C:\JPG\Rose.jpg';
  jpegfile[2] := 'C:\JPG\suiren.jpg';

  fs := TFileStream.Create('c:\Test.dat',fmCreate or fmShareExclusive);
  ms := TMemoryStream.Create;
  try
    con := 3;
    fs.Write(con,SizeOf(integer));
    for i := 0 to con-1 do
    begin
      ms.Clear;
      ms.LoadFromFile(jpegfile[i]);
      size := ms.Size;
      fs.Write(size,SizeOf(integer));
      fs.Write(ms.Memory^,size);
    end;
  finally
    ms.Free;
    fs.Free;
  end;
end;

// ファイルから読み出して Image1 〜 Image3 に表示する
procedure TForm1.Button2Click(Sender: TObject);
var
  i,con,size:integer;
  ms:TMemoryStream;
  fs:TFileStream;
  jpg:TJpegImage;
  compo:TComponent;
begin
  fs := TFileStream.Create('c:\Test.dat',fmOpenRead or fmShareExclusive);
  ms := TMemoryStream.Create;
  jpg := TJpegImage.Create;
  try
    fs.Position := 0;
    fs.Read(con,SizeOf(integer));
    for i := 0 to con-1 do
    begin
      ms.Clear;
      fs.Read(size,SizeOf(integer));
      ms.SetSize(size);
      fs.Read(ms.Memory^,size);
      jpg.LoadFromStream(ms);
      compo := FindComponent('Image'+IntToStr(i+1));
      if compo is TImage then TImage(compo).Picture.Bitmap.Assign(jpg);
    end;
  finally
    fs.Free;
    ms.Free;
    jpg.Free;
  end;
end;


Toji  2004-11-24 12:03:36  No: 11899

りおりおさんいつも有り難うございます  今解決しました
MemoryStreamを使うとは盲点でした
setsizeとms.clearも例示が無ければ気づかなかったと思います
改めてありがとうございましたm(_ _)m


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加