Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.04.24;
Скачать: CL | DM;

Вниз

Как сделать список TBitmap ов?   Найти похожие ветки 

 
K-1000 ©   (2015-08-12 16:42) [0]

Загружаться картинки будут в OnCreate().
Через функцию LoadImage("name_1", "data/image_1.bmp");
Т.е. имя и путь.

Получать нужно через функцию GetImage(Name: string): TBitmap;
Т.е. по имени TBitmap.

В Delphi 7.


 
K-1000 ©   (2015-08-12 16:46) [1]

Пока вижу только такое решение:


type
 TItem = record
     Name: string;
     Bitmap: TBitmap;
 end;

List: TList;

Item.Name:= Name;
Item.Bitmap:= TBitmap;
Item.Bitmap.LoadFromFile();

List.Add(Item);


 
Sha ©   (2015-08-12 16:50) [2]

TStringList


 
Dimka Maslov ©   (2015-08-12 17:06) [3]

TImageList?


 
Столп Третьей Силы ©   (2015-08-12 18:43) [4]

Единственный недостаток ЛистовОбъектов (содержащих ссылку на битмап) - потеря гдихендла. Этого недостатка лишен ИмаджЛист, но он хранит картинки одинакового размера, в этом его недостаток.
Многое зависит от конкретных условий задачи. Можно и свой ИмаджЛист написать, с блекджеком. Одна канва, таблица смещений и размеров, метод получения.

Но в общем случае, конечно СтрингЛист предпочтительнее.


 
K-1000 ©   (2015-08-12 19:18) [5]

>Столп Третьей Силы ©   (12.08.15 18:43) [4]

> Этого недостатка лишен ИмаджЛист, но он хранит картинки
> одинакового размера, в этом его недостаток.


Да, изображения разных размеров.


> Но в общем случае, конечно СтрингЛист предпочтительнее.


Пока сделал через него.


>Единственный недостаток ЛистовОбъектов (содержащих ссылку на битмап) - >потеря гдихендла.


Это как? В каком месте он теряется?

 
 Bitmap: TBitmap;
 Bitmap.LoadFromFile();

 S: TStringList;
 S.AddObject("1", Bitmap);


 
K-1000 ©   (2015-08-12 19:32) [6]

Вот сделал класс, не знаю что делать в случае исключения в AddImage() во время загрузки изображения:


type
 TListImages = class
   constructor Create();
   destructor  Destroy(); override;
 private
   FList: TStringList;
 public
   procedure AddImage(const Name: string; const FileName: string);
   function  GetImage(const Name: string): TBitmap;
 end;

{ TListImages }

constructor TListImages.Create();
begin
 inherited;
 FList:= TStringList.Create();
end;

destructor TListImages.Destroy();
begin
 FreeAndNil(FList);
 inherited;
end;

procedure TListImages.AddImage(const Name: string; const FileName: string);
var
 Bitmap: TBitmap;
begin
 Bitmap:= TBitmap.Create();
 try
   Bitmap.LoadFromFile(FileName);
   Bitmap.PixelFormat:= pf32bit;

   FList.AddObject(Name, Bitmap);
 except
   FreeAndNil(Bitmap);
 end;
end;

function TListImages.GetImage(const Name: string): TBitmap;
var
 Idx: LongInt;
begin
 if (FList.Find(Name, Idx))
 then Result:= (FList.Objects[Idx] as TBitmap)
 else Result:= nil;
end;

// Пример использования.

procedure TForm1.Button1Click(Sender: TObject);
var
 ListImages: TListImages;
 Bitmap:     TBitmap;
begin
 ListImages:= TListImages.Create();
 try
   ListImages.AddImage("image_1", "1.bmp");

   Bitmap:= ListImages.GetImage("image_1");

   if (Assigned(Bitmap))
   then Canvas.Draw(25, 25, Bitmap)
   else ShowMessage("Error");
 finally
   FreeAndNil(ListImages);
 end;
end;


 
Столп Третьей Силы ©   (2015-08-12 20:52) [7]

В методе Адд ты уничтожаешь загруженный битмап и его больше нет. Убери фри.
В деструктор добавь очистку битмапов (в цикле фри для каждого).
Да метод add имхо должен возвращать битмап и к тому же проверять нет ли уже с таким именем и возвращать его если есть.


 
Столп Третьей Силы ©   (2015-08-12 20:56) [8]


> K-1000 ©   (12.08.15 19:18) [5]
> >Единственный недостаток ЛистовОбъектов (содержащих ссылку
> на битмап) - >потеря гдихендла.

> Это как? В каком месте он теряется?

Пока забей, мне влом объяснять. Для самообразования читай в гугле GDI handle


 
K-1000 ©   (2015-08-12 21:02) [9]


> Столп Третьей Силы ©   (12.08.15 20:52) [7]
>
> В методе Адд ты уничтожаешь загруженный битмап и его больше
> нет. Убери фри.


Он уничтожается, если произошло исключение во время LoadFromFile()
Вот только мне не ясно правильно ли так делать...


> В деструктор добавь очистку битмапов (в цикле фри для каждого).


Ага.


> Да метод add имхо должен возвращать битмап и к тому же проверять
> нет ли уже с таким именем и возвращать его если есть.


Не думаю, что мне это понадобится.


 
Столп Третьей Силы ©   (2015-08-12 21:20) [10]


> K-1000 ©   (12.08.15 21:02) [9]
> Он уничтожается, если произошло исключение во время LoadFromFile()

Да, я не внимателен.


> K-1000 ©   (12.08.15 21:02) [9]
> Вот только мне не ясно правильно ли так делать...

