1

いくつかの画像をオブジェクトリストにロードしてから、それらを呼び戻そうとします。しかし、それは画像を表示していませんか?

procedure TForm1.LoadImages(const Dir: string);
var
  i: Integer;
  CurFileName: string;
  JpgIn: TJPEGImage;
  BmpOut: TBitmap;
begin
//sets index for object list
  CurIdx := -1;
  i := 0;
  while True do
  begin
//gets current folder 
    CurFileName := Format('%s%d.jpg',
                          [IncludeTrailingPathDelimiter(Dir), i]);
    if not FileExists(CurFileName) then
      Break;
//creates jpgin
    JpgIn := TJPEGImage.Create;
    try
//loads jpgin 
      JpgIn.LoadFromFile(CurFileName);
//creates TBitmap and sets width to same as jpgs
      BmpOut := TBitmap.Create;
      bmpout.Width := jpgin.Width;
      bmpout.Height := jpgin.Height;
     try
         BmpOut.Assign(JpgIn);
//if i assign it here it works, showing last image of course
         //zimage1.Bitmap.Width := bmpout.Width;
        //zimage1.Bitmap.Height := bmpout.Height;
         //ZImage1.Bitmap.Assign(bmpout);
//adds 1 to index for object list. thus starting at 0
         curIdx := curIdx+1;
//add bitmap to objectlist
         CurIdx:= mylist.Add(TBitmap(bmpout));
      finally
//free bitmap and jpg
        BmpOut.Free;
      end;
    finally
      JpgIn.Free;
    end;
    Inc(i);
  end;
//makes sure cout is above 0  
  if mylist.Count > 0 then
  begin
//create bitmap
    BmpOut := TBitmap.Create;
      try
//sets width and heigh of bitmap before getting image
      bmpout.Height := TBitmap(mylist[curidx]).Height;
      bmpout.Width := TBitmap(mylist[curidx]).Width;
      bmpout.Assign(TBitmap(mylist[CurIdx]));
//sets zimage width height before getting image.
      zimage1.Bitmap.Width := bmpout.Width;
      zimage1.Bitmap.Height := bmpout.Height;
      ZImage1.Bitmap.Assign(bmpout);
    finally
      BmpOut.Free;
    end;
  end;
  page:= '0';
end;

あなたが気づいたら、私はそこにこの部分があり、画像をzimage1にロードすることが問題であったかどうかを確認しました。

     //zimage1.Bitmap.Width := bmpout.Width;
    //zimage1.Bitmap.Height := bmpout.Height;
     //ZImage1.Bitmap.Assign(bmpout);

私がそれをしたとき、それはbmpoutをzimage1にロードしました、それは私にそのiamが間違っているオブジェクトリストで何かを考えるように導きますか?

4

1 に答える 1

5

あなたはこのコードを持っています:

  CurIdx:= mylist.Add(TBitmap(bmpout));
finally
  //free bitmap and jpg
  BmpOut.Free;
end;

リストにアイテムを追加すると、すぐに同じアイテムを解放します。TListそしてその子孫TObjectListは、彼らが保持しているオブジェクトの「ディープコピー」を作成しません。

後でリストの内容を読むと、取得しているのは古い参照です。最初に参照したオブジェクトを参照しなくなり、おそらくオブジェクトをまったく参照しなくなります。これらの場所のメモリには、以前のオブジェクトのように見えるように構造化されたデータが含まれている可能性がありますが、その保証はありません。プログラムがクラッシュしないという保証もありません。クラッシュは一般的ですが、次に一般的な動作は、実行を継続しても期待されるデータが表示されないなど、プログラムが微妙なエラーを示すことです。


オブジェクトのリストが必要な場合は、それらを解放しないでください。finally上で引用したブロックを取り除きます。例外を防ぐには、次のように、所有権を現在のコードブロックからリストに慎重に譲渡する必要があります。

BmpOut := TBitmap.Create;
try
  BmpOut.Assign(JpgIn);
  CurIdx := mylist.Add(bmpout);
except
  BmpOut.Free;
  raise;
end;

AssignまたはAdd呼び出し中に例外が発生した場合、ローカルプロシージャはビットマップを解放する必要があります。それ以外の場合、リストはオブジェクトの所有権を取得し、リストを解放すると、そのすべてのオブジェクトが暗黙的に解放されます(リストのOwnsObjectsプロパティがであると想定True)。

すべてのビットマップをロードしてリストに保存したら、画像コントロールに割り当てるためだけに別のビットマップを作成する必要はありません。リストに保存したものを使用できます。

if mylist.Count > 0 then
begin
  ZImage1.Bitmap.Assign(mylist[mylist.Count - 1]);
end;

そのコードから、を追跡する必要さえないことがわかりますCurIdx。その値は常に最後に追加されたオブジェクトのインデックスになり、そのインデックスは常にリスト内のオブジェクトの総数より1つ少なくなります。

また、別のグラフィックオブジェクトから値を割り当てる前に、ビットマップの高さと幅を設定する必要はありません。ソースオブジェクトの寸法を自動的に取得します。

于 2012-06-13T21:18:35.997 に答える