Saving JPEG to database [closed] - delphi

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
This code give Access violation at the TBlobField line:
procedure TfrmCapture.Button3Click(Sender: TObject);
var
j: TJPEGImage;
S: TFileStream;
begin
J := TJPEGImage.Create;
try
J.Assign(Image1.Picture.Graphic);
J.CompressionQuality := 80;
J.Compress;
J.SaveToStream(S);
S.Position := 0;
TBlobField(frmSignout.tblImg.FieldByName('Picture')).LoadFromStream(S);
finally
J.Free;
end;
Image1.Picture := nil;
Close;
end;
Basically Im trying to convert a Timage into JPEG and then save it to Image field (MSSQL express)
any ideas how to fix it ?

You are not instantiating the TFileStream that you save to:
procedure TfrmCapture.Button3Click(Sender: TObject);
var
J: TJPEGImage;
S: TFileStream;
begin
J := TJPEGImage.Create;
try
J.Assign(Image1.Picture.Graphic);
J.CompressionQuality := 80;
J.Compress;
S := TFileStream.Create('c:\path to\somefile.jpg', fmCreate); // <-- add this!
try
J.SaveToStream(S);
S.Position := 0;
TBlobField(frmSignout.tblImg.FieldByName('Picture')).LoadFromStream(S);
finally
S.Free; // <-- add this
end;
finally
J.Free;
end;
Image1.Picture := nil;
Close;
end;
That being said, I would suggest avoiding the file altogether (unless you really need it) and use TDataSet.CreateBlobStream() instead of TBlobField.LoadFromStream():
procedure TfrmCapture.Button3Click(Sender: TObject);
var
J: TJPEGImage;
S: TStream;
begin
J := TJPEGImage.Create;
try
J.Assign(Image1.Picture.Graphic);
J.CompressionQuality := 80;
J.Compress;
S := frmSignout.tlbImg.CreateBlobStream(frmSignout.tblImg.FieldByName('Picture'), bmWrite);
try
J.SaveToStream(S);
finally
S.Free;
end;
finally
J.Free;
end;
Image1.Picture := nil;
Close;
end;

Man Im just tired...of course its not file stream its memory stream..jeez.
This is the correct code to save Timage as JPEG in MSSQL express (~50kb/image):
procedure TfrmCapture.Button3Click(Sender: TObject);
var
j:TJPEGImage;
S : TMemorystream;
begin
J := TJPEGImage.Create;
S := Tmemorystream.Create;
try
J.Assign(image1.Picture.graphic);
J.CompressionQuality :=80;
J.Compress;
J.SaveToStream(S);
S.Position :=0;
(frmSignout.tblImg.FieldByName('Picture') as TblobField).LoadFromStream(S);
finally
J.Free;
S.Free;
end;
image1.Picture :=nil;
close;
end;

Related

Retrieve Word server properties with Delphi

