2012-06-13 4 views
1

일부 이미지를 오브젝트 목록에로드 한 다음 리콜하려고합니다. 그러나 그 이미지를 보여주지 않는가?objectlist가 데이터를 검색하지 않습니다.

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에 iamge를로드하는 것이 문제인지 확인하려면이 부분을 확인하십시오.

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

내가 잘못하고 스피 오브젝트리스트와의 뭔가를 생각하는 저를 인도하는 zimage1에 bmpout로드 것을했을 때? 당신은 목록에 항목을 추가 한 다음 즉시 무료 바로 그 동일한 항목

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

:

+2

(mylist.add (TBitmap (bmpout))') 그리고 (bmpout.Free()') 그것을 해제하기 위해 bmpout을 추가하고 있습니다. 'Add'는 객체의 복사본을 생성하지 않습니다. 그래서 당신은 당신의 목록에 잘못된 포인터가 있습니다. – teran

+0

물론 'mylist' 변수가 무엇인지 모르겠습니다 ('추가 '동작에 대해 말하기). 하지만 그것은 TObjectList라고 가정합니다. 'curIdx : = curIdx + 1;'줄은 불필요하다. 그리고 두번째 :'bmpout'을'TBitmap'으로 캐스팅 할 필요가 없습니다. 내가 전화하기 전에 – teran

+0

바닥 근처에, 나는 그것을 다시 만들었습니까? –

답변

5

는이 코드가 있습니다. TList과 그 자손 인 TObjectList은 보유한 객체의 "전체 복사본"을 만들지 않습니다.

나중에 목록의 내용을 읽을 때 오래된 참조이 표시됩니다. 그들은 더 이상 원래 참조한 객체를 참조하지 않으며 객체를 전혀 참조하지 않습니다. 해당 위치의 메모리에는 여전히 이전 오브젝트처럼 보이도록 구조화 된 데이터가 포함될 수 있지만이를 보장 할 수는 없습니다. 프로그램이 충돌하지 않을 것이라는 보장은 없습니다. 크래시가 일반적이지만 다음으로 가장 일반적인 동작은 프로그램을 계속 실행하지만 예상되는 데이터를 표시하지 않는 것과 같은 미세한 오류를 표시하는 것입니다.


개체 목록을 원하면 해제하십시오. 위에서 인용 한 finally 블록을 제거하십시오. 예외 안전을 위해, 당신은 신중하게 다음과 같이 목록에 현재의 코드 블록에서 소유권을 이전 할 수 있습니다 :

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

를 예외가 Assign 또는 Add 통화 중 발생하는 경우, 다음 로컬 절차는 해제해야 비트 맵. 그렇지 않으면 목록에 개체의 소유권이 부여되고 목록을 비우면 모든 개체가 암시 적으로 해제됩니다 (목록의 OwnsObjects 속성이 True이라고 가정).

일단 모든 비트 맵을로드하고 목록에 저장하면 이미지 컨트롤에 할당 할 무언가를 갖기 위해 다른 비트 맵을 만들 필요가 없습니다. 당신은 당신도 CurIdx 추적 할 필요가없는 것을 알 수있다, 그 코드에서

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

: 당신은 당신이 목록에 저장 한 하나를 사용할 수 있습니다. 이 값은 항상 마지막으로 추가 된 오브젝트의 인덱스가되며 해당 인덱스는 항상리스트에있는 오브젝트의 총 수보다 하나 작습니다.

다른 그래픽 개체의 값을 할당하기 전에 비트 맵의 ​​높이와 너비를 설정할 필요도 없습니다. 원본 개체의 크기를 자동으로 가져옵니다.

관련 문제