Discussion:
using TBlobfield getting "Bitmap image is not valid"
(too old to reply)
buddy
2009-06-21 21:12:50 UTC
Permalink
{using D3}

I spent many hours searching for how to save a jpeg to a blob field in
a table. Here is the closest I've gotten:

var
Jpg: TJpegImage;
Stream: TMemoryStream;
begin
Jpg := nil;
Stream := nil;
with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Stream := TMemoryStream.Create;
Jpg.LoadFromFile(FileName);
Jpg.SaveToStream(Stream);
Stream.Position := 0;
TBlobfield(mainform.tblItems.FieldByName('item-
photo')).LoadFromStream(Stream);

At this point I get the error 'Bitmap image is not valid'

But I test using table.field,IsNull and "something" was stored. I try
to retrieve whatever was stored using:

var
bS : TBlobStream;
Jpg : TJpegImage;
begin
bS := TBlobStream.Create(table1photo, bmRead);

At this point I get the error "Invalid Class Typecast"

What am I doing wrong?

Buddy
Jamie
2009-06-21 23:49:13 UTC
Permalink
Post by buddy
{using D3}
I spent many hours searching for how to save a jpeg to a blob field in
var
Jpg: TJpegImage;
Stream: TMemoryStream;
begin
Jpg := nil;
Stream := nil;
with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Stream := TMemoryStream.Create;
Jpg.LoadFromFile(FileName);
Jpg.SaveToStream(Stream);
Stream.Position := 0;
TBlobfield(mainform.tblItems.FieldByName('item-
photo')).LoadFromStream(Stream);
At this point I get the error 'Bitmap image is not valid'
But I test using table.field,IsNull and "something" was stored. I try
var
bS : TBlobStream;
Jpg : TJpegImage;
begin
bS := TBlobStream.Create(table1photo, bmRead);
At this point I get the error "Invalid Class Typecast"
What am I doing wrong?
Buddy
Try setting the Blobtype property to BLOB, it maybe at GRaphic, and that
is normally a bitmap.

ftBlob will indicate a large object field which means it can store
anything.
Jpegs are not in the list of specific types.
BRoberts
2009-06-22 04:37:51 UTC
Permalink
Post by buddy
{using D3}
I spent many hours searching for how to save a jpeg to a blob field in
var
Jpg: TJpegImage;
Stream: TMemoryStream;
begin
Jpg := nil;
Stream := nil;
with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Stream := TMemoryStream.Create;
Jpg.LoadFromFile(FileName);
Jpg.SaveToStream(Stream);
Stream.Position := 0;
TBlobfield(mainform.tblItems.FieldByName('item-
photo')).LoadFromStream(Stream);
At this point I get the error 'Bitmap image is not valid'
But I test using table.field,IsNull and "something" was stored. I try
var
bS : TBlobStream;
Jpg : TJpegImage;
begin
bS := TBlobStream.Create(table1photo, bmRead);
At this point I get the error "Invalid Class Typecast"
You might try something like

var pic : tJPEGImage;
bs : tStream;

. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .

. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
buddy
2009-06-22 19:27:27 UTC
Permalink
Jamie you were right, it was ftGraphic, I changed it to ftBlob. Did
not fix the problem but maybe I have multiple problems so I left it
ftBlob.

BRoberts, you got me MUCH further, but still errors. Here's where I
am now:

SAVING the image:

current code:

var
Jpg: TJpegImage;
Stream: TStream;
...

with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(FileName);

Stream := mainform.tblItems.CreateBlobStream
(mainform.tblItems.FieldByName('item-photo'),bmWrite);
Stream.Position := 0;
Jpg.SaveToStream(Stream);

I still get the "Bitmap image is not valid" error. But here are 3
things that might give a clue to someone with more programming
knowledge than I (hobbyist)

1. Right after the last line above, I put showmessage('got past this
line');
I get the message first, and then the error. But there's nothing of
consequence in the rest of the procedure that would cause an error,
just the end of some try-finally and try-except blocks, with things
like Jpg.Free, Stream.Free, Free.

2. After the above line I put: Jpg.SaveToFile('c:\tmp\mytest.jpg');

Then I tried to open mytest.jpg with my graphics viewer, IrfanView,
and .... it opened fine! Displays correctly, no complaints from
IrfanView. ??

3. This code is on a showmodal form (that's what I've always done, not
sure I know how to do it non-showmodal), called from the main form
like this:

with TformItemAdd.Create(Self) do
try
srcItems.DataSet.Append;
ShowModal;
finally
Free;
end;
srcItems.Dataset.Refresh;

When Delphi breaks for the error, Delphi switches focus to the main
form code listing, with the little green arrow on the left pointing to
the ShowModal line.

RETREIVING the image:

current code:

var
bs : TStream;
Jpg : TJpegImage;
....

bs := tblItems.CreateBlobStream (tblItems.FieldByName('item-
photo'), bmRead);
Jpg := TJpegImage.Create;
Jpg.LoadFromStream(bs); // error here: JPeg Error #53
imageItems.Picture.Assign(Jpg);

No more "typecast" error! But on the line indicated above I get "JPeg
Error #53" and it never gets to the last line.

sigh...

Buddy
Post by BRoberts
You might try something like
var  pic  : tJPEGImage;
     bs   : tStream;
. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .
. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
Jamie
2009-06-22 22:43:09 UTC
Permalink
Post by buddy
Jamie you were right, it was ftGraphic, I changed it to ftBlob. Did
not fix the problem but maybe I have multiple problems so I left it
ftBlob.
BRoberts, you got me MUCH further, but still errors. Here's where I
var
Jpg: TJpegImage;
Stream: TStream;
...
with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(FileName);
Stream := mainform.tblItems.CreateBlobStream
(mainform.tblItems.FieldByName('item-photo'),bmWrite);
Stream.Position := 0;
Jpg.SaveToStream(Stream);
I still get the "Bitmap image is not valid" error. But here are 3
things that might give a clue to someone with more programming
knowledge than I (hobbyist)
1. Right after the last line above, I put showmessage('got past this
line');
I get the message first, and then the error. But there's nothing of
consequence in the rest of the procedure that would cause an error,
just the end of some try-finally and try-except blocks, with things
like Jpg.Free, Stream.Free, Free.
2. After the above line I put: Jpg.SaveToFile('c:\tmp\mytest.jpg');
Then I tried to open mytest.jpg with my graphics viewer, IrfanView,
and .... it opened fine! Displays correctly, no complaints from
IrfanView. ??
3. This code is on a showmodal form (that's what I've always done, not
sure I know how to do it non-showmodal), called from the main form
with TformItemAdd.Create(Self) do
try
srcItems.DataSet.Append;
ShowModal;
finally
Free;
end;
srcItems.Dataset.Refresh;
When Delphi breaks for the error, Delphi switches focus to the main
form code listing, with the little green arrow on the left pointing to
the ShowModal line.
var
bs : TStream;
Jpg : TJpegImage;
....
bs := tblItems.CreateBlobStream (tblItems.FieldByName('item-
photo'), bmRead);
Jpg := TJpegImage.Create;
Jpg.LoadFromStream(bs); // error here: JPeg Error #53
imageItems.Picture.Assign(Jpg);
No more "typecast" error! But on the line indicated above I get "JPeg
Error #53" and it never gets to the last line.
sigh...
Buddy
Post by BRoberts
You might try something like
var pic : tJPEGImage;
bs : tStream;
. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .
. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
Try creating a TBobField.

Var
B:TBlobField;
Begin
B := TBlobField.Create(..);
B. BlobType := ftBlob;

from here,. you save the Jpg into this Blob, then assign it to the
dbase feild.
etc..
P.S.
you may need to Free this blob once you're done with it.

I haven't tested this my self but it's a good place to start.
buddy
2009-06-23 01:10:36 UTC
Permalink
On Jun 22, 4:43 pm, Jamie
Post by Jamie
Jamie you were right, it was ftGraphic, I changed it to ftBlob.  Did
not fix the problem but maybe I have multiple problems so I left it
ftBlob.
BRoberts, you got me MUCH further, but still errors.  Here's where I
var
  Jpg: TJpegImage;
  Stream: TStream;
...
with TOpenDialog.Create(self) do
    try
      Filter := '.jpg files (*.jpg)|*.jpg';
      if Execute then
        begin
          try
            Jpg := TJpegImage.Create;
            Jpg.LoadFromFile(FileName);
            Stream := mainform.tblItems.CreateBlobStream
(mainform.tblItems.FieldByName('item-photo'),bmWrite);
            Stream.Position := 0;
            Jpg.SaveToStream(Stream);
I still get the "Bitmap image is not valid" error.  But here are 3
things that might give a clue to someone with more programming
knowledge than I (hobbyist)
1. Right after the last line above, I put showmessage('got past this
line');
I get the message first, and then the error.  But there's nothing of
consequence in the rest of the procedure that would cause an error,
just the end of some try-finally and try-except blocks, with things
like Jpg.Free, Stream.Free, Free.
2. After the above line I put: Jpg.SaveToFile('c:\tmp\mytest.jpg');
Then I tried to open mytest.jpg with my graphics viewer, IrfanView,
and .... it opened fine!  Displays correctly, no complaints from
IrfanView.  ??
3. This code is on a showmodal form (that's what I've always done, not
sure I know how to do it non-showmodal), called from the main form
 with TformItemAdd.Create(Self) do
    try
      srcItems.DataSet.Append;
      ShowModal;
    finally
      Free;
    end;
  srcItems.Dataset.Refresh;
When Delphi breaks for the error, Delphi switches focus to the main
form code listing, with the little green arrow on the left pointing to
the ShowModal line.
var
  bs  : TStream;
  Jpg : TJpegImage;
....
   bs := tblItems.CreateBlobStream (tblItems.FieldByName('item-
photo'), bmRead);
   Jpg := TJpegImage.Create;
   Jpg.LoadFromStream(bs);            // error here:  JPeg Error #53
   imageItems.Picture.Assign(Jpg);
No more "typecast" error!  But on the line indicated above I get "JPeg
Error #53" and it never gets to the last line.
sigh...
Buddy
Post by BRoberts
You might try something like
var  pic  : tJPEGImage;
    bs   : tStream;
. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .
. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
Try creating a TBobField.
Var
  B:TBlobField;
Begin
  B := TBlobField.Create(..);
  B. BlobType := ftBlob;
   from here,. you save the Jpg into this Blob, then assign it to the
dbase feild.
etc..
  P.S.
   you may need to Free this blob once you're done with it.
I haven't tested this my self but it's a good place to start.
How do I save the Jpg into the blob? Jpg doesn't have a
savetoblobfield method. Would I savetofile then B.loadfromfile ?
Jamie
2009-06-23 01:38:04 UTC
Permalink
On Jun 22, 4:43 pm, Jamie
Post by Jamie
Post by buddy
Jamie you were right, it was ftGraphic, I changed it to ftBlob. Did
not fix the problem but maybe I have multiple problems so I left it
ftBlob.
BRoberts, you got me MUCH further, but still errors. Here's where I
var
Jpg: TJpegImage;
Stream: TStream;
...
with TOpenDialog.Create(self) do
try
Filter := '.jpg files (*.jpg)|*.jpg';
if Execute then
begin
try
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(FileName);
Stream := mainform.tblItems.CreateBlobStream
(mainform.tblItems.FieldByName('item-photo'),bmWrite);
Stream.Position := 0;
Jpg.SaveToStream(Stream);
I still get the "Bitmap image is not valid" error. But here are 3
things that might give a clue to someone with more programming
knowledge than I (hobbyist)
1. Right after the last line above, I put showmessage('got past this
line');
I get the message first, and then the error. But there's nothing of
consequence in the rest of the procedure that would cause an error,
just the end of some try-finally and try-except blocks, with things
like Jpg.Free, Stream.Free, Free.
2. After the above line I put: Jpg.SaveToFile('c:\tmp\mytest.jpg');
Then I tried to open mytest.jpg with my graphics viewer, IrfanView,
and .... it opened fine! Displays correctly, no complaints from
IrfanView. ??
3. This code is on a showmodal form (that's what I've always done, not
sure I know how to do it non-showmodal), called from the main form
with TformItemAdd.Create(Self) do
try
srcItems.DataSet.Append;
ShowModal;
finally
Free;
end;
srcItems.Dataset.Refresh;
When Delphi breaks for the error, Delphi switches focus to the main
form code listing, with the little green arrow on the left pointing to
the ShowModal line.
var
bs : TStream;
Jpg : TJpegImage;
....
bs := tblItems.CreateBlobStream (tblItems.FieldByName('item-
photo'), bmRead);
Jpg := TJpegImage.Create;
Jpg.LoadFromStream(bs); // error here: JPeg Error #53
imageItems.Picture.Assign(Jpg);
No more "typecast" error! But on the line indicated above I get "JPeg
Error #53" and it never gets to the last line.
sigh...
Buddy
Post by BRoberts
You might try something like
var pic : tJPEGImage;
bs : tStream;
. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .
. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
Try creating a TBobField.
Var
B:TBlobField;
Begin
B := TBlobField.Create(..);
B. BlobType := ftBlob;
from here,. you save the Jpg into this Blob, then assign it to the
dbase feild.
etc..
P.S.
you may need to Free this blob once you're done with it.
I haven't tested this my self but it's a good place to start.
How do I save the Jpg into the blob? Jpg doesn't have a
savetoblobfield method. Would I savetofile then B.loadfromfile ?
Move it to a TmemoryStream, then from there to the BlobFeild etc..
BRoberts
2009-06-23 02:38:46 UTC
Permalink
Post by buddy
I still get the "Bitmap image is not valid" error. But here are 3
things that might give a clue to someone with more programming
knowledge than I (hobbyist)
1. Right after the last line above, I put showmessage('got past this
line');
I get the message first, and then the error. But there's nothing of
consequence in the rest of the procedure that would cause an error,
just the end of some try-finally and try-except blocks, with things
like Jpg.Free, Stream.Free, Free.
2. After the above line I put: Jpg.SaveToFile('c:\tmp\mytest.jpg');
Then I tried to open mytest.jpg with my graphics viewer, IrfanView,
and .... it opened fine! Displays correctly, no complaints from
IrfanView. ??
This indicates to me that the error is being generated in code that follows
the show message. Place a breakpoint on the savetostream line then step
through the code until you isolate the line that generates the error.
Post by buddy
3. This code is on a showmodal form (that's what I've always done, not
sure I know how to do it non-showmodal), called from the main form
with TformItemAdd.Create(Self) do
try
srcItems.DataSet.Append;
ShowModal;
finally
Free;
end;
srcItems.Dataset.Refresh;
When Delphi breaks for the error, Delphi switches focus to the main
form code listing, with the little green arrow on the left pointing to
the ShowModal line.
My tendancy would be to put the appen in the same code unit that does the
Post or Cancel.

BTW one can also use the blob field directly to load the jpeg file, e.g.

tBlobField (tblItems.FieldByName ('item-photo')).LoadFromFile
('picFileName');
Post by buddy
var
bs : TStream;
Jpg : TJpegImage;
....
bs := tblItems.CreateBlobStream (tblItems.FieldByName('item-
photo'), bmRead);
Jpg := TJpegImage.Create;
Jpg.LoadFromStream(bs); // error here: JPeg Error #53
imageItems.Picture.Assign(Jpg);
No more "typecast" error! But on the line indicated above I get "JPeg
Error #53" and it never gets to the last line.
sigh...
The error indicates an invalid image. If the image is not being saved
properly in the record one would expect an error like this, so I would
concentrate on solving the saveing to db record problem before spending any
time on this error.
Post by buddy
Post by BRoberts
You might try something like
var pic : tJPEGImage;
bs : tStream;
. . .
pic := tJPEGImage.Create;
pic.LoadFromFile ('picFileName');
// presuming tblItems.State in [dsEdit, dsInsert]
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmWrite);
pic.SaveToStream (bs);
. . .
. . .
bs := tblItems.CreateBlobStream (tblItems.FieldByName ('item-photo'),
bmRead);
pic := tJPEGImage.Create;
pic.LoadFromStream (bs);
. . .
buddy
2009-06-23 08:16:12 UTC
Permalink
Post by BRoberts
This indicates to me that the error is being generated in code that follows
the show message. Place a breakpoint on the savetostream line then step
through the code until you isolate the line that generates the error.
Did that, the line which breaks is

Stream.Free

in the FINALLY of the TRY which creates the OpenDialog
Post by BRoberts
BTW one can also use the blob field directly to load the jpeg file, e.g.
tBlobField (tblItems.FieldByName ('item-photo')).LoadFromFile
('picFileName');
Wow! that makes for much simpler code. No variables, fewer lines.

But it still gets the same error, and breaks on that line now. (the
TBlobField... line)

I should mention, right before the lines which are causing the
problem, I do:

image1.Picture.LoadFromFile(FileName);

No problem. Displays perfectly, i.e. TImage i.e. Delphi thinks the
jpg data is fine, right?

Yet gets the Delphi "Bitmap image is not valid" error when trying to
get it into the blob field of the db.
Why does Delphi think it's supposed to be a Bitmap? Since type is
ftBlob, Delphi should think it's just binary data coming in, right?
BRoberts
2009-06-24 02:11:37 UTC
Permalink
Post by buddy
Post by BRoberts
This indicates to me that the error is being generated in code that follows
the show message. Place a breakpoint on the savetostream line then step
through the code until you isolate the line that generates the error.
Did that, the line which breaks is
Stream.Free
in the FINALLY of the TRY which creates the OpenDialog
Post by BRoberts
BTW one can also use the blob field directly to load the jpeg file, e.g.
tBlobField (tblItems.FieldByName ('item-photo')).LoadFromFile
('picFileName');
Wow! that makes for much simpler code. No variables, fewer lines.
But it still gets the same error, and breaks on that line now. (the
TBlobField... line)
I should mention, right before the lines which are causing the
image1.Picture.LoadFromFile(FileName);
No problem. Displays perfectly, i.e. TImage i.e. Delphi thinks the
jpg data is fine, right?
Yet gets the Delphi "Bitmap image is not valid" error when trying to
get it into the blob field of the db.
Why does Delphi think it's supposed to be a Bitmap? Since type is
ftBlob, Delphi should think it's just binary data coming in, right?
If the field data type is ftBlob then, AFAIK, the code should not care what
is being loaded. Do you have any event handlers on the table or field?
buddy
2009-06-24 09:15:10 UTC
Permalink
Post by BRoberts
Post by buddy
Post by BRoberts
This indicates to me that the error is being generated in code that follows
the show message. Place a breakpoint on the savetostream line then step
through the code until you isolate the line that generates the error.
Did that, the line which breaks is
Stream.Free
in the FINALLY of the TRY which creates the OpenDialog
Post by BRoberts
BTW one can also use the blob field directly to load the jpeg file, e.g.
tBlobField (tblItems.FieldByName ('item-photo')).LoadFromFile
('picFileName');
Wow!  that makes for much simpler code.  No variables, fewer lines.
But it still gets the same error, and breaks on that line now. (the
TBlobField... line)
I should mention, right before the lines which are causing the
image1.Picture.LoadFromFile(FileName);
No problem.  Displays perfectly, i.e. TImage i.e. Delphi thinks the
jpg data is fine, right?
Yet gets the Delphi "Bitmap image is not valid" error when trying to
get it into the blob field of the db.
Why does Delphi think it's supposed to be a Bitmap?  Since type is
ftBlob, Delphi should think it's just binary data coming in, right?
If the field data type is ftBlob then, AFAIK, the code should not care what
is being loaded. Do you have any event handlers on the table or field?
SOLVED !! (really weird)

No event handlers. But in looking to make sure, I noticed that in the
object inspector the field item-photo was listed as TGraphicfield.
Had another blob field in the table named item-scan and it was
TBlobfield in the object inspector.

Used the db's (DBISAM) Restructure tool and deleted it, rebuilt table,
then added it back, and .. still listed as Graphicfield in the object
inspector. So deleted it, and added back with the name "itemphoto",
all one word. Now listed correctly as TBlobfield in the object
inspector.

It seems the restructure tool sees the word "photo" in the name, and
automatically adds it as a TGtaphicfield, even though it is type blob
in the grid listing of the restructure tool. Weird.

Everything working perfectly now. Thank you for keeping me headed the
right direction on this.

Buddy

buddy
2009-06-23 08:41:23 UTC
Permalink
Post by BRoberts
This indicates to me that the error is being generated in code that follows
the show message. Place a breakpoint on the savetostream line then step
through the code until you isolate the line that generates the error.
Did that, the line which breaks is

Stream.Free

in the FINALLY of the TRY which creates the OpenDialog
Post by BRoberts
BTW one can also use the blob field directly to load the jpeg file, e.g.
tBlobField (tblItems.FieldByName ('item-photo')).LoadFromFile
('picFileName');
Wow! that makes for much simpler code. No variables, fewer lines.

But it still gets the same error, and breaks on that line now. (the
TBlobField... line)

I should mention, right before the lines which are causing the
problem, I do:

image1.Picture.LoadFromFile(FileName);

No problem. Displays perfectly, i.e. TImage i.e. Delphi thinks the
jpg data is fine, right?

Yet gets the Delphi "Bitmap image is not valid" error when trying to
get it into the blob field of the db.
Why does Delphi think it's supposed to be a Bitmap? Since type is
ftBlob, Delphi should think it's just binary data coming in, right?
Loading...