Thanks to the below functions, I am succesfully retrieving, from a Word document stored locally (synced with the Server through OneDrive), its Server properties (those which are stored as SharePoint columns), all this without Ole automation. The functions' structure is:
Since the Word document is a zipped file, unzip the file where such properties are stored.
Extract the contents of the file into a string.
Load the string into an XML document.
Feed the field names and their contents into a StringList.
``
function WordGetServerProperties (FName:string):TStringList;
var
s,ss:string;
i,ii:integer;
St:TStringList;
XML:IXMLDocument;
N,NN: IXMLNode;
begin
s:=ExtractZipToStr(FName,'customXml/item1.xml',ExtractFilePath(FName));
if StrContains('<p:properties',s)=False then
s:=ExtractZipToStr(FName,'customXml/item2.xml',ExtractFilePath(FName));
if StrContains('<p:properties',s)=False then
s:=ExtractZipToStr(FName,'customXml/item3.xml',ExtractFilePath(FName));
XML:=NewXMLDocument;
St:=TStringList.Create;
XML.Active := True;
XML.LoadFromXML(s);
N:=xml.DocumentElement;
try
for i := 0 to N.ChildNodes.Count -1 do
begin
if N.ChildNodes[i].NodeName = 'documentManagement' then
begin
NN:=N.ChildNodes[i];
for ii := 0 to NN.ChildNodes.Count -1 do
begin
ss:=AnsiReplaceStr(NN.ChildNodes[ii].NodeName,'_x0020_',' ');
if ss='SharedWithUsers' then continue;
ss:=ss+'='+NN.ChildNodes[ii].Text;
st.Add(ss)
end;
end;
end;
finally
XML.Active := False;
end;
Result:=st;
end;
function ExtractZipToStr(const ZipFileName: string; const ZippedFileName, ExtractedFileName: string): widestring;
var
ZipFile: TZipFile;
F,s:string;
i:integer;
Exists:Boolean;
LStream: TStream;
FStream:TFileStream;
LocalHeader: TZipHeader;
begin
Exists:=False;
ZipFile := TZipFile.Create;
LStream := TStream.Create;
try
try
ZipFile.Open(ZipFileName,zmRead);
except on EZipException do begin Result:='noprops'; ZipFile.Close; ZipFile.Free; LStream.Free; exit; end; end;
for i := 0 to ZipFile.FileCount - 1 do
begin
F:= ZipFile.FileNames[i];
if F='docProps/custom.xml' then begin Exists:=True; system.Break; end;
end;
if exists=True then
begin
ZipFile.Read(ZippedFileName, LStream, LocalHeader);
LStream.Position:=0;
Result:=StreamToString(LStream);
end
else Result:='noprops';
finally
ZipFile.Close;
ZipFile.Free;
LStream.Free;
end;
end;
function StreamToString(aStream: TStream): widestring;
var
SS: TStringStream;
begin
if aStream <> nil then
begin
SS := TStringStream.Create('');
try
SS.CopyFrom(aStream, 0);
Result := SS.DataString;
finally
SS.Free;
end;
end else
begin
Result := '';
end;
end;
This is relatively fast but as not as much as I would like. Hopefully I have shown that (being amateur at this) I am at the end of my wits. Would you see any way to either improve or utterly replace these routines by something more efficient?

Getting JPEG Error #42 when trying to add new record

I have figured out how to store and retrieve a JPEG file in my database. If the JPEG file is there, I can easily edit it, but if I try to enter a new record, I always get JPEG Error #42. Here are my code snippets. I use btnLabelGetClick to upload an image to the stream to be posted.
procedure TfrmWines.AutoSetDataChange(Sender: TObject; Field: TField);
var
JPG: TJPEGImage;
ms: TMemoryStream;
begin
JPG := TJPEGImage.Create;
ms := TMemoryStream.Create;
try
TBlobField(wdatamod.mywines.FieldByName('winelabel')).SaveToStream(ms);
ms.Position := 0;
JPG.LoadFromStream(ms);
Image1.Picture.Assign(JPG);
finally
JPG.Free;
ms.Free;
end;
end;
procedure TfrmWines.btnAddClick(Sender: TObject);
begin
ButtonsEnter;
//btnLabelGet.Click;
wdatamod.mywines.Insert;
edWinename.SetFocus;
end;
procedure TfrmWines.btnLabelGetClick(Sender: TObject);
begin
if OpenPictureDialog1.Execute(Self.Handle) then
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;
I solved this AND coded the way to add a standing image for all new records if I don't have an image I want to use:
if autoset.DataSet.State = dsInsert then
begin
image1.Picture.Graphic.LoadFromFile('q:\sourcecode\mycellar\images\blk_wht_glass.jpg');
Exit;
end;
Here is the new code that prevents the JPEG Error #42 on adding a new record
procedure TfrmWines.AutoSetDataChange(Sender: TObject; Field: TField);
var
JPG:TJPEGImage;
ms:TMemoryStream;
begin
if autoset.DataSet.State = dsInsert then
begin
image1.Picture.Graphic.LoadFromFile('q:\sourcecode\mycellar\images\blk_wht_glass.jpg');
Exit;
end;
begin
JPG:=TJPEGImage.Create;
ms:=TMemoryStream.Create;
try
TBlobField(wdatamod.mywines.FieldByName('winelabel')).SaveToStream(ms);
ms.Position := 0;
JPG.LoadFromStream(ms);
Image1.Picture.Assign(JPG);
finally
JPG.Free;
ms.Free;
end;
end;
end;
If your BLOB field is empty, there is no data to load into TJPEGImage. You need to check for that condition before calling LoadFromStream().
Also, I suggest using TDataSet.CreateBlobStream() instead of using TBlobStream.SaveToStream() to make a copy of the BLOB data in memory. Let TJPEGImage read the data directly from the database, the DataSet knows how to read/write BLOB data using streams.
Try something more like this:
procedure TfrmWines.AutoSetDataChange(Sender: TObject; Field: TField);
var
Fld: TField;
JPG: TJPEGImage;
strm: TStream;
begin
Fld := wdatamod.mywines.FieldByName('winelabel');
if (Fld.DataSet.State = dsInsert) or (TBlobField(Fld).BlobSize = 0) then
begin
Image1.Picture.LoadFromFile('q:\sourcecode\mycellar\images\blk_wht_glass.jpg');
end else
begin
JPG := TJPEGImage.Create;
try
strm := Fld.DataSet.CreateBlobStream(Fld, bmRead);
try
JPG.LoadFromStream(strm);
finally
strm.Free;
end;
Image1.Picture.Assign(JPG);
finally
JPG.Free;
end;
end;
end;
Alternatively:
procedure TfrmWines.AutoSetDataChange(Sender: TObject; Field: TField);
var
Fld: TField;
JPG: TJPEGImage;
strm: TStream;
begin
Fld := wdatamod.mywines.FieldByName('winelabel');
if TBlobField(Fld).BlobSize > 0 then
begin
JPG := TJPEGImage.Create;
try
strm := Fld.DataSet.CreateBlobStream(Fld, bmRead);
try
JPG.LoadFromStream(strm);
finally
strm.Free;
end;
Image1.Picture.Assign(JPG);
finally
JPG.Free;
end;
end else
begin
Image1.Picture.LoadFromFile('q:\sourcecode\mycellar\images\blk_wht_glass.jpg');
end;
end;

