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

Вниз

Архитектура в CAD-системе. Изображения.   Найти похожие ветки 

 
Псарь   (2011-08-04 04:16) [0]

Делаю скромный редактор по перетаскиванию и прочему манип. с объектами-картинками.
Основной класс объекта манипуляций:


type
 TDisplayObj = class
   constructor Create(X, Y: LongInt);
 private
   FX, FY  : LongInt;
   FW, FH  : LongWord;
   FIsHit  : boolean;
   FAlpha  : byte;
   FIsBlend: boolean;

   FPtDrag : TPoint;
   FIsDrag : boolean;
 protected
   procedure SetEffect(Bmp: TBitmap);
   procedure Draw(AContext: TContext; Bmp: TBitmap);
   procedure OnMouseDown(X, Y: LongInt);
   procedure OnMouseMove(X, Y: LongInt);
   procedure OnMouseUp  (X, Y: LongInt);
 public
   function  GetBounce: TRect;
   procedure Aligned(Align: LongWord);
   function  HitTest(X, Y: LongInt): boolean; overload;
   function  HitTest(const R: TRect): boolean; overload;
   property  PosX:    LongInt read FX       write FX;
   property  PosY:    LongInt read FY       write FY;
   property  Alpha:   byte    read FAlpha   write FAlpha;
   property  IsBlend: boolean read FIsBlend write FIsBlend;
 end;


Очевидно, что хранить в каждой таком объекте (коих десятки и сотни) TBitmap - не выгодно по памяти.
Следовательно он должен подаваться снаружи.
Сделал ассоциативный массив, кидается TBitmap и назначается имя.
Зная имя, получаем изображение и рисуем.

Но тут гложат меня сомнения, как правильно сделать:
1) Хранить в каждом TDisplayObj строку - ключ к TBitmap?
   или вынести ее в метод Draw?
2) Как задавать высоту и ширину объекта? Т.е.
   ГДЕ задавать? В конструкторе по ключу имени? Или
   в том же Draw? Но ведь метод GetBounce может понадобиться и без Драв.
3) Все время получать и искать в массиве по ключи при рисовании - медленно может выйти. Лучше хранить уже готовые НАЙДЕННЫЕ ТБитмапы.
Но как правильно все организовать?

зы. Троллей прошу идти в баню.


 
Псарь   (2011-08-04 04:16) [1]

TContext - расширенный TCanvas, если чо


 
Sapersky   (2011-08-04 06:58) [2]

В TBitmap используется механизм разделения картинок. При копировании через TBitmap.Assign в новом объекте создаётся ссылка на картинку, сама картинка не копируется. При этом ведётся подсчёт ссылок и всё корректно уничтожается по мере надобности.
Можно и просто копировать переменную TBitmap присвоением, при этом она работает как обычный указатель - занимает 4 байта и указывает на "чужие" данные. Но проблемы с уничтожением (уничтожили объект в одном месте, все прочие указатели "испортились") придётся решать вручную.


 
Псарь   (2011-08-04 07:57) [3]


>  Sapersky   (04.08.11 06:58) [2]


Вы уверены?
Почему тогда при уничтожении Bmp1, Bmp2 все равно рисуется?
Или я что не понимаю.



var
 Bmp1, Bmp2: TBitmap;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Bmp1:= TBitmap.Create;
 Bmp2:= TBitmap.Create;

 Bmp1.LoadFromFile("C:\image\LazerTank.bmp");
 Bmp2.Assign(Bmp1);
end;

procedure TForm1.Timer1Timer(Sender: TObject); // Интервал 1.
begin
 If Bmp2.Empty then Caption:= "NULL"
 else begin
   Caption:= "True";
   Canvas.Draw(10, 10, Bmp2);
 end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
 FreeAndNil(Bmp1);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Bmp1.Free;
 Bmp2.Free;
end;


 
Ega23 ©   (2011-08-04 10:23) [4]


>  TDisplayObj = class
>    constructor Create(X, Y: LongInt);


Зачем конструктор publised?


 
brother ©   (2011-08-04 10:36) [5]

> If Bmp2.Empty then Caption:= "NULL"

а так:
If Bmp2 = nil then Caption:= "NULL"
?


 
DiamondShark ©   (2011-08-04 11:18) [6]


> Псарь   (04.08.11 07:57) [3]
> Почему тогда при уничтожении Bmp1, Bmp2 все равно рисуется?

Потому что
>  При этом ведётся подсчёт ссылок и всё корректно уничтожается
> по мере надобности.


 
Псарь   (2011-08-05 12:37) [7]


> Ega23 ©   (04.08.11 10:23) [4]


> Зачем конструктор publised?


Он будет вроде как в публик?


> brother ©   (04.08.11 10:36) [5]
>
> > If Bmp2.Empty then Caption:= "NULL"
>
> а так:
> If Bmp2 = nil then Caption:= "NULL"
> ?


При чем тут это?
Мы же не уничтожаем Bmp2. Он всегда будет валидным.
А вот изображение в нем под вопросом.


> DiamondShark ©   (04.08.11 11:18) [6]


Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
в Bmp2?
Если так, то сделаю каждому TDisplayObject"у по TBitmap.


 
Jeer ©   (2011-08-05 15:19) [8]


> Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
> в Bmp2?


Если сделано по толковому, то никто не гоняет биты и байты туда-сюда.
Валидный указатель остается во втором живом объекте и этого (+ контроль ссылок) достаточно от мемликов.


 
Sapersky   (2011-08-06 19:08) [9]

Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
в Bmp2?


Изображения вообще не хранятся в TBitmap, они хранятся во внутреннем контейнере TBitmapImage.
При выполнении Assign двум или более TBitmap"ам назначается один TBitmapImage, при этом TBitmapImage хранит кол-во владельцев (счётчик ссылок). При уничтожении TBitmap счётчик ссылок уменьшается, и TBitmapImage уничтожается только тогда, когда он равен 0, т.е. больше нет владельцев.
И кстати, исходники всего этого открыты (хотя для новичка, возможно, выглядят пугающе).


 
Псарь   (2011-08-07 09:13) [10]


>  Sapersky   (06.08.11 19:08) [9]


Большущее Вам спасибо. =)



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

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

Наверх




Память: 0.49 MB
Время: 0.013 c
1-1272455088
RAN-II
2010-04-28 15:44
2011.11.27
Доступ к документу FireFox


2-1312641641
avi9526
2011-08-06 18:40
2011.11.27
Где находится функция прорисовки TCheckBox


2-1312053793
Pepe
2011-07-30 23:23
2011.11.27
Hmac MD5 Delphi


2-1312270931
arturich
2011-08-02 11:42
2011.11.27
runtime создание BandedColumn в cxGrid


2-1312799819
А
2011-08-08 14:36
2011.11.27
mysql zoesdb нет коннекта