1
votes

I'm at my whits end... trying to get a custom list of pictures, a TImageList and a TListView to work together. Original problem: No dynamically-added pictures are displayed in the list. Narrowed it down, problem is in the TImagelist. Code is below. ilMain is the TImagelist (defined elsewhere). Adding a bitmap to the list, immediatly retrieving it, first "Draw" works fine but the sedond fails... what am I missing here?

var i:integer;
  test:TSch;
  currentimage :TBitmap;
  stupid :TBitmap;

begin
  currentImage:=TBitmap.Create;
  stupid:=TBitmap.Create;
  ilMain.Clear;
//  currentImage.LoadFromFile('C:\Delphi\piccat\pics\MonaLisa.jpg');
  JPeg2Bmp('C:\Delphi\piccat\pics\MonaLisa.jpg',currentImage);

  form1.canvas.Draw(100,10,currentimage);
  ilMain.Add(currentimage,nil);
  ilMain.GetBitmap(0,stupid);
  form1.canvas.Draw(200,10,stupid);

EDIT:

Done some further testing on this one; results are very confusing and inconsistent.

Result are actually GREATLY dependant on the size of the input file (thanks for that pointer, kobik!); it seems everything smaller than 256x256 isn't imported into the imagelist, while bigger pictures ALONG THE X-AXIS are (sometimes??) spread over several items.

ilMain was set to 256x256 pixels.

Here is the output for several input sizes (X x Y, in pixels): 950x414 First draw displays entire image, second take 256x256 pixels in the upper left corner. HOWEVER, THREE items of the TImagelist are populated, with 3x 256x256 pixels: the three pictures that can be "cut out" from the main picture and still be 256x256 pixels. All edges cut off which are smaller, either vertical or horizontal, than 256x256 are lost.

1600x1600 Six images are imported; the first row of complete 256x256 blocks which can be cut from the top of the pic. The incomplete block on the tp right is omitted, and all rows below Y-size 256 as well.

1500x1000 Similar to previous one; five items imported now.

638x376 Again similar; only two items "fit" now.

197x256 (my original test file, described in post above) NO ITEMS IMPORTED (X-size is smaller than TImaglist X-size?)

256x256 AGAIN, NO DATA IMPORTED

257x257 STILL NO DATA IMPORTED

260x260 STILL NO DATA IMPORTED

300x300 STILL NO DATA IMPORTED

512x256 Very weird one. One pic is imported; BUT it is reduced in size, so approximately 70% of the original pic fits in the (new) 256 X size. A black bar is added below the pic to make up for the lost space due to this shrinking.

So this is where I stop testing for now, and wondering if anyone can shed some light here...?

EDIT: Design part moved to new question (see request in comment kobik, thanks man!)

1
Well, I don't see anything wrong with your code. Perhaps, the problem is with indices of added bitmaps. You retrieve bitmap only for zero index. Thus, you always get first added bitmap, whilist others are still placed inside TImageList. Try to replace this: ilMain.GetBitmap(0,stupid)' with this: ilMain.GetBitmap(ilMain.Add(currentimage,nil),stupid)`. Just a suggestion.Josef Švejk
...or just additional thought: currentimage bitmap has big size (more than 200x200 px.), so "second draw" is performed over already drawn currentimage, hence you won't notice the second image as it "hidden' on currentimage.Josef Švejk
Step back, take a breath, relax. Make a minimal reproducible example. Make the code as clear as possible. Post that.David Heffernan
Dima, no, the pic would show. Obviously this is test code, so yeah the index is hard-coded, will obviously make it dynamic once I get this to work... Your suggested change gets the same results btw.Jur
The code is incomplete.David Heffernan

1 Answers

4
votes

Your code works (or at-least needs to work) assuming your JPeg2Bmp is correct. I guess @Dima's second comment is correct.

You haven't showed the ilMain properties, and if you use the default you get an imagelist with Width/Height=16.

Try to omit the first call to form1.canvas.Draw(100,10,currentimage);, and draw only the form1.canvas.Draw(200,10,stupid); and You should see a 16x16 drawing at position 200,10.

TImagelist can't load arbitrary image sizes.
You need to pre-define it's size, and load the bitmaps with suitable sizes. i.e. create thumbnails to fit the imagelist dimensions.

Note also that (you probably know that) You need to draw only in response to WM_PAINT Message. e.g. in the Form OnPaint event.

EDIT: As regard to your edit, this is how TImageList works. if you add a bitmap that is larger than the imagelist width, it will attempt to break the bitmap into separate bitmaps to fit the imagelist size. this is by design.

See the documentation about ImageList_Add about the hbmImage parameter:

A handle to the bitmap that contains the image or images. The number of images is inferred from the width of the bitmap.