2017-01-02 5 views
-1

Я выяснил, как сохранить и получить файл JPEG в моей базе данных. Если файл JPEG есть, я могу его легко отредактировать, но если я попытаюсь ввести новую запись, я всегда получаю JPEG Error # 42. Вот мои фрагменты кода. Я использую btnLabelGetClick для загрузки изображения в поток, который будет опубликован.Получение JPEG Ошибка # 42 при попытке добавить новую запись

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; 
+4

Возможный дубликат [Почему я получаю JPEG ошибка 42, когда она хранится в базе данных?] (HTTP: // StackOverflow .com/questions/12697699/why-do-i-get-jpeg-error-42-when-its-stored-in-a-database). Платит выполнение базового веб-поиска. Это было задано в той или иной форме так много раз. –

+0

Если ваше поле blob пусто, данных для загрузки в 'TJPEGImage' нет. Вы должны проверить это условие перед вызовом 'LoadFromStream'. –

+0

Я исследовал это. Исследуя это, я получил возможность получить текущий код. Я думаю, что я решил это, отключив источник данных, а затем добавив запись, и я больше не получаю JPEG Error # 42. –

ответ

0

Я решил эту проблему и закодировал способ добавить постоянное изображение для всех новых записей, если у меня нет изображения я хочу использовать:

if autoset.DataSet.State = dsInsert then 
begin 
    image1.Picture.Graphic.LoadFromFile('q:\sourcecode\mycellar\images\blk_wht_glass.jpg'); 
    Exit; 
end; 

Вот новый код, который предотвращает JPEG Error # 42 при добавлении новой записи

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

Вместо этого вам нужно использовать 'image1.Picture.LoadFromFile()'. Свойство «Graphic» недействительно до загрузки изображения. Этот код также не учитывает возможность того, что blob по-прежнему остается пустым после внесения записи. Вы все еще должны справиться с этой возможностью. –

+0

Спасибо, что тоже работает. –

+0

Не только это работает, но и безопасный и правильный способ использования 'LoadFromFile()'. Пусть 'Picture' определяет тип изображения и заполняет' Graphic' соответственно. Не предполагайте, что 'Graphic' является допустимым или всегда ожидаемым типом класса, если вы не всегда загружаете один и тот же тип изображения каждый раз. –

0

Если поле BLOB пусто, нет данных для загрузки в TJPEGImage. Перед тем, как позвонить LoadFromStream(), вам необходимо проверить это условие.

Кроме того, я предлагаю использовать TDataSet.CreateBlobStream() вместо TBlobStream.SaveToStream(), чтобы сделать копию данных BLOB в памяти. Пусть TJPEGImage считывает данные непосредственно из базы данных, DataSet знает, как читать/записывать данные BLOB с использованием потоков.

Попробуйте что-то больше, как это:

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; 

В качестве альтернативы:

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;