![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TPaintBox & TImage [D7]
Елена © (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.