?
Solved

Array of Bitmaps

Posted on 2000-04-10
10
Medium Priority
?
474 Views
Last Modified: 2010-04-04
I have a form with a listbox on the left and an image control on the right.
When you click something in the listbox, it needs to display the image to go with it. The only way I could think to do this was to declare an array of tbitmap and when you click the listbox, the array with the listbox's itemindex shows in the image control. When I try to clear the whole thing, the array, the image and the listbox, it appears to clear. When you reload every thing new, the listitems that contained images before, still do. I have been having alot of access errors trying to free the whole array eachtime.
The array needs to hold at least 75 images. Any Ideas?

Thanks in advance,
Cando
0
Comment
Question by:cando
  • 2
  • 2
  • 2
  • +4
10 Comments
 
LVL 4

Expert Comment

by:StevenB
ID: 2702310
 I'm in a hurry here, but one word springs to mind: TImageList.

  (Sorry if I've misinterpreted things and stated the bleedin' obvious)

  Gotta dash,

  Steven
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2702326
Maintain a TObjectList next to the ListBox and store the bitmaps in this list. TObjectList frees the bitmaps automatically when necessary...
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2702345
TImageList can only hold images of equal size. Maybe this is case here... don't know.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:cando
ID: 2702654
Sorry,

All the images could be very different, loaded from files or pasted form the clipboard.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2702726
Can you post the relevant code?

Cheers,

Raymond.


0
 

Author Comment

by:cando
ID: 2702773
FImage: array[1..75] of TBitmap;

procedure TForm1.LoadFromFile1Click(Sender: TObject);
begin
 if OpenPictureDialog1.Execute then
 begin
   FImage[ListBox2.ItemIndex + 1] := TBitmap.Create;
   FImage[ListBox2.ItemIndex + 1].LoadFromFile(openPictureDialog1.FIleName);
   Image1.Picture.Bitmap := FImage[ListBox2.ItemIndex + 1];
 end;
end;

procedure TForm1.ListBox2Click(Sender: TObject);
begin
  try Image1.Picture.Bitmap := FImage[ListBox2.ItemIndex + 1] except end;
end;


This all seems to work alright When I try to clear it all so it can be refilled, it clears but when the listbox is filled again, it has pictures for the items that had them last time. I dont know how to clear the array.

Here is the code I use to clear everything.



procedure TForm1.ClearAll;
var
  i: integer;
begin
  Image1.Picture := nil;
  ListBox2.Clear;

  try
    for I := 1 to 75 do FImage[i].free;
  except end;
end;
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2702781
When you add the items to the listbox, use addobject

a sample (form with button1, listbox1, image1 and openpicturedialog1)

procedure TForm1.Button1Click(Sender: TObject);
var
  mybitmap : tbitmap;
begin
  if openpicturedialog1.execute then
    begin
      mybitmap := tbitmap.create;
      mybitmap.loadfromfile(openpicturedialog1.filename);
      listbox1.items.addobject ('item', TObject(mybitmap));
    end;

When you delete an item from the list box, don't forget to call TBitmap(listbox1.items.object[x]).free first.

Mark


end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  image1.picture.bitmap.assign(TBitmap(listbox1.items.objects[listbox1.itemindex]));
end;
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 2702794
Actually, if you are working in Delphi 4 or higher, you could use a dynamic array of Bitmaps, incrementing it as you poplulate it:

Var BMPArray:array of Tbitmap;

Begin
  BmpArray[length(bmpArray)-1]:=Tbitmap.create;
  BmpArray[length(bmpArray)-1].LoadFromfile('yada.bmp');
end;


and then scaling that array down to
nothing again by using Copy:


bmpArray:=Copy(BmpArray,0,0);


0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2702796
Oops, my last comment about delete is in the middle of my sample, sorry 'bout that...  below is a better example, button2 is a delete item button (no error checking..)


procedure TForm1.Button1Click(Sender: TObject);
var
  mybitmap : tbitmap;
begin
  if openpicturedialog1.execute then
    begin
      mybitmap := tbitmap.create;
      mybitmap.loadfromfile(openpicturedialog1.filename);
      listbox1.items.addobject ('item', TObject(mybitmap));
    end;

end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
if assigned(listbox1.items.objects[listbox1.itemindex]) then
  image1.picture.bitmap.assign(TBitmap(listbox1.items.objects[listbox1.itemindex]));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 TBitmap(listbox1.items.objects[listbox1.itemindex]).free;
 TBitmap(listbox1.items.objects[listbox1.itemindex]).Assign(nil);
end;
0
 
LVL 10

Accepted Solution

by:
Lischke earned 450 total points
ID: 2703270
Hi all,

I'm currently writing on an image database browser which shows all images as thumbnails. For performance reasons I cache 300 (adjustable) TBitmaps in a normal TList. mulllet_attack has already mentioned to use the listbox's ability to store objects. This is also a good solution. Take care that you free the objects correctly.

If you still want to use your extra list then make sure you reset the references in it:

procedure TForm1.ClearAll;
var
  i: integer;
begin
  Image1.Picture := nil;
  ListBox2.Clear;

  try
    for I := 1 to 75 do
    begin
      FImage[i].free;
      FImage[i] := nil;
    end;
  except end;
end;

otherwise you will access invalid memory!

DrDelphi, just a hint for your dynamic array approach which is something I also like (and use quite often).

Allocation:

  SetLength(BMPArray, Length(BMPArray) + 1);
  BMPArray[High(BMPArray)] := TBitmap.Create;
  :

Do not rely on automatic memory allocation, this will not happen (as in Java)!

Deallocation:

for I := 0 to High(BMPArray) do
  BMPArray[I].Free;
BMPArray := nil;

Ciao, Mike
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Kernel Data Recovery is a renowned Data Recovery solution provider which offers wide range of softwares for both enterprise and home users with its cost-effective solutions. Let's have a quick overview of the journey and data recovery tools range he…
Enter Foreign and Special Characters Enter characters you can't find on a keyboard using its ASCII code ... and learn how to make a handy reference for yourself using Excel ~ Use these codes in any Windows application! ... whether it is a Micr…
Suggested Courses

616 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question