MetaFileのストリーム保存

解決


印刷屋  2010-08-23 08:06:34  No: 39040

メタファイルをストリーム保存できるようになったんですが、構造がよくわからずに使っています。
これから複数のメタファイルをひとつのファイルに保存したいのですが、その場合は、
for cnt := 1 to 3 do
  TMetafile.SaveToStream(MS);

for cnt := 1 to 3 do
  TMetafile.LoadFromStream(MS);
だけでいいのですか?
ストリーム内に1回メタファイルを書き込んだ際、その終端情報でも入っているのかなぁという疑問です。
よろしくお願いします。


monaa  2010-08-23 10:15:13  No: 39041

実際やってみれば分かる事なのでは?

procedure TForm1.Button1Click(Sender: TObject);
var
  mf1,mf2:TMetafile;
  mc1,mc2:TMetafileCanvas;
begin
  mf1 := TMetafile.Create;
  mf1.Width := 100;
  mf1.Height:= 100;
  mc1 := TMetafileCanvas.Create(mf1,0);
  mc1.TextOut(0,0,'AAA');

  mf2 := TMetafile.Create;
  mf2.Width := 100;
  mf2.Height:= 100;
  mc2 := TMetafileCanvas.Create(mf2,0);
  mc2.TextOut(0,20,'BBB');
  mc2.Free;

  mc1.Draw(0,0,mf2);
  mc1.Free;
  Canvas.Draw(0,0,mf1);
  mf1.Free;
  mf2.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  mf1,mf2:TMetafile;
  mc1,mc2:TMetafileCanvas;
  ms:TMemoryStream;
begin
  ms := TMemoryStream.Create;

  mf1 := TMetafile.Create;
  mf1.Width := 100;
  mf1.Height:= 100;
  mc1 := TMetafileCanvas.Create(mf1,0);
  mc1.TextOut(0,0,'AAA');
  mc1.Free;
  mf1.SaveToStream(ms);
  mf1.Free;

  mf2 := TMetafile.Create;
  mf2.Width := 100;
  mf2.Height:= 100;
  mc2 := TMetafileCanvas.Create(mf2,0);
  mc2.TextOut(0,20,'BBB');
  mc2.Free;
  mf2.SaveToStream(ms);
  mf2.Free;

  mf1:=TMetafile.Create;
  ms.Position:=0;
  mf1.LoadFromStream(ms);
  Canvas.Draw(0,0,mf1);
  mf1.Free;
  ms.Free;
end;


印刷屋  2010-08-24 07:33:29  No: 39042

手間を端折ってすいません。
やっぱり、LoadFromStreamはひとつの終端を見極めて読み出してるんですね。


tor  2010-08-24 08:05:08  No: 39043

確かに「やってみれば分かる」ことではありますが、
どういう理由で動くのかを理解しておくのも無駄ではないかと。
(実は危ないことをやっていて、たまたま動いただけという可能性もありますし)

> やっぱり、LoadFromStreamはひとつの終端を見極めて読み出してるんですね。
厳密に言うと終端を調べているわけではなく
先頭にメタファイルヘッダというレコードがあって、
その中にメタファイル全体のサイズが書いてあります。
だからそのサイズ分だけ読み書きすればいいという仕組みですね。

一応参考までに、メタファイルの内部構造については
MSDNのAbout Metafilesの項で概要が説明されています。
詳しい中身はGetEnthMetafileHeaderやEnumEnhMetafileといった関数をたどっていけば調べられます。
http://msdn.microsoft.com/en-us/library/dd145051(v=VS.85).aspx
(日本語版だと概要だとか構造体のリファレンスとかがばっさり削られているので注意)


印刷屋  2010-08-26 07:25:10  No: 39044

torさんありがとうございます。
理解が深まりました。


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

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






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