Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TPaintBox & TImage [D7]


Страницы:   1 2

Елена ©   (2011-11-22 00:33:00) 

Добрый вечер мастера. Пожалуйста помогите в таком вот вопросе - нужно нарисовать на форме пиксельную сетку, наподобие формы Delphi на этапе проэктирования.

Сделать можно так:

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
 i,j: Integer;
 Step: Integer;
begin
 Step := 10;
 for i := 0 to 10000 div Step do
   for j := 0 to 7000 div Step do
   PaintBox1.Canvas.Pixels[i*Step,j*Step] := clBlack;
end;

Но это будет требовать постоянной перерисовки, в результате чего будет подтормаживать, а размеры 10000Х7000 должны быть именно такими (может даже больше).

Если нарисовать подобным образом на TImage, то на размере его более 2000px вылазит белый фон, с которым ничего не поделаеш.
Как быть?


KilkennyCat   (2011-11-23 13:14:00) [1]

понятно.
ну, у меня как-то так получается, что практическе всегда буферизация и рисование на дс в памяти несколько быстрее.
наверное, мне просто везет.


han_malign   (2011-11-23 08:56:00) [2]


> ты о чем?

- я о том, что большинстве случаев DoubleBuffered - только добавляет тормозов...
А для отрисовки фона есть специально заточенный объект GDI - Brush, который начиная с W98 не ограничен ни глубиной цвета, ни размером 8x8...

З.Ы. В блитинге могут использоваться комбинации всех трех растров - источника, кисти и растра назначения...


KilkennyCat   (2011-11-22 17:45:00) [3]


> han_malign   (22.11.11 11:21) [11]
>
>
> > новый битмап, делаешь на него BitBlt() битмапа фона и
> рисуешь остальное.
>
> - советчик блин...
>
> TCanvas.Brush.Bitmap


ты о чем?


Омлет   (2011-11-22 15:14:00) [4]

> Anatoly Podgoretsky ©   (22.11.11 14:25) [23]
> Опять игнорируешь ClipRect, не больше его.


Есть весь компонент TImage (размера R0), есть его видимая на экране область (R1) и область, которой необходима перерисовка в момент WM_PAINT (R2) - ClipBox. Известно, что R0 >= R1 >= R2.
TImage всегда выводит пытается вывести R0, но винда его обрезает до R1 и копирует на экран. А реально надо вывести только R2, который часто меньше R1.


han_malign   (2011-11-22 14:51:00) [5]


> И насколько заливка кистью будет быстрее?

- по идее это должно делаться аппаратно...

но мерцать так же будет, поскольку один фиг второй раз заливку делать...
а вот если наследоваться от TCustomControl(TWinControl) и "один раз" менять TWinControl.Brush (со всеми прелестями WM_CTLCOLORxxx и WM_ERASEBKGND), то таки должно стать приятно...


Anatoly Podgoretsky   (2011-11-22 14:35:00) [6]

> Елена  (22.11.2011 14:31:24)  [24]

В конце концов тебе именно и решать оптимизировать или оставить все как
естью


Елена   (2011-11-22 14:31:00) [7]


> Anatoly Podgoretsky ©   (22.11.11 14:00) [20]


Все понятно, спасибо. Вот этот код меня полностью устраивает - просто "ездит" картинка от положения скрола и все.


...................................
 private
   Scale: Integer;
   CL_Width: Integer;
   CL_Height: Integer;
   Fon: TImage;
 public
   { Public declarations }
 end;

var
 MainF: TMainF;

implementation

uses About;

{$R *.dfm}

procedure TMainF.FormCreate(Sender: TObject);
var
 i,j: Integer;
begin
 Scale := 15;
 CL_Width := 100000;
 CL_Height := 70000;

 Fon := TImage.Create(ScrollBox);
 Fon.Parent := ScrollBox;
 Fon.SetBounds(0,0,Screen.Width,Screen.Height);
 Fon.Transparent := True;

 for i := 0 to Screen.Width div Scale do
   for j := 0 to Screen.Height div Scale do
   begin
     Fon.Canvas.Pixels[i*Scale,j*Scale] := clRed;
   end;

 ScrollBox.HorzScrollBar.Size := CL_Width;
 ScrollBox.HorzScrollBar.Range := CL_Width;
 ScrollBox.HorzScrollBar.Increment := 15;
 ScrollBox.HorzScrollBar.Position := 0;

 ScrollBox.VertScrollBar.Size := CL_Height;
 ScrollBox.VertScrollBar.Range := CL_Height;
 ScrollBox.VertScrollBar.Increment := 15;
 ScrollBox.VertScrollBar.Position := 0;
end;

procedure TMainF.ScrollBoxCanResize(Sender: TObject; var NewWidth,
 NewHeight: Integer; var Resize: Boolean);
