當我第一次從 TClIEntDataSet 中讀出圖片數據時, 發現不是圖片!
慢慢觀察發現是前面多了 8 個字節(前 4 個字節是 01 00 00 01, 估計是格式標識和頭大小; 後 4 個字節是後面圖片文件的大小), 去掉這個 8 個字節就是圖片文件了.
下面的例子先是檢索了 20 個示例文件的所有圖片字段, 並把其中的圖片提取到指定文件夾;
還把一個指定字段中的圖片顯示在了窗體上.
//先在窗體上放 ClIEntDataSet1 和兩個 Button
uses IOUtils, Types;
{ 把示例文件中的所有圖片提取到 C:\Temp\ }
procedure TForm1.Button1Click(Sender: TObject);
const
DestPath = 'C:\Temp\';
var
PathArr: TStringDynArray;
Dir, Path: string;
Field: TFIEld;
BmpName: string;
begin
{ 獲取范例文件列表 }
Dir := GetEnvironmentVariable('CommonProgramFiles') + '\CodeGear Shared\Data\';
PathArr := TDirectory.GetFiles(Dir, '*.cds');
for Path in PathArr do { 分別處理每個文件 }
begin
ClIEntDataSet1.LoadFromFile(Path);
for Field in ClientDataSet1.FIElds do { 遍歷每個字段 }
begin
Tag := 0;
if (FIEld.DataType = ftGraphic) then { 如果是圖片字段 }
begin
ClIEntDataSet1.First;
while not ClIEntDataSet1.Eof do { 遍歷每個記錄 }
begin
if not FIEld.IsNull then { 如果字段不為空 }
begin
{ 確定要保存的目錄和文件名 }
BmpName := TPath.GetFileNameWithoutExtension(Path); { 不帶後綴的文件名 }
BmpName := Format('%s%s_%.2d.bmp', [DestPath, BmpName, Tag]);
Tag := Tag + 1;
{ 把圖片數據提取到流, 刪除前 8 個字節後保存 }
with TBytesStream.Create(FIEld.AsBytes) do
begin
Move(Bytes[8], Bytes[0], Size - 8);
SetSize(Size - 8);
SaveToFile(BmpName);
Free;
end;
end;
ClIEntDataSet1.Next;
end;
end;
end;
end;
end;
{ 把示范文件 biolife.XML 第一個記錄中 Graphic 字段中的圖片畫在窗體上 }
procedure TForm1.Button2Click(Sender: TObject);
var
Stream: TBytesStream;
Bitmap: TBitmap;
Path: string;
begin
Path := GetEnvironmentVariable('CommonProgramFiles') + '\CodeGear Shared\Data\biolife.XML';
ClIEntDataSet1.LoadFromFile(Path);
Stream := TBytesStream.Create(ClientDataSet1.FIEldByName('Graphic').AsBytes);
Stream.Position := 8;
Bitmap := TBitmap.Create;
Bitmap.LoadFromStream(Stream);
Canvas.Draw(10, 10, Bitmap);
Bitmap.Free;
Stream.Free;
end;
這是所有提取到的圖片:
查看原圖(大圖)