将JPEG分配给TJPEGImages数组时,为什么会出现访问冲突?

时间:2017-04-07 14:58:57

标签: delphi jpeg access-violation assign timage

  Formulae: array [1..6] of TJPEGImage;

我有一个数组,我想在其中分配图像,以便我可以将它们显示在表单上。我使用了JPEG data-stream to TImage问题中的类似代码,但我在if语句中收到了访问冲突错误消息

procedure Tfrm_calc2.ChangeDisplay(ImgNo: Integer; NewImage: Boolean);
var
  TempImg: TJPEGImage;
begin
  TempImg:= TJPEGImage.Create;
  TempImg.LoadFromFile('C2F'+inttostr(ImgNo)+'.jpg');
  img_Formulae.Picture.Assign(TempImg);

 // assigning each picture to an element in array if it is the first time. This will be used to save the pictures later on
  If NewImage = True then Formulae[ImgNo].Assign(TempImg);


  TempImg.Free;
  ImgDisplayed:= ImgNo;

  lbl_FormulaDisplay.Caption:= 'Formula ' + inttostr(ImgNo); //user can see which formula can be seen
end;

感谢。

3 个答案:

答案 0 :(得分:2)

在调用Assign之前,您是否使用已分配的对象填充数组?可能不是。尝试更像这样的东西:

procedure Tfrm_calc2.ChangeDisplay(ImgNo: Integer);
var
  TempImg: TJPEGImage;
begin
  TempImg := TJPEGImage.Create;
  try
    TempImg.LoadFromFile('C2F'+IntToStr(ImgNo)+'.jpg');
    img_Formulae.Picture.Assign(TempImg);

    if Formulae[ImgNo] = nil then
    begin
      Formulae[ImgNo] := TempImg;
      TempImg := nil;
    end else
      Formulae[ImgNo].Assign(TempImg);
  finally
    TempImg.Free;
  end;
  ImgDisplayed := ImgNo;
  lbl_FormulaDisplay.Caption := 'Formula ' + IntToStr(ImgNo);
end;

可替换地:

procedure Tfrm_calc2.ChangeDisplay(ImgNo: Integer);
var
  TempImg: TJPEGImage;
begin
  TempImg := TJPEGImage.Create;
  try
    TempImg.LoadFromFile('C2F'+IntToStr(ImgNo)+'.jpg');
    img_Formulae.Picture.Assign(TempImg);

    FreeAndNil(Formulae[ImgNo]);
    Formulae[ImgNo] := TempImg;
  except
    TempImg.Free;
    raise;
  end;
  ImgDisplayed := ImgNo;
  lbl_FormulaDisplay.Caption := 'Formula ' + IntToStr(ImgNo);
end;

答案 1 :(得分:0)

Formulae[ImgNo].Assign(TempImg);

这是尝试将图片分配给已创建的对象。但是,您的对象很可能尚未创建,因为我认为无法在上面的代码中初始化它们。 Assign要求对象已创建

在你的情况下,理想的做法是在启动时,确保事先在数组中创建所有这些对象。然后,也一定要在结束时销毁它们。

您的整个代码可以像......一样简单。

procedure Tfrm_calc2.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  for I := Low(Formulae) to High(Formulae) do begin
    Formulae[I] := TJpegImage.Create;
  end;
end;

procedure Tfrm_calc2.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  for I := Low(Formulae) to High(Formulae) do begin
    FreeAndNil(Formulae[I]);
  end;
end;

procedure Tfrm_calc2.ChangeDisplay(ImgNo: Integer);
begin
  Formulae[ImgNo].LoadFromFile('C2F'+IntToStr(ImgNo)+'.jpg');
  ImgDisplayed:= ImgNo;
  lbl_FormulaDisplay.Caption:= 'Formula ' + IntToStr(ImgNo);
end;

无需加载其他实例并进行分配。只需直接加载文件即可。

答案 2 :(得分:0)

来自Embarcadero VCL参考

  

调用“分配”以复制一个对象的属性或其他属性   来自另一个人。

因此必须在调用Assign

之前创建目标类

另一个建议是先创建一个TJpegImage类的实例,然后将它分配给你的temp TJpegImage,如下所示:

var
 JPegArray : array[0..10] of TJPEGImage;

...

var
 JPeg : TJPEGImage;
begin
 JPeg := TJPEGImage.Create;
 JPeg.LoadFromFile('C:/M.jpg');

 JPegArray[1] := TJPEGImage.Create;
 JPegArray[1].Assign(JPeg);

 JPeg.Free;

 Image1.Picture.Assign(JPegArray[1]);

 ...

end;