begin
 Fon.Left := ScrollBox.HorzScrollBar.Position-ScrollBox.HorzScrollBar.Position;
 Fon.Top  := ScrollBox.VertScrollBar.Position-ScrollBox.VertScrollBar.Position;
end;


Anatoly Podgoretsky   (2011-11-22 14:25:00) [8]

> Омлет  (22.11.2011 14:22:22)  [22]

Опять игнорируешь ClipRect, не больше его.


Омлет   (2011-11-22 14:22:00) [9]

А я про то, что утверждение, будто "TImage перерисовывает что нужно, а не все подряд"- неверно, т.к. TImage перерисовывает всё подряд.


Anatoly Podgoretsky   (2011-11-22 14:00:00) [10]

У нее


Anatoly Podgoretsky   (2011-11-22 14:00:00) [11]

Разве у него это видно на экране?
for i := 0 to 10000 div Step do
  for j := 0 to 7000 div Step do

Что у него канва 10000*7000


Anatoly Podgoretsky   (2011-11-22 13:58:00) [12]

> Омлет  (22.11.2011 13:39:18)  [18]

А я про что речь то веду, нафиг расчитывать и выводить то что не нужно.


Омлет   (2011-11-22 13:39:00) [13]

> Anatoly Podgoretsky ©   (22.11.11 13:26) [17]

Понятно, что на невидимую часть канвы Виндоус не будет ничего выводить. Но суть в том, что будет перерисовываться вся видимая часть TImage, даже если не надо её всю обновлять.


Anatoly Podgoretsky   (2011-11-22 13:26:00) [14]

> Омлет  (22.11.2011 13:01:16)  [16]

А в Виндоус есть ClipRect
Там весь вывод использует обрезку вывода по границам, обычно cliprect
расчитывается динамически. Ну не перерисовывает Виндоус весь рабочий стол, а
только нужное окно, а то и часть его, как правило.


Омлет   (2011-11-22 13:01:00) [15]

> Anatoly Podgoretsky ©   (22.11.11 12:33) [15]

Никакого ClipRect там нет и в помине.

function TImage.DestRect: TRect;
var
 w, h, cw, ch: Integer;
 xyaspect: Double;
begin
 w := Picture.Width;
 h := Picture.Height;
 cw := ClientWidth;
 ch := ClientHeight;
 if Stretch or (Proportional and ((w > cw) or (h > ch))) then
 begin
if Proportional and (w > 0) and (h > 0) then
begin
     xyaspect := w / h;
     if w > h then
     begin
       w := cw;
       h := Trunc(cw / xyaspect);
       if h > ch then  // woops, too big
       begin
         h := ch;
         w := Trunc(ch * xyaspect);
       end;
     end
     else
     begin
       h := ch;
       w := Trunc(ch * xyaspect);
       if w > cw then  // woops, too big
       begin
         w := cw;
         h := Trunc(cw / xyaspect);
       end;
     end;
   end
   else
   begin
     w := cw;
     h := ch;
   end;
 end;

 with Result do
 begin
   Left := 0;
   Top := 0;
   Right := w;
   Bottom := h;
 end;

 if Center then
OffsetRect(Result, (cw - w) div 2, (ch - h) div 2);
end;


Anatoly Podgoretsky   (2011-11-22 12:33:00) [16]

> Омлет  (22.11.2011 11:39:13)  [13]

А какой ClipRect в данный момент, ну или хотя бы чему равен DestRect


Омлет   (2011-11-22 11:47:00) [17]

> han_malign   (22.11.11 11:21) [11]

И насколько заливка кистью будет быстрее?


Омлет   (2011-11-22 11:39:00) [18]

> Anatoly Podgoretsky ©   (22.11.11 11:06) [10]
> Это особенность Виндоус


> procedure TImage.Paint;
> begin
>   ...
>     with inherited Canvas do
>       StretchDraw(DestRect, Picture.Graphic);
>   ...
> end;


han_malign   (2011-11-22 11:25:00) [19]

З.Ы. Возможно еще пригодится SetBrushOrgEx(Canvas.Handle, ...)...


han_malign   (2011-11-22 11:21:00) [20]


> новый битмап, делаешь на него BitBlt() битмапа фона и рисуешь остальное.

- советчик блин...

TCanvas.Brush.Bitmap

Windows GDI
LOGBRUSH

  ....................

Remarks

Although lbColor controls the foreground color of a hatch brush, the SetBkMode and SetBkColor functions control the background color.

Windows 95: Creating brushes from bitmaps or DIBs larger than 8 by 8 pixels is not supported. If a larger bitmap is specified, only a portionof the bitmap is used.

Windows 98/Me, Windows NT/2000/XP: Brushes can becreated from bitmaps or DIBs larger than8 by 8 pixels.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо