Delphi7: не удается загрузить JPEG из записи, но можно загрузить его непосредственно из базы данных

#delphi #blob #jpeg #record

Вопрос:

Прежде всего, я использую следующую запись:

 type
  TCarouselPhotos = record
    cpDescription:  String;
    cpDurationSec:  Integer;
    cpPhotograph:   TJPEGImage;
    cpOrder:     Integer;
  end;
 

Эта запись используется в следующем массиве:

 CarouselPhotoArray: array of TCarouselPhotos;
 

И теперь я пытаюсь загрузить данные из базы данных в этот массив:

 CarouselPhotoArray[0].cpPhotograph:= getImageFromBlob;
 

И это та функция, которую я использую:

 function TFormMain.getImageFromBlob: TJPEGImage;
var tmpStream: TMemoryStream;
    tmpJPEG: TJPEGImage;
begin
  tmpStream := TMemoryStream.Create;
  tmpJPEG   := TJPEGImage.Create;
  try
    TBlobField(QueryTemp.FieldByName('Afbeelding')).SaveToStream(tmpStream);
    tmpStream.Position := 0;
    tmpJPEG.LoadFromStream(tmpStream);
    If tmpStream.Size > 0
      then Result := tmpJPEG  // note: when I try "image1.picture.graphic := tmpJPEG" it works!
      else Result := nil;
  finally
    tmpStream.Free;
    tmpJPEG.Free;
  end;
end;
 

Почему-то я не получаю никаких ошибок, но как только я попытаюсь отобразить изображение, оно вызовет ошибку нарушения доступа…

 Image1.Picture.Graphic := CarouselPhotoArray[0].cpPhotograph;
 

Что здесь может пойти не так? Пожалуйста, помогите.

Комментарии:

1. Вы присваиваете результат getImageFromBlob записи карусели, но вы вызываете Free на tmpJPEG, поэтому запись карусели указывает на свободную память. Выполнение Result := tmpJPEG не создает копию объекта JPEG.

2. Должен ли я просто удалить строку, которая освобождает память, или я должен решить эту проблему другим способом, чтобы она работала и была чистой?

3. Что ж, есть несколько способов сделать это, но поскольку JPEG в каждой записи CarouselPhotos должен сохраняться, пока запись используется, удаление tmpJPEG.Fee строки было бы наиболее простым. Вам понадобится какой-то код, чтобы освободить каждую карусельную фотографию. Cpphotography, когда он больше не нужен.

4. Спасибо! Я исправил это так, как вы изначально описали.

5. Всякий раз, когда у вас есть функция, возвращающая какой-либо объект в результате, вы не должны освобождать этот объект из самой функции. Время жизни рассматриваемого объекта должно превышать время выполнения указанного метода, поэтому об освобождении объекта в рамках указанного метода не может быть и речи. . Но вам все равно нужно уничтожить указанный объект после того, как вы закончите его использовать. В таких случаях это будет сделано через некоторое время после выполнения вашей функции.