Delphi - Reading from a log file that changes every second

I need to read from a .log file that is constantly changing by another application. (more data being added frequently)
So I have this to begin with:
var
LogFile: TStrings;
Stream: TStream;
begin
LogFile := TStringList.Create;
try
Stream := TFileStream.Create(Log, fmOpenRead or fmShareDenyNone);
try
LogFile.LoadFromStream(Stream);
finally
Stream.Free;
end;
while LogFile.Count > Memo1.Lines.Count do
Memo1.Lines.Add(LogFile[Memo1.Lines.Count]);
finally
LogFile.Free;
end;
end;
This works perfectly fine. It updates the memo at real time with the data being added. However some of the data being added I don't want to see in the memo. I wish to not add these lines, but still have the memo updated at real time without the junk lines.
What is the best way to go about this?
You'd clearly need to check to see if the line has content you want to include, and only add it if it has that content (or not add it if you don't want to include it, whichever is the case). It would also be much more efficient to keep track of the last line in the LogFile you processed previously, so you could skip those lines each time - if you make the variable a private member of the form itself, it will automatically be initialized to 0 when your application starts:
type
TForm1 = class(TForm)
//... other stuff added by IDE
private
LastLine: Integer;
end;
// At the point you need to add the logfile to the memo
for i := LastLine to LogFile.Count - 1 do
begin
if ContentWanted(LogFile[i]) then
Memo1.Lines.Append(LogFile[i]);
Inc(LastLine);
end;
So to handle this completely based on your code:
type
TForm1 = class(TForm)
//... IDE stuff here
private
FLastLogLine: Integer;
procedure ProcessLogFile;
public
// Other stuff
end;
procedure TForm1.ProcessLogFile;
var
Log: TStringList;
LogStream: TFileStream;
i: Integer;
begin
Log := TStringList.Create;
try
LogStream := TFileStream.Create(...);
try
Log.LoadFromStream(LogStream);
finally
LogStream.Free;
end;
for i := FLastLogLine to Log.Count - 1 do
if Pos('[Globals] []', Log[i]) <>0 then
Memo1.Lines.Append(Log[i]);
// We've now processed all the lines in Log. Save
// the last line we processed as the starting point
// for the next pass.
FLastLogLine := Log.Count - 1;
finally
Log.Free;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
ProcessLogFile;
finally
Timer1.Enabled := True;
end;
end;
end;
I know its been a couple of weeks since i last posted here, but i rewrote the entire application and came up with this piece of code, which is working perfectly!
Basically i do not call .free on the stream or stringlist and am able to set the initial stream size then check if its changed, hence getting the data i need and not the entire file!
Thanks everyone for helping!
procedure TForm1.GetEndLogFile;
begin
LogFile := TStringList.Create;
Stream := TFileStream.Create('C:\Users\John\Documents\chat.log', fmOpenRead or fmShareDenyNone);
LogFile.LoadFromStream(Stream);
i := Stream.Size;
end;
procedure TForm1.LogFileRefresh;
var
buf: string;
begin
if i <> Stream.Size then
begin
SetLength(buf, Stream.Size);
Stream.Seek(i, Stream.Size);
Stream.Read(buf[1], Stream.Size);
i := Stream.Size;
Memo1.Lines.Append(Buf);
//ShowMessage(buf);
end;
end;
procedure TForm1.GetEndLogFile;
var
LogFile: TStrings;
Stream: TStream;
begin
LogFile := TStringList.Create;
try
Stream := TFileStream.Create(LogFile, fmOpenRead or fmShareDenyNone);
try
LogFile.LoadFromStream(Stream);
EndOfFile := LogFile.Count;
finally
Stream.Free;
end;
finally
LogFile.Free;
end;
end;
procedure TForm1.LogFileRefresh;
var
LogFile2: TStrings;
Stream2: TStream;
i: Integer;
begin
LogFile2 := TStringList.Create;
try
Stream2 := TFileStream.Create(LogFile, fmOpenRead or fmShareDenyNone);
try
LogFile2.LoadFromStream(Stream2);
finally
Stream2.Free;
end;
for i := EndOfFile to LogFile2.Count -1 do
begin
if Pos('[Globals] []',LogFile2[i])<>0 then
Memo1.Lines.Append(LogFile2[i]);
Inc(EndOfFile);
end;
finally
LogFile2.Free
end;
end;
Basically came up with this, and its working perfectly fine. Should i run into any problems this way? Is there a neater way to do this?