Уничтожать объект правильно, но ты перед этим его добавил в список... (сам смотри)
Да и вызывающий ничего не знает о том добавилось ли.

Демонстрация конца ГДИ хендлов
http://s4.postimg.org/7ie36rrdp/Rec.gif


 
K-1000 ©   (2015-08-13 08:50) [11]


>  Столп Третьей Силы ©   (12.08.15 21:20) [10]
>
> Уничтожать объект правильно, но ты перед этим его добавил
> в список... (сам смотри)
> Да и вызывающий ничего не знает о том добавилось ли.


Сделал.


> Демонстрация конца ГДИ хендлов


В нашем списке где будет утечка?
Ведь вызывается FreeAndNil()


 
Pavia ©   (2015-08-13 09:28) [12]


> В нашем списке где будет утечка?

Это не утечка. Просто GDi.Handel это ценный ресурс он ограничен 8-10 тысячами. Используется для рисования всего на форме. А при создании TBitmap он расходуется.
Если список будет большим порядка 8-10 тыс, то программа не сможет корректно работать.


 
K-1000 ©   (2015-08-13 09:38) [13]


> Pavia ©   (13.08.15 09:28) [12]
>
>
> > В нашем списке где будет утечка?
>
> Это не утечка. Просто GDi.Handel это ценный ресурс он ограничен
> 8-10 тысячами. Используется для рисования всего на форме.
>  А при создании TBitmap он расходуется.
> Если список будет большим порядка 8-10 тыс, то программа
> не сможет корректно работать.


Не думаю, что столько битмапов понадобится.


 
han_malign ©   (2015-08-13 13:21) [14]


> Это не утечка. Просто GDi.Handel это ценный ресурс он ограничен 8-10 тысячами.

А Bitmap.Dormant - после "использования" - освободит GDI дескриптор - до следующей "нужды"...


 
DVM ©   (2015-08-13 13:52) [15]

Нафига вообще хранить кучу битмапов? Именно с завязкой на Gdi? Если они маленькие лучше хранить одним битмапом и вырезать оттуда нужные фрагменты, если большие то хранить вообще на диске и по мере необходимости погружать, если с диска грузить медленно, то загрузить их заранее в список стримов а уж из них грузить на лету в битмап.


 
K-1000 ©   (2015-08-13 17:11) [16]


> DVM ©   (13.08.15 13:52) [15]
>
> Нафига вообще хранить кучу битмапов?


Около 40-50 битмапов нужно, размеры разные.
Нужно для редактора. Хранить в списке удобно.

> Именно с завязкой на Gdi?

А что много GDI-ресурсов тянет 1 TBitmap?
По-идее это один HBITMAP и DIB-Секция, не много должно быть.


 
K-1000 ©   (2015-08-15 08:30) [17]

Буквально 2 вопроса по классу (Вопросы в комментариях):



{ TListImages }

constructor TListImages.Create();
begin
 inherited;
 FList           := TStringList.Create();
 FList.Duplicates:= dupError;
 FList.Sorted    := True;
end;

destructor TListImages.Destroy();
var
 i:      LongInt;
 Bitmap: TBitmap;
begin
 for i:= 0 to FList.Count - 1 do // Верно ли тут сделано? Сам FList не очистит ссылки?
 begin
   Bitmap:= (FList.Objects[i] as TBitmap);
   FreeAndNil(Bitmap);
 end;

 FreeAndNil(FList);
 inherited;
end;

function TListImages.AddImage(const Name: string; const FileName: string): boolean;
var
 Bitmap: TBitmap;
begin
 Bitmap:= TBitmap.Create();
 try
   Bitmap.LoadFromFile(FileName);
 except                                   // Правильно ли так обрабатывать исключение?
   FreeAndNil(Bitmap);
 end;

 Result:= Assigned(Bitmap);

 if Result then
 begin
   FList.AddObject(Name, Bitmap);

 end;
end;

function TListImages.GetImage(const Name: string): TBitmap;
var
 Idx: LongInt;
begin
 if (FList.Find(Name, Idx))
 then Result:= (FList.Objects[Idx] as TBitmap)
 else Result:= nil;
end;



 
DVM ©   (2015-08-15 09:50) [18]


> K-1000 ©   (15.08.15 08:30) [17]


>  for i:= 0 to FList.Count - 1 do // Верно ли тут сделано?
>  Сам FList не очистит ссылки?

Не очистит. Верно.


> // Правильно ли так обрабатывать исключение?

Ну как тебе сказать. Формально все правильно, но о том, почему битмап не загружен ты не узнаешь. Может быть стоит после FreeAndNil(Bitmap); добавить raise?


 
K-1000 ©   (2015-08-16 09:01) [19]


> DVM ©   (15.08.15 09:50) [18]
>Может быть стоит после FreeAndNil(Bitmap); добавить raise?


Ага. Спасиб.



Страницы: 1 вся ветка

Текущий архив: 2016.04.24;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.006 c
15-1439131296
Кто б сомневался
2015-08-09 17:41
2016.04.24
Ребят, а чего бы вам не объедениться с delphikingdom


15-1439456322
olle
2015-08-13 11:58
2016.04.24
Штрих-М Повторная печать чека


2-1412050405
Stepan4ik
2014-09-30 08:13
2016.04.24
Обрезать после запятой (Float)


15-1439587804
Юрий
2015-08-15 00:30
2016.04.24
С днем рождения ! 15 августа 2015 суббота


15-1439386977
K-1000
2015-08-12 16:42
2016.04.24
Как сделать список TBitmap ов?