Getting JPEG Error #42 when trying to add new record

1k views Asked by At

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;
2

There are 2 answers

3
K Boykin On

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;
0
Remy Lebeau On

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;