MyBaseを試してみる。(BLOBフィールドで画像の読み書き)
とりあえずDB.TBlobFieldのヘルプを読んでみると・・・
ということで、次のようなコードを書いてみました。
これらを使って次のような処理で、読み書きは確かにできます。
しかし、たくさんの画像形式があるときに、いちいちBitmap用とかPNG用とか作るのは大変ですよね。TPicture.Graphicに入れて、変換させると楽かなとか思いましたが、更にヘルプを調べてみますとTBlobField にはLoadFromFile, SaveToFile等という関数がありました。これは使えると思い、早速試してみたところ、ファイル形式に関係なくとても簡単に扱えるようになりました。
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;
| 固定リンク