Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2016.04.24;
Скачать: [xml.tar.bz2];

Вниз

Как сделать список 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.002 c
2-1411245669
Stepan4ik
2014-09-21 00:41
2016.04.24
Function 2 значения


15-1439457626
NailMan
2015-08-13 12:20
2016.04.24
Помогите с написанием функции для ардуинки


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


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


2-1411564536
Who_are_you?
2014-09-24 17:15
2016.04.24
делфи 7 а делфи 5





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский