Завантажуватися картинки будуть в OnCreate ().
Через функцію LoadImage ( "name_1", "data / image_1.bmp");
Тобто ім'я та шлях.
Отримувати потрібно через функцію GetImage (Name: string): TBitmap;
Тобто по імені TBitmap.
Поки бачу тільки таке рішення:
type
# XA0; TItem = record
# XA0; # XA0; # XA0; Name: string;
# XA0; # XA0; # XA0; Bitmap: TBitmap;
# XA0; end;
Item.Name:= Name;
Item.Bitmap: = TBitmap;
Item.Bitmap.LoadFromFile ();
Єдиний недолік ЛістовОб'ектов (містять посилання на бітмапами) - втрата гдіхендла. Цього недоліку позбавлений ІмаджЛіст, але він зберігає картинки однакового розміру, в цьому його недолік.
Багато що залежить від конкретних умов завдання. Можна і свій ІмаджЛіст написати, з блекджек. Одна канва, таблиця зсувів і розмірів, метод отримання.
Але в загальному випадку, звичайно СтрінгЛіст краще.
Так, зображення різних розмірів.
> Але в загальному випадку, звичайно СтрінгЛіст краще.
Поки зробив через нього.
> Єдиний недолік ЛістовОб'ектов (містять посилання на бітмапами) -> втрата гдіхендла.
Це як? В якому місці він губиться?
# XA0;
# XA0; Bitmap: TBitmap;
# XA0; Bitmap.LoadFromFile ();
# XA0; S: TStringList;
# XA0; S.AddObject ( "1", Bitmap);
Ось зробив клас, не знаю що робити в разі виключення в AddImage () під час завантаження зображення:
type
# XA0; TListImages = class
# XA0; # XA0; constructor Create ();
# XA0; # XA0; destructor # XA0; Destroy (); override;
# XA0; private
# XA0; # XA0; FList: TStringList;
# XA0; public
# XA0; # XA0; procedure AddImage (const Name: string; const FileName: string);
# XA0; # XA0; function # XA0; GetImage (const Name: string): TBitmap;
# XA0; end;
constructor TListImages.Create ();
begin
# XA0; inherited;
# XA0; FList: = TStringList.Create ();
end;
destructor TListImages.Destroy ();
begin
# XA0; FreeAndNil (FList);
# XA0; inherited;
end;
procedure TListImages.AddImage (const Name: string; const FileName: string);
var
# XA0; Bitmap: TBitmap;
begin
# XA0; Bitmap: = TBitmap.Create ();
# XA0; try
# XA0; # XA0; Bitmap.LoadFromFile (FileName);
# XA0; # XA0; Bitmap.PixelFormat: = pf32bit;
# XA0; # XA0; FList.AddObject (Name, Bitmap);
# XA0; except
# XA0; # XA0; FreeAndNil (Bitmap);
# XA0; end;
end;
function TListImages.GetImage (const Name: string): TBitmap;
var
# XA0; Idx: LongInt;
begin
# XA0; if (FList.Find (Name, Idx))
# XA0; then Result: = (FList.Objects [Idx] as TBitmap)
# XA0; else Result: = nil;
end;
procedure TForm1.Button1Click (Sender: TObject);
var
# XA0; ListImages: TListImages;
# XA0; Bitmap: # XA0; # XA0; TBitmap;
begin
# XA0; ListImages: = TListImages.Create ();
# XA0; try
# XA0; # XA0; ListImages.AddImage ( "image_1", "1.bmp");
# XA0; # XA0; Bitmap: = ListImages.GetImage ( "image_1");
# XA0; # XA0; if (Assigned (Bitmap))
# XA0; # XA0; then Canvas.Draw (25, 25, Bitmap)
# XA0; # XA0; else ShowMessage ( "Error");
# XA0; finally
# XA0; # XA0; FreeAndNil (ListImages);
# XA0; end;
end;
У методі Адд ти губиш завантажений бітмапами і його більше немає. Прибери фрі.
У деструктор додай очищення бітмапами (в циклі фрі для кожного).
Так метод add имхо повинен повертати бітмапами і до того ж перевіряти чи немає вже з таким ім'ям і повертати його якщо є.
> Це як? В якому місці він губиться?
Поки забий, мені влом пояснювати. Для самоосвіти читай в гуглі GDI handle
Він знищується, якщо відбулося виключення під час LoadFromFile ()
Ось тільки мені не зрозуміло чи правильно так робити.
> В деструктор додай очищення бітмапами (в циклі фрі для кожного).
> Так метод add имхо повинен повертати бітмапами і до того ж перевіряти
> Чи немає вже з таким ім'ям і повертати його якщо є.
Не думаю, що мені це знадобиться.
> Демонстрація кінця ГДВ хендлов
У нашому списку де буде витік?
Адже викликається FreeAndNil ()
> У нашому списку де буде витік?
Це не витік. Просто GDi.Handel це цінний ресурс він обмежений 8-10 тисячами. Використовується для малювання всього на формі. А при створенні TBitmap він витрачається.
Якщо список буде великим порядку 8-10 тис, то програма не зможе коректно працювати.
Не думаю, що стільки бітмапами знадобиться.
> Це не витік. Просто GDi.Handel це цінний ресурс він обмежений 8-10 тисячами.
А Bitmap.Dormant - після "використання" - звільнить GDI дескриптор - до наступної "потреби".
Нафіга взагалі зберігати купу бітмапами? Саме з зав'язкою на Gdi? Якщо вони маленькі краще зберігати одним бітмапами і вирізати звідти потрібні фрагменти, якщо великі то зберігати взагалі на диску і в міру необхідності занурювати, якщо з диска вантажити повільно, то завантажити їх заздалегідь в список стрімів а вже з них вантажити на льоту в бітмапами.
> Саме з зав'язкою на Gdi?
А що багато GDI-ресурсів тягне 1 TBitmap?
По-ідеї це один HBITMAP і DIB-Секція, не багато має бути.
constructor TListImages.Create ();
begin
# XA0; inherited;
# XA0; FList # XA0; # XA0; # XA0; # XA0; # XA0; : = TStringList.Create ();
# XA0; FList.Duplicates: = dupError;
# XA0; FList.Sorted # XA0; # XA0;: = True;
end;
destructor TListImages.Destroy ();
var
# XA0; i: # XA0; # XA0; # XA0; LongInt;
# XA0; Bitmap: TBitmap;
begin
# XA0; for i: = 0 to FList.Count - 1 do // Чи вірно тут зроблено? Сам FList не очиститься посилання?
# XA0; begin
# XA0; # XA0; Bitmap: = (FList.Objects [i] as TBitmap);
# XA0; # XA0; FreeAndNil (Bitmap);
# XA0; end;
function TListImages.AddImage (const Name: string; const FileName: string): boolean;
var
# XA0; Bitmap: TBitmap;
begin
# XA0; Bitmap: = TBitmap.Create ();
# XA0; try
# XA0; # XA0; Bitmap.LoadFromFile (FileName);
# XA0; except # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; # XA0; // Чи правильно так обробляти виключення?
# XA0; # XA0; FreeAndNil (Bitmap);
# XA0; end;
# XA0; if Result then
# XA0; begin
# XA0; # XA0; FList.AddObject (Name, Bitmap);
function TListImages.GetImage (const Name: string): TBitmap;
var
# XA0; Idx: LongInt;
begin
# XA0; if (FList.Find (Name, Idx))
# XA0; then Result: = (FList.Objects [Idx] as TBitmap)
# XA0; else Result: = nil;
end;
> // Чи правильно так обробляти виключення?
Ну як тобі сказати. Формально все правильно, але про те, чому бітмапами не завантажено ти не дізнаєшся. Може бути варто після FreeAndNil (Bitmap); додати raise?