« DBGridを同期させる。 | トップページ | MyBaseを試してみる。(グループ化 on FireMonkey) »

MyBaseを試してみる。(BLOBフィールドで画像の読み書き)

とりあえずDB.TBlobFieldのヘルプを読んでみると・・・
TBlobField は,BLOB 項目の間でのデータのストリームをサポートするメソッドや,
BLOB 項目とバイナリファイルとの間でのバイナリデータのコピーをサポートする
メソッドを新しく導入します。また,データセットの CreateBlobStream
 メソッドによって返されるストリームを使用して,BLOB 項目によって管理される
データを読み書きすることもできます。 

ということで、次のようなコードを書いてみました。
// データベースの作成
procedure CreateDB(CDS: TClientDataSet);
begin
  CDS.Close;
  CDS.FieldDefs.Add('FileName', ftWideString, 100);
  CDS.FieldDefs.Add('IMG', ftBlob, 100);
  CDS.CreateDataSet;
  CDS.Close;
end;

// Jpegの追加
procedure cdsAddJPEGImage(CDS: TClientDataSet; FieldName: String;
  Jpeg: String);
var
  JPG:  TJPEGImage;
  Stream: TStream;
begin
  JPG := TJPEGImage.Create;
  try
    JPG.LoadFromFile(Jpeg);
    CDS.Append;
    Stream := CDS.CreateBlobStream(CDS.FieldByName(FieldName), bmReadWrite);
    try
      JPG.SaveToStream(Stream);
    finally
      Stream.Free;
    end;
  finally
    JPG.Free;
  end;
end;

// Jpegの取り出し
procedure cdsGetJPEGImage(CDS: TClientDataSet; FieldName: String;
  Jpeg: String);
var
  Stream: TStream;
  JPG:  TJPEGImage;
begin
  JPG := TJPEGImage.Create;
  try
    Stream := CDS.CreateBlobStream(CDS.FieldByName(FieldName), bmRead);
    try
      Stream.Position := 0;
      JPG.LoadFromStream(Stream);
      JPG.SaveToFile(Jpeg);
    finally
      Stream.Free;
    end;
  finally
    JPG.Free;
  end;
end;

これらを使って次のような処理で、読み書きは確かにできます。
// Save
procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateDB(ClientDataSet1);
  ClientDataSet1.Open;
  cdsAddJPEGImage(ClientDataSet1,'IMG','D:\aaa.jpg');
  ClientDataSet1.SaveToFile('D:\Test.CDS');
end;

// Load
procedure TForm1.Button2Click(Sender: TObject);
begin
  ClientDataSet1.LoadFromFile('D:\Test.CDS');
  ClientDataSet1.Open;
  cdsGetJPEGImage(ClientDataSet1,'IMG','D:\Test\aaa.jpg');
end;

しかし、たくさんの画像形式があるときに、いちいちBitmap用とかPNG用とか作るのは大変ですよね。TPicture.Graphicに入れて、変換させると楽かなとか思いましたが、更にヘルプを調べてみますとTBlobField にはLoadFromFile, SaveToFile等という関数がありました。これは使えると思い、早速試してみたところ、ファイル形式に関係なくとても簡単に扱えるようになりました。
// Save
procedure TForm1.Button3Click(Sender: TObject);
begin
  CreateDB(ClientDataSet1);
  ClientDataSet1.Open;
  ClientDataSet1.Append;
  (ClientDataset1.FieldByName('IMG') as TBlobField).LoadFromFile('D:\aaa.jpg');
  ClientDataSet1.Append;
  (ClientDataset1.FieldByName('IMG') as TBlobField).LoadFromFile('D:\aaa.png');
  ClientDataSet1.Append;
  (ClientDataset1.FieldByName('IMG') as TBlobField).LoadFromFile('D:\aaa.bmp');
  ClientDataSet1.Append;
  (ClientDataset1.FieldByName('IMG') as TBlobField).LoadFromFile('D:\aaa.xlsx');
  ClientDataSet1.CheckBrowseMode;
  ClientDataSet1.SaveToFile('D:\Test.CDS');
end;

// Load
procedure TForm1.Button4Click(Sender: TObject);
var
  MS: TMemoryStream;
begin
  MS:= TMemoryStream.Create;
  try
    ClientDataSet1.LoadFromFile('D:\Test.CDS');
    ClientDataSet1.Open;

    (ClientDataset1.FieldByName('IMG') as TBlobField).SaveToFile('D:\Test\aaa.jpg');
    ClientDataSet1.Next;

    (ClientDataset1.FieldByName('IMG') as TBlobField).SaveToFile('D:\Test\aaa.png');
    ClientDataSet1.Next;

    (ClientDataset1.FieldByName('IMG') as TBlobField).SaveToFile('D:\Test\aaa.bmp');

    // ファイルに保存ではなくTImageに表示したい場合
    (ClientDataset1.FieldByName('IMG') as TBlobField).SaveToStream(MS);
    MS.Position := 0;
    Image1.Picture.Bitmap.LoadFromStream(MS);

    ClientDataSet1.Next;
    (ClientDataset1.FieldByName('IMG') as TBlobField).SaveToFile('D:\Test\aaa.xlsx');
  finally
    MS.Free;
  end;
end;

|

« DBGridを同期させる。 | トップページ | MyBaseを試してみる。(グループ化 on FireMonkey) »