How to display BLOB Image from database in the TAdvStringGrid with the help of DataSet

I have been making an application at Delphi XE3. I am trying to display values from database to the TAdvStringGrid component placed on the form. I am using dataset to display results at TAdvSTringGRid (code is given below). All other values are displaying perfectly except Image in database. Where it is expected to show image, it is showing junk characters. How to display image perfectly from DataBase at TAdvStringGrid.
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;
Call to ShowSelectResult below
procedure 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;
Problem is at the else if i=4 loop in the above code at sg.CreatePicture (format of the CreatePicture procedure is given below), where I want to display image in that particular column.
In manual of TAdvStringGrid they have mentioned following methods for picture display at grid cells
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’;
But there is no mention about how to use it with DataSet.I am messing with CreatePicture procedure of TAdvStringGRid, not getting it worked out with DataSet.
Latest Development
Finally I find out way with the help of some scholars like Bummi to save the JPEG image into memorystream and then display same.
My latest code is as follows
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;
Now it's facing some memory issue according to me at the line Jpg.LoadFromStream(Stream);
It is error code JPEG Error #53 , I came to know that above such error code display only when image you are trying to access via memorystream is corrupted but I have made sure image is not corrupted and displaying properly with the help of other software extracted from similar database. I also have renewed the image in the database. Still why I am getting JPEG Error #53. Problem is mainly at Jpg.LoadFromStream(Stream)
Note that the with commented code
Jpg.LoadFromFile('C:\Sample Pictures\Cabo.jpg');
Picture.Assign(Jpg);
sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
When it is extracted from static file it works perfectly. Problem is only with the MemoryStream. How to rectify this error?
CreateBlobStream is creating a TStream object, not a TMemoryStream.
Since you do not want to write the JPG to the database you should use bmRead instead of bmReadWrite.
I am not used to SQLite, but you will have to make sure that you are using a suitable binary datetype (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;
To ensure that the stored image is really a JPG you should write the JPG for testing with something like:
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;
I realize this is a tad late, but I wanted to contribute. I quite simply did the following, having not to worry about the image format (.jpg, .png etc.). I simply create a TStream object, load the BLOB stream into it, and then I load the Image from the stream. Short and sweet, and it works great for me.
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;

retrieve image saved on database [duplicate]

This question already has answers here:
How to insert image into database using TADOQuery Component Only
(2 answers)
Store images in MS-Access Database using Delphi6
(1 answer)
Closed 10 years ago.
I'm using this code to load images into my Timage:
begin
if OpenPictureDialog1.Execute(Self.Handle) then
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;
Then I'm using this code to store into my ms access database:
var
AStream : TMemoryStream;
begin
Adotable1.Append;
AStream := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(AStream);
AStream.Position := 0;
if Adotable1.Active then
begin
TBlobField(Adotable1.FieldByName('Termograma')).LoadFromStream(AStream);
end;
finally
AStream.Free;
end;
adotable1.Post;
But now I want to display these saved images on a Timage, can anyone help me?
The images are .jpeg format
As far as TPicture is not able to decide which kind of TGraphic it has to create for loading, since a stream does not have an extension like a filename you have to decide it, and assign the Graphic.
In this case a TJPEGImage to the Picture.
var
JPG:TJPEGImage;
ms:TMemoryStream;
begin
JPG:=TJPEGImage.Create;
ms:=TMemoryStream.Create;
try
TBlobField(AdoTable1.FieldByName('Termograma')).SaveToStream(ms);
ms.Position := 0;
JPG.LoadFromStream(ms);
Image2.Picture.Assign(JPG);
finally
JPG.Free;
ms.Free;
end;
end;
The following unit is able to store diffent graphicformats in blobfields.
Storage is not compatible to simple storing of image data because information about then graphicformat is stored too, to give the ability to create the needed class for loading.
unit LoadSaveImageBlobs;
// 20120224 by Thomas Wassermann
// Adapt. RegisterClasses and uses for your requirements
// based on an Idea of Emiliano Sos
interface
uses Classes,DB,Graphics,Jpeg,PngImage;
Procedure SavePicture2Blob(Blob: TBlobField; Picture: TPicture);
Procedure LoadPictureFromBlob(Picture: TPicture; Blob: TBlobField);
implementation
Procedure SavePicture2Blob(Blob: TBlobField; Picture: TPicture);
var
ms, ms2: TMemoryStream;
theClassName: AnsiString;
len: Byte;
begin
ms := TMemoryStream.Create;
try
Blob.Clear;
theClassName := Picture.Graphic.ClassName;
len := Length(theClassName);
ms.WriteBuffer(len, 1);
if len > 0 then
ms.WriteBuffer(theClassName[1], len);
ms2 := TMemoryStream.Create;
try
Picture.Graphic.SaveToStream(ms2);
ms2.Position := 0;
if ms2.Size > 0 then
ms.CopyFrom(ms2, ms2.Size);
finally
ms2.Free;
end;
Blob.LoadFromStream(ms);
finally
ms.Free;
end;
end;
Procedure LoadPictureFromBlob(Picture: TPicture; Blob: TBlobField);
var
ms, ms2: TMemoryStream;
len: Byte;
theClassName: AnsiString;
Graphic: TGraphic;
GraphicClass: TGraphicClass;
begin
ms := TMemoryStream.Create;
Blob.SaveToStream(ms);
ms.Position := 0;
try
ms.ReadBuffer(len, 1);
SetLength(theClassName, len);
if len > 0 then
ms.ReadBuffer(theClassName[1], len);
GraphicClass := TGraphicClass(FindClass(theClassName));
if (GraphicClass <> nil) and (len > 0) then
begin
Graphic := GraphicClass.Create;
ms2 := TMemoryStream.Create;
try
ms2.CopyFrom(ms, ms.Size - len - 1);
ms2.Position := 0;
Graphic.LoadFromStream(ms2);
finally
ms2.Free;
end;
Picture.Assign(Graphic);
end;
finally
ms.Free;
end;
end;
initialization
// you might register others if wished
RegisterClasses([TIcon, TMetafile, TBitmap, TJPEGImage,TPngImage]);
end.

Resources