我疯了。
这就是我正在做的事情
双击按钮并添加以下代码:
procedure TForm31.Button1Click(Sender: TObject);
var
BF: TBlobField;
BS: TStream;
BM: TBitmap;
begin
ClientDataset1.Open;
ClientDataset1.First;
BF := ClientDataSet1.FieldByName('Graphic') as TBlobField;
BS := ClientDataSet1.CreateBlobStream(BF, bmRead);
BS.Position := 0;
BM := TBitmap.Create;
try
BM.LoadFromStream(BS);
finally
BM.Free;
end;
end;
运行它。当我这样做时,我得到“位图图像无效”。
咦?这些数据多年来一直是位图 - 出了什么问题?
答案 0 :(得分:7)
如果将TGraphicField
保存到文件(使用它的SaveToFile
方法)并使用十六进制查看器查看该文件,它确实是一个位图。问题是在开头有一个描述文件类型的blob头。这在documentation中有所提及,有些模糊。我还在docs中的TBlobField.GraphicHeader
属性说明中找到了对它的引用。
如果您将Stream.Position
设置为8而不是0,则会正确读入TBitmap
。
BS.Position := 8;
BM.LoadFromStream(BS);
答案 1 :(得分:4)
图形字段是二进制大对象(BLOB)字段的一种形式 数据包含一个描述编码的BLOB标题 图形值。
“BLOB标题”在那里有误导性,它似乎是图形备忘录的Paradox存储格式的残余。
(* from DB *)
{ Paradox graphic BLOB header }
type
TGraphicHeader = record
Count: Word; { Fixed at 1 }
HType: Word; { Fixed at $0100 }
Size: Longint; { Size not including header }
end;
procedure TForm1.FormClick(Sender: TObject);
const
HeaderSize = SizeOf(TGraphicHeader);
var
Field: TGraphicField;
Stream: TClientBlobStream;
begin
Field := ClientDataSet1.FieldByName('Graphic') as TGraphicField;
Stream := ClientDataSet1.CreateBlobStream(Field, bmRead) as TClientBlobStream;
Stream.SaveToFile('dump.bin'); // examine BLOB and see extra bytes preceding BITMAPFILEHEADER
Assert(Stream.Position = 0);
Stream.Seek(+HeaderSize, soFromCurrent); // discard header, it does not contain anything of use anyways
Image1.Picture.Bitmap.LoadFromStream(Stream);
ClientDataSet1.Next;
end;