Форум: "Начинающим";
Текущий архив: 2012.03.04;
Скачать: [xml.tar.bz2];
ВнизTPaintBox & TImage Найти похожие ветки
← →
Елена (2011-11-22 00:33) [0]Добрый вечер мастера. Пожалуйста помогите в таком вот вопросе - нужно нарисовать на форме пиксельную сетку, наподобие формы 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 вылазит белый фон, с которым ничего не поделаеш.
Как быть?
← →
Германн © (2011-11-22 00:48) [1]
> а размеры 10000Х7000 должны быть именно такими
А почему должны?
← →
KilkennyCat © (2011-11-22 00:50) [2]
> размеры 10000Х7000
у тебя такой монитор? офигеть....
может, стоит рисовать только то, что будет видно?
← →
KilkennyCat © (2011-11-22 00:52) [3]
> Но это будет требовать постоянной перерисовки,
все зависит от того, что ты хочешь сделать. если эта сетка является фоном для всего остального, то нарисуй ее один раз, на битмаре, и не удаляй его.
а потом просто берешь новый битмап, делаешь на него BitBlt() битмапа фона и рисуешь остальное.
если остальное такого же рода, то и с ним точно также - BitBlt битмапов.
← →
KilkennyCat © (2011-11-22 00:53) [4]да, ну и в конечном итоге BitBlt на че хочешь, паинтбокс, имадж, хоть сразу на форму.
← →
Елена (2011-11-22 01:44) [5]
> KilkennyCat © (22.11.11 00:50) [2]
TImage или TPaintBox находится в ScrollBox, чтобы прокручивать этот размер, а монитор самый обычный.
> может, стоит рисовать только то, что будет видно?
> то нарисуй ее один раз, на битмаре, и не удаляй его.
> а потом просто берешь новый битмап, делаешь на него BitBlt()
> битмапа фона и рисуешь остальное.
Это как?
← →
KilkennyCat © (2011-11-22 02:12) [6]
>
> Это как?
еще раз:
при запуске программы:
создаем битмап fonBMP, квадрат, равен какому-нить разумному размеру, например, четверть от монитора.;
Об этом можно прочитать в справке про TBitMap, TScreen
рисуем на fonBMP.Canvas сетку.
создаем битмап mainBMP с размером, равным отображаемому.
работа программы:
при ресайзинге:
изменяем размер mainBMP
при скроллинге или иных причинах перерисовки делаем следующее:
заполняем mainBMP содержимым fonBMP с учетом смещения скроллинга (создаем эффект движения сетки при скроллинге) при помощи функции BitBlt (читаем про нее в MSDN)
если координаты скроллинга сообщают нам о том, что это будет видно, рисуем на mainBMP то, что собственно хотим.
при помощи BitBlt копируем mainBMP на хоть Form.canvas
по окончании программы:
убиваем mainBMP и fonBMP
← →
Омлет © (2011-11-22 09:35) [7]> Елена (22.11.11 00:33)
1. Pixels в циклах категорически нежелательно использовать, т.к. это медленная операция. Чтобы выводить линии, пользуйтесь методами MoveTo и LineTo.
2. Перерисовывать надо только видимую часть и только требующую перерисовки область.
3. TImage - выкинуть и забыть.
← →
Anatoly Podgoretsky © (2011-11-22 09:55) [8]
> Но это будет требовать постоянной перерисовки,
Но это принципы работы виндоус, в любой момент изображение на экране может быть зменено другим, так что или ты сама постоянно перерисовываешь, или используешь TImage, который это делает за тебя, то что у тебя ничего не выходит с TImage значения не имеет.
Кстати TImage перерисовывает что нужно, а не все подряд
← →
Омлет © (2011-11-22 11:00) [9]> Кстати TImage перерисовывает что нужно, а не все подряд
Это в какой версии Дельфи?
← →
Anatoly Podgoretsky © (2011-11-22 11:06) [10]> Омлет (22.11.2011 11:00:09) [9]
Это особенность Виндоус
← →
han_malign (2011-11-22 11:21) [11]
> новый битмап, делаешь на него 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 portion of the bitmap is used.
Windows 98/Me, Windows NT/2000/XP: Brushes can be created from bitmaps or DIBs larger than 8 by 8 pixels.
← →
han_malign (2011-11-22 11:25) [12]З.Ы. Возможно еще пригодится SetBrushOrgEx(Canvas.Handle, ...)...
← →
Омлет © (2011-11-22 11:39) [13]> Anatoly Podgoretsky © (22.11.11 11:06) [10]
> Это особенность Виндоус
> procedure TImage.Paint;
> begin
> ...
> with inherited Canvas do
> StretchDraw(DestRect, Picture.Graphic);
> ...
> end;
← →
Омлет © (2011-11-22 11:47) [14]> han_malign (22.11.11 11:21) [11]
И насколько заливка кистью будет быстрее?
← →
Anatoly Podgoretsky © (2011-11-22 12:33) [15]> Омлет (22.11.2011 11:39:13) [13]
А какой ClipRect в данный момент, ну или хотя бы чему равен DestRect
← →
Омлет © (2011-11-22 13:01) [16]> 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 13:26) [17]> Омлет (22.11.2011 13:01:16) [16]
А в Виндоус есть ClipRect
Там весь вывод использует обрезку вывода по границам, обычно cliprect
расчитывается динамически. Ну не перерисовывает Виндоус весь рабочий стол, а
только нужное окно, а то и часть его, как правило.
← →
Омлет © (2011-11-22 13:39) [18]> Anatoly Podgoretsky © (22.11.11 13:26) [17]
Понятно, что на невидимую часть канвы Виндоус не будет ничего выводить. Но суть в том, что будет перерисовываться вся видимая часть TImage, даже если не надо её всю обновлять.
← →
Anatoly Podgoretsky © (2011-11-22 13:58) [19]> Омлет (22.11.2011 13:39:18) [18]
А я про что речь то веду, нафиг расчитывать и выводить то что не нужно.
← →
Anatoly Podgoretsky © (2011-11-22 14:00) [20]Разве у него это видно на экране?
for i := 0 to 10000 div Step do
for j := 0 to 7000 div Step do
Что у него канва 10000*7000
← →
Anatoly Podgoretsky © (2011-11-22 14:00) [21]У нее
← →
Омлет © (2011-11-22 14:22) [22]А я про то, что утверждение, будто "TImage перерисовывает что нужно, а не все подряд" - неверно, т.к. TImage перерисовывает всё подряд.
← →
Anatoly Podgoretsky © (2011-11-22 14:25) [23]> Омлет (22.11.2011 14:22:22) [22]
Опять игнорируешь ClipRect, не больше его.
← →
Елена (2011-11-22 14:31) [24]
> 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:35) [25]> Елена (22.11.2011 14:31:24) [24]
В конце концов тебе именно и решать оптимизировать или оставить все как
естью
← →
han_malign (2011-11-22 14:51) [26]
> И насколько заливка кистью будет быстрее?
- по идее это должно делаться аппаратно...
но мерцать так же будет, поскольку один фиг второй раз заливку делать...
а вот если наследоваться от TCustomControl(TWinControl) и "один раз" менять TWinControl.Brush (со всеми прелестями WM_CTLCOLORxxx и WM_ERASEBKGND), то таки должно стать приятно...
← →
Омлет © (2011-11-22 15:14) [27]> Anatoly Podgoretsky © (22.11.11 14:25) [23]
> Опять игнорируешь ClipRect, не больше его.
Есть весь компонент TImage (размера R0), есть его видимая на экране область (R1) и область, которой необходима перерисовка в момент WM_PAINT (R2) - ClipBox. Известно, что R0 >= R1 >= R2.
TImage всегда выводит пытается вывести R0, но винда его обрезает до R1 и копирует на экран. А реально надо вывести только R2, который часто меньше R1.
← →
KilkennyCat © (2011-11-22 17:45) [28]
> han_malign (22.11.11 11:21) [11]
>
>
> > новый битмап, делаешь на него BitBlt() битмапа фона и
> рисуешь остальное.
>
> - советчик блин...
>
> TCanvas.Brush.Bitmap
ты о чем?
← →
han_malign (2011-11-23 08:56) [29]
> ты о чем?
- я о том, что большинстве случаев DoubleBuffered - только добавляет тормозов...
А для отрисовки фона есть специально заточенный объект GDI - Brush, который начиная с W98 не ограничен ни глубиной цвета, ни размером 8x8...
З.Ы. В блитинге могут использоваться комбинации всех трех растров - источника, кисти и растра назначения...
← →
KilkennyCat © (2011-11-23 13:14) [30]понятно.
ну, у меня как-то так получается, что практическе всегда буферизация и рисование на дс в памяти несколько быстрее.
наверное, мне просто везет.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2012.03.04;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.004 c