Solved

Array of Bitmaps

Posted on 2000-04-10
10
443 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 150 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

Enroll in June's Course of the Month

June's Course of the Month is now available! Every 10 seconds, a consumer gets hit with ransomware. Refresh your knowledge of ransomware best practices by enrolling in this month's complimentary course for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Come and listen to Percona CEO Peter Zaitsev discuss what’s new in Percona open source software, including Percona Server for MySQL (https://www.percona.com/software/mysql-database/percona-server) and MongoDB (https://www.percona.com/software/mongo-…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

691 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