我一直在Delphi XE3上申请。我试图将值从数据库显示到表单上放置的TAdvStringGrid
组件。我正在使用数据集在TAdvSTringGRid
显示结果(代码如下)。除数据库中的图像外,所有其他值都显示完美。在预期显示图像的地方,它显示垃圾字符。如何在TAdvStringGrid上完美地从DataBase显示图像。
SQLConnection1: TSQLConnection;
SQLMonitor1: TSQLMonitor;
DataSource1: TDataSource;
ADOConnection1: TADOConnection;
ClientDataSet1: TClientDataSet;
AdvStringGrid1: TAdvStringGrid;
procedure Button1Click(Sender: TObject);
procedure ShowSelectResults(results: TDataSet; sg: TAdvSTringGrid);
procedure FormCreate(Sender: TObject);
procedure TForm2.FormCreate(Sender: TObject);
var
results: TDataSet;
begin
SQLConnection1.Params.Add('Database=E:\playdb.s3db');
try
SQLConnection1.Connected := true;
SQLMonitor1.Active := True;
SQLConnection1.Execute('Select * from plays', nil, results);
except
on E: EDatabaseError do
ShowMessage('Exception raised with message' + E.Message);
end;
ShowSelectResults(results, advstringgrid1);
end;
调用
下的ShowSelectResultprocedure TForm2.ShowSelectResults(results: TDataSet; sg: TAdvStringGrid);
var
names: TStringList;
i,j,k, rc: Integer;
resultsfield: variant;
Field: TblobField;
Stream: TStream;
Jpg: TJPEGImage;
Picture: TPicture;
begin
if not results.IsEmpty then
//Prints Data in the TAdvStringGrid
results.First;
j := 1;
while not results.EOF do
begin
if (j>sg.rowcount) then
sg.rowcount := sg.rowcount + 1;
for i := 0 to results.fields.Count - 1 do
begin
if i=0 then
else if i = 4 then
//Here I want to display image from db
Field := TBlobField(results.FieldByName(names[i]).AsString);
Stream := results.CreateBlobStream(Field, bmRead);
sg.CreatePicture(i, j, true, ShrinkWithAspectRatio, 20, haCenter, vaAboveText).Picture
else
sg.cells[i,j] := results.FieldByName(names[i]).AsString;
end;
results.Next;
inc(j);
end;
end;
问题发生在else if i=4
的上述代码中的sg.CreatePicture
循环(下面给出CreatePicture
过程的格式),我希望在该特定列中显示图像。< / p>
在TAdvStringGrid手册中,他们提到了以下网格单元格图片显示方法
Grid.CreatePicture(2,3,True,Shrink,0,haLeft,vaTop).LoadFromFile(‘TST.JPG’);
procedure AddPicture(ACol,ARow: Integer;APicture:TPicture;transparent: Boolean; stretchmode:TStretchMode; padding: Integer; hal:TCellHalign; val:TCellValign);
function GetPicture(ACol,ARow: Integer): TPicture;
Grid.CreateFilePicture(2,3,True,Shrink,0,haLeft,vaTop).Filename := ‘TST.JPG’;
但是没有提到如何将它与DataSet一起使用。我正在搞乱TAdvStringGRid的CreatePicture过程,而不是使用DataSet来解决它。
最新发展
最后,我在Bummi等学者的帮助下找到方法将JPEG图像保存到memorystream
然后再显示。
我的最新代码如下
procedure TForm2.ShowSelectResults(results: TDataSet; sg: TAdvStringGrid);
var
names: TStringList;
Field: TblobField;
//Stream: TStream;
Stream: TMemoryStream;
//blobType := TBlobType;
Jpg: TJPEGImage;
Picture: TPicture;
Image: TImage;
Graphic: TGraphic;
Begin
//k := results.FieldCount;
//sg.Rowcount := rc;
results.First;
j := 1;
while not results.EOF do
begin
if (j>sg.rowcount) then
sg.rowcount := sg.rowcount + 1;
for i := 0 to results.fields.Count - 1 do
begin
if i=0 then
else if i = 4 then // Column 5 for Image
begin
try
if ((results.FieldByName(names[i]).AsString) <> '') then
Begin
Stream := TMemoryStream.Create;
Image := Timage.Create(Self);
Jpg := TJPEGImage.Create;
Picture := TPicture.Create;
Field := TBlobField(results.FieldByName('image'));
Stream := results.CreateBlobStream(Field, bmReadWrite);
//Field.SaveToStream(Stream);
Stream.Position := 0;
Jpg.LoadFromStream(Stream);
Picture.Assign(Jpg);
//Jpg.LoadFromFile('C:\Sample Pictures\Cabo.jpg');
//Picture.Assign(Jpg);
sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
end;
finally
Jpg.Free;
Stream.Free;
end;
end
else
//Prints data in other columns
sg.cells[i.j] := results.FieldByName(names[i]).AsString;
inc(j);
end;
end;
现在我在线Jpg.LoadFromStream(Stream);
处面临一些记忆问题
它是错误代码JPEG Error #53
,我才知道上面这样的错误代码仅在您尝试通过内存流访问的图像被破坏时显示但我确保图像没有损坏并且在其他软件的帮助下正确显示从类似的数据库中提取我也在数据库中更新了图像。我仍然得到JPEG Error #53
的原因。问题主要在Jpg.LoadFromStream(Stream)
请注意带注释的代码
Jpg.LoadFromFile('C:\Sample Pictures\Cabo.jpg');
Picture.Assign(Jpg);
sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
从静态文件中提取它时效果很好。问题仅出在MemoryStream上。如何纠正这个错误?
答案 0 :(得分:4)
CreateBlobStream正在创建一个TStream对象,而不是TMemoryStream
由于您不想将JPG写入数据库,因此应使用bmRead而不是bmReadWrite。
我不习惯SQLite,但你必须确保使用合适的二进制日期类型(BLOB)。
JPG := TJpegImage.Create;
Picture:= TPicture.Create;
try
st := results.CreateBlobStream(TBlobField(results.FieldByName('image')), bmRead);
try
JPG.LoadFromStream(st);
Picture.Assign(JPG);
sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
finally
st.Free;
end;
finally
JPG.Free;
Picture.Free;
end;
为了确保存储的图像真的是JPG,您应该编写JPG以进行测试,例如:
var
ms: TMemoryStream;
begin
ads.Open;
ads.Append;
ms := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(ms); // make sure having loaded a JPG
ms.Position := 0;
TBlobField(ads.FieldByName('image')).LoadFromStream(ms);
finally
ms.Free;
end;
ads.Post;
end;
答案 1 :(得分:0)
我意识到这有点迟了,但是我想做出贡献。我非常简单地执行了以下操作,不必担心图像格式(.jpg,.png等)。我只是创建一个TStream对象,将BLOB流加载到其中,然后从该流加载Image。简短而甜美,对我来说很棒。
var
Stream : TStream;
begin
try
Stream := TStream.Create;
Stream := Dataset.CreateBlobStream(Dataset.FieldByName('SIGNATURE'), bmRead);
Stream.Position := 0;
lblPicSize.Caption := 'Picture is ' + IntToStr(Stream.Size) + ' Bytes';
if Stream.Size <= 0 then
pnlPic.Caption := '<No Signature>'
else
pnlPic.Caption := '';
try
imgSignature.Picture.LoadFromStream(Stream);
except
on E:Exception do
begin
ShowMessage(E.Message);
end;
end;
finally
Stream.Free;
end;
end;