Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > использование Canvas....


Автор: txx 28.7.2006, 22:14
решил более подробно изучить графические возможности делфи ... объясните кто-нибудь в чём разница если я рисую просто на ... .canvas  или же обращаюсь к ней через ... .pictures.BitMap.canvas  ...читал несколько статей, где мельком показывалась разница между этими способами, но всё это как-то очень "размыто" и не совсем ясно ... объясните, пжалста, русскими словами и в общих чертах если можно smile) 
.... заранее пасиб. 

Автор: Alexeis 28.7.2006, 22:32
canvas - объект связаный с некоторым устройством, при помощи контекста (DC), работа с любым контекстом с позиции програмирования одинакова, однако результат действия завит от устройства с которым связан контекст. Если это контекст принтера, то изображение выведится на принтер, если контекст окна, то нарисуется на окне. С битмапом связан особый контекст, контекст памяти, который позволяет рисовать на невидимой облости расположенной в памяти. При этом изображение из битмапа, можно копировать куда угодно. Но битмап кроме всего прочего позволяет рисовать на свойе поверхности даже без контекста - напрямую записывая значения цветов в память.  Что касается Image1.picture.BitMap.canvas, то рисование на этом канвасе ни чем ни отличается от рисования на TBitmap с одной лишь разницей, что объект TImage выводит автоматически изображения на свою видимою поверхность, что избавляет програмиста от написания кода обновления изображения например при затирании изображения другим окном. 

Автор: demon13 15.8.2006, 15:34
Код

procedure TForm1.Timer1Timer(Sender: TObject);
var
i, p: integer;
begin
 p:= Random(1023);

 Application.ProcessMessages;

 for i:=0 to 763 do
 begin
  if z=1 then
   Break;

  Form1.Canvas.Font.Name:='RomanS';
  Form1.Canvas.Font.Color:=clGreen;
  Form1.Canvas.Font.Height:=32;
  Form1.Canvas.TextOut(p,i,'A');
  Sleep(5);
 end
end;


у меня несколько таймеров выполняют эту процедуру, но падает только одна буква остальные стоят на месте что можно зделать чтобы остальные буквы тоже двигались smile 

Автор: Alexeis 15.8.2006, 19:45
Цитата

но падает только одна буква остальные стоят на месте

так выводится же только одна буква
Form1.Canvas.TextOut(p,i,'A');

Добавлено @ 19:46 
чтоб остальные двигались надо выводить все smile

Автор: demon13 15.8.2006, 21:31
Шесть таймеров выполняют эту прцидуру и прорисовываются все шесть букв а двигается одна

Автор: Alexeis 15.8.2006, 23:05
Чет кроме буквы "а" ничего не выводится smile 
Везде
Код

 Form1.Canvas.TextOut(p,i,'A');

где вывод других букв, 
Таймеров то 6, но выводят они все одно и тоже
Код

procedure TForm1.Timer1Timer(Sender: TObject);
var
i, p: integer;
begin
 p:= Random(1023);

 Form1.Canvas.Font.Name:='RomanS';
 Form1.Canvas.Font.Color:=clGreen;
 Form1.Canvas.Font.Height:=15;
 Form1.Canvas.TextOut(p,0,'A');

 for i:=0 to 763 do
 begin
  if z=1 then
   Break;

  Application.ProcessMessages;
  Form1.Canvas.Font.Name:='RomanS';
  Form1.Canvas.Font.Color:=clGreen;
  Form1.Canvas.Font.Height:=32;
  Form1.Canvas.TextOut(p,i,'A');
  Sleep(5);
 end
end;

Не ужели нужно выводить 6 букв "a"???

Автор: demon13 15.8.2006, 23:28
Тот код уже не актуален

Добавлено @ 23:34 
Эту идею я взял с http://earnik.com/forum/topic21864.html

Автор: Alexeis 16.8.2006, 00:58
Я тут по быстрому свою матрицу накидал smile 
но уж забыл как там точно было.
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  ch  : array[1..40, 1..40] of Char;

  p : Integer = 40;
  h : Integer;
  w : Integer;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i, j, hi, wi : Integer;
begin
  PatBlt(Canvas.Handle, 0, 0, ClientWidth, ClientHeight, BLACKNESS);

  hi := 10;
  wi := 10;

  for i := 1 to 40
  do
    Begin
      if p = 0
      then
        p := 40;

      hi := 10;

      for j := p to 40
      do
        begin
          Canvas.TextOut(wi, hi, ch[i, j]);
          hi := hi + h;
        end;

      for j := 1 to p-1
      do
        begin
          Canvas.TextOut(wi, hi, ch[i, j]);
          hi := hi + h;
        end;

      wi := wi + w;
    end;

  Dec(p);
end;



procedure TForm1.FormCreate(Sender: TObject);
var
  i, j : Integer;

begin
   Randomize;

   for i := 1 to 40
   do
     for j := 1 to 40
     do
       ch[i, j] :=Chr(Ord('a') + Random(25));


  Font.Name := 'comic sans ms';
  Font.Color := $008000;
  Font.Style := [fsBold];
  Font.Size := 10;

  Canvas.Font.Name := 'comic sans ms';
  Canvas.Font.Color := $008000;
  Canvas.Font.Style := [fsBold];
  Canvas.Font.Size := 10;

   Form1.Color := clBlack;

   h := Canvas.TextHeight('A');
   w := Canvas.TextWidth(' A ');


   DoubleBuffered := True;
   DoubleBuffered := True;
end;

end.


Автор: demon13 16.8.2006, 20:58
Зделано круто не спорю smile 

Автор: demon13 16.8.2006, 21:00
 smile Но думаю лучше не просто буквы, а двоичный код

Автор: demon13 16.8.2006, 21:02
Скачиваете эти файлы в одну папку, переименовываете их и запускаете disk1.EXE smile   весь исходный код написан alexeis1 большое ему спасибо

Автор: Alexeis 16.8.2006, 22:07
Тут еще явно напрашивается какой нибудь фильтр, для размытия в вертикальном направлении.
И еще нужен выход по движению мышки.
demon13, хорошо бы выложить модифицированный код, а то я вижу количество столбцов сократилось до 25 это зависит от разрешения экрана.  Напрашивается сделать в OpenGl, чтоб сразу и масштаб был автоматическим и скорость. Вообще, если покалдовать, то симпатичненький ScreanSaver выйдет.

Автор: demon13 16.8.2006, 22:50
Столбцов осталось столько же, размер шрифта увеличился.

вот ноый код. Завтра насчет мыши сделаю.

Добавлено @ 23:00 
Ну да заставка прикольная может выйти. Калдовать будем? smile 

Автор: Alexeis 17.8.2006, 00:37
Только вот бы на оригинал взглянуть, а то я фильм года три назад видел, детали не помню этого эффекта.
Где бы фрагмент скачать?

Автор: demon13 17.8.2006, 00:50
На нашу прогу похоже?

Добавлено @ 01:01 
Я сейчас качаю какойто фрагмент http://www.dvdpirat.ru/Kpk/The_matrix_revolutions-kpk.avi, скачаю, скажу то или нет.

Автор: demon13 17.8.2006, 01:13
На ссылке видео очень познавательное, но не то smile

Добавлено @ 01:13 
Буду еще искать.

Автор: Alexeis 17.8.2006, 01:16
Да тут еще размытие надо будет сделать.
Ксати 
Цитата(demon13 @  16.8.2006,  22:50 Найти цитируемый пост)
Столбцов осталось столько же, размер шрифта увеличился.
 Значит надо уменьшить массив и циклы, иначе строки считаются напрасно, да еще вниз уходят напрасно. Размер видимой матрицы 31x26, такая же должна быть и размерноть матрицы чаров. Зачем пустые операции вывода?

Автор: demon13 17.8.2006, 01:25
А как сделать размытие?
Цитата(alexeis1 @  17.8.2006,  01:16 Найти цитируемый пост)
 Значит надо уменьшить массив и циклы, иначе строки считаются напрасно, да еще вниз уходят напрасно. Размер видимой матрицы 31x26, такая же должна быть и размерноть матрицы чаров. Зачем пустые операции вывода?
 - это панты 5 секунд подредактировать.

Добавлено @ 01:29 
Цитата(alexeis1 @  16.8.2006,  22:07 Найти цитируемый пост)
хорошо бы выложить модифицированный код

Скачай код и попробуй сделать размытие.

Автор: Alexeis 17.8.2006, 01:30
Цитата(demon13 @  17.8.2006,  01:25 Найти цитируемый пост)
А как сделать размытие?

Да в любом факе можно встретить размытие по Гаусу, простая операция свертки с гаусианом.
Имеются уже готовые алгоритмы, но вот выводить лучше на невидимую поверхность битмапа ее обработать и целиком на экран отрисовывать.

Добавлено @ 01:31 
Цитата(demon13 @  17.8.2006,  01:25 Найти цитируемый пост)

Скачай код и попробуй сделать размытие.

Попробую.

Автор: demon13 17.8.2006, 01:46
Cмотри что я нашел вот-

Автор: demon13 17.8.2006, 01:47
и вот

Добавлено @ 01:54 
Правда у меня первая только начинается и выходит smile 

Автор: Alexeis 17.8.2006, 01:56
demon13, смотрится ничего, но ведь там букы, а что в фильме они тоже как капли стекали? 
Ну это на самом дле не самая лучшая, я видел и красивее. Что касается размытия, то придется вначале получать картинки единиц и нулей, делать размытие, а затем их рисовать, иначе получается 1 кадр в секунду. smile 

Автор: demon13 17.8.2006, 01:58
Во 2-ой зделано как в фильме.

Автор: Alexeis 17.8.2006, 02:07
Кстати буквы разной яркости, так создается эффект трехмерности.

Добавлено @ 02:08 
Цитата(demon13 @  17.8.2006,  01:47 Найти цитируемый пост)
Правда у меня первая только начинается и выходит smile

После 4 попытки и задержки дыхания она таки работает smile 

Автор: demon13 17.8.2006, 02:11
Первая очень прикольная, только символы там не в тему использованы smile 

Автор: Alexeis 17.8.2006, 02:19
Первая намного сложнее, поскольку там происходит еще рэндомизированое гашение одельных элеменов хвоста, что усиливат эффект растекания.

Автор: demon13 17.8.2006, 02:22
НО она и намного красивее smile 

Автор: Alexeis 17.8.2006, 02:24
Яркие капли бегут быстрее, т.е. определена функция яркости от скорости, но гашение там просто супер сделано, вроде и рэндом, но начало следа всегда яркое без фрагментов, а концовка почти всегда удаляется целиком.

Автор: demon13 17.8.2006, 02:30
Добавлено @ 02:35 
Что лучше всего?
1) нарисовать символы
2)использовать двоичный код
3)Англицкие буквы

Автор: Alexeis 17.8.2006, 09:27
Цитата(demon13 @  17.8.2006,  02:30 Найти цитируемый пост)
А при помощи чего сделана 1 заставка?

При помощи того что и наша, написана на GDI, использует двойную буферизацию через дополнительный битмап который выводится на экран функцией bitblt, кроме того, там не произвоится полного стерания всей картини перед началом рисования нового кадра. А текст выводится Textout, цвет фона текста устанавливается SetBkColor.
но судя по размеру файла (280кб) ее писали не на чистом API smile

Добавлено @ 09:30 
Цитата(demon13 @  17.8.2006,  02:30 Найти цитируемый пост)
Что лучше всего?

Я думаю нули и единицы, просто может их как нибудь улучшить в Фотошопе.

Автор: demon13 17.8.2006, 09:33
Чтоб похитрей придумать  smile  Если просто поставить OnMouseMove Close, то получается как с первым screenSever'ом smile 

Автор: Alexeis 17.8.2006, 10:19
Цитата(demon13 @  17.8.2006,  09:33 Найти цитируемый пост)
Если просто поставить OnMouseMove Close, то получается как с первым screenSever'ом

Так надо поставить таймер и активизировать обработку события только через пол секунды

Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  OnMouseMove := nil;
  tmr1.Interval := 500;
  tmr1.Enabled := True;
end;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  tmr1.Enabled := False;
  OnMouseMove := FormMouseMove;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Close;
end;

Автор: demon13 17.8.2006, 10:30
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  OnMouseMove := nil;
  tmr1.Interval := 500;
  tmr1.Enabled := True;
end;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  tmr1.Enabled := False;
  OnMouseMove := FormMouseMove;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Close;
end;

Работает пол секунды и выходит.

Автор: Alexeis 17.8.2006, 11:07
Цитата(demon13 @  17.8.2006,  10:30 Найти цитируемый пост)
Работает пол секунды и выходит.

Что даже если мышь не шевилить?

Автор: demon13 17.8.2006, 12:22
Дааааа, Adobe Photoshop CS2 мне не друг smile 

Автор: Alexeis 17.8.2006, 12:23
Странно, у меня работает, тогда можно пределить малую облать при выходе из которой будет считатся, что мышь сдвинули.
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  OnMouseMove := nil;
  tmr1.Interval := 500;
  tmr1.Enabled := True;
end;

var
  p0 : TPoint;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  tmr1.Enabled := False;
  OnMouseMove := FormMouseMove;
  GetCursorPos(p0);
  p0 := Form1.ScreenToClient(p0)
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if (abs(x - p0.x) > 20) or (abs(y - p0.y) > 20)
  then
    Close;
end;


Добавлено @ 12:34 
Цитата(demon13 @  17.8.2006,  12:22 Найти цитируемый пост)
Дааааа, Adobe Photoshop CS2 мне не друг 

Да ладно всавить нолик в картинку и применить фильтр, тут много ума не надо smile 

Автор: demon13 17.8.2006, 12:35
Так все отлично работает.

Автор: Alexeis 17.8.2006, 13:05
Вот примерчик "1" с в масштабе 400%

Автор: demon13 17.8.2006, 13:16
Это при помощи размытия зделано?

Автор: Alexeis 17.8.2006, 13:20
А вот нолик

Цитата

Это при помощи размытия зделано?

1) Градиентная заливка
2) Moution Blur -90 градусов 2 пиксела
3) Wave Blur

Автор: Alexeis 17.8.2006, 13:41
Вот и в масштабе 100%

Автор: demon13 17.8.2006, 17:14
Выглядит классно smile 

Автор: Alexeis 17.8.2006, 17:24
demon13, так вот предлагаю сделать плагиат, той красивой заставки, только улучшить ее маленько. Надо будет наш алгоритм доработать и еще проидется делать несколько вариантов нулей и единиц с разной яркостью. Рисовать их будем прям на канве, при помощи BitBlt.

Автор: demon13 17.8.2006, 17:40
Цитата(alexeis1 @  17.8.2006,  17:24 Найти цитируемый пост)
Надо будет наш алгоритм доработать

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

Автор: Alexeis 17.8.2006, 17:59
Цитата(demon13 @  17.8.2006,  17:40 Найти цитируемый пост)
 а самим их стерать.
 выше определенной  позиции отсчиывая от головы "капли". Там так и сделано, но они пропадают с разной вероятностью, те что достаточно далеко почти, наверняка исчезают, те что поближе 50/50 что исчезнут, те что рядом никогда не исчезают. Если быстрый накрывает медленого, то он его "убивает" совсем. Для каждого потока надо будет создавать структуру(record), где будет хранится голова, скорость и яркость капли. Эти структуры надо будет динамически добавлять и убирать из очереди капель. И сделать обработчик который будет по очереди рисовать каждую каплю (бесконечный цикл).
И еще неплохо бы число линий подбирать динамически, в зависимости от разрешения экрана.
Попробую кое что из этого сделать. Если что отпишусь. smile 

Автор: demon13 17.8.2006, 18:08
Цитата(alexeis1 @  17.8.2006,  17:59 Найти цитируемый пост)
И еще неплохо бы число линий подбирать динамически, в зависимости от разрешения экрана.

Напиши при каком разрешении сколько линий ставить и source выложи.

Автор: demon13 17.8.2006, 23:13
Цитата(alexeis1 @  17.8.2006,  17:59 Найти цитируемый пост)
Там так и сделано, но они пропадают с разной вероятностью, те что достаточно далеко почти, наверняка исчезают, те что поближе 50/50 что исчезнут, те что рядом никогда не исчезают.


Автор: demon13 17.8.2006, 23:14
Я думаю это легко объяснить

Автор: demon13 17.8.2006, 23:16
Может конечно яне прав, но все же.

Автор: Alexeis 18.8.2006, 01:15
Вот нашел фрагмент матрицы
[url=    http://rapidshare.de/files/29793631/matrix.avi.html]    http://rapidshare.de/files/29793631/matrix.avi.html[/url]
Да тут существует два эффекта, нужно бы разобранся какой из них делать
из нулей и единиц красиво не выходит.

Автор: demon13 18.8.2006, 01:54
Все цифры лево смотрятся, машинный код гураздо лучше.

Добавлено @ 02:01 
Цитата(alexeis1 @  18.8.2006,  01:15 Найти цитируемый пост)
Да тут существует два эффекта, нужно бы разобранся какой из них делатьиз нулей и единиц красиво не выходит.

Ты хочеш машинный код заменить буквами?

Автор: Alexeis 18.8.2006, 09:28
Цитата(demon13 @  18.8.2006,  01:54 Найти цитируемый пост)
Ты хочеш машинный код заменить буквами?

Я пробовал написать эффект "переливания"(мерцания) головы капли, при использовании одних нулей и единиц это смотрится слабо, лучше уж 16-тиричные символы отображать. 
demon13, если посмотрел отрывок видео, то там два эффекта. Первый - "стекание" иероглифов с несплошным заполнением экрана, второй  "стекание" десятичных цифр при полном заполнении экрана, т.е. без гашения отдельных символов, а только с их наложением. Там цифры объединены в группы как WinHeX. Думаю логичней будет его воспроизводить, поскольку в иероглифах мало смысла.

Автор: demon13 18.8.2006, 10:49
Цитата(alexeis1 @  18.8.2006,  09:28 Найти цитируемый пост)
лучше уж 16-тиричные символы отображать. 

Так smile 

Автор: Alexeis 18.8.2006, 11:45
Ну можно еще разделить на группы по 6 - 7 столбцов, а между ними промежутки и еще надо их моноширным шрифтом выводить, тогда необходимость в очистке экрана отпадет.

Добавлено @ 11:51 
кроме того перед появлением на экране символ на время зажечь надо, а затем погасить, когда будет смещение к следующему шагу.

Автор: demon13 18.8.2006, 12:04
Как в таком виде   Font.Color := $008000; будет выглядить Red - 150, Green - 255, Blue - 100.
Ты настройки в The Matrix Green Screen видел smile 

Автор: dumb 18.8.2006, 12:23
afair $00BBGGRR, т.е. $0064ff96

Автор: Alexeis 18.8.2006, 12:50
Цитата(demon13 @  18.8.2006,  12:04 Найти цитируемый пост)
Ты настройки в The Matrix Green Screen видел

Не неразбирался.
А вот вместо 

Цитата(demon13 @  18.8.2006,  12:04 Найти цитируемый пост)
Red - 150, Green - 255, Blue - 100.
 Я бы сделал $00FF00

Автор: demon13 18.8.2006, 12:58
Цитата(alexeis1 @  18.8.2006,  11:45 Найти цитируемый пост)
Ну можно еще разделить на группы по 6 - 7 столбцов, а между ними промежутки
 типа так smile 

Автор: Alexeis 18.8.2006, 13:14
Ага ничего, красиво, вот только мерцает жутко, что от очистки канвы еще не отказался?

Автор: demon13 18.8.2006, 13:35
Цитата(alexeis1 @  18.8.2006,  13:14 Найти цитируемый пост)
вот только мерцает жутко

а как мерцание убрать?

Автор: Alexeis 18.8.2006, 14:02
Цитата(demon13 @  18.8.2006,  13:35 Найти цитируемый пост)
а как мерцание убрать?

Лучше всего выводить на Canvas TBitapa, а затем рисовать его 
либо BitBllt, либо, при помощи canvas.Draw формы.

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

Автор: demon13 18.8.2006, 14:15
Выложи свой exe'шник. smile 

Автор: Alexeis 18.8.2006, 23:42
Цитата(demon13 @  18.8.2006,  14:15 Найти цитируемый пост)
Выложи свой exe'шник.

К сожалению у меня нет сейчас времени сделать полностью весь алгоритм, но могу показать вывод изображения через промежуточный битмап.

Автор: demon13 18.8.2006, 23:43
Цитата(alexeis1 @  18.8.2006,  23:42 Найти цитируемый пост)
но могу показать вывод изображения через промежуточный битмап.
 давай.

Автор: Alexeis 19.8.2006, 00:04
Вот тут идет воспроизведение 25 кадров в секунду без мерцания, правда от этого не легче поскольку картинка рэндомизированая и в глазах и без мерцания рябит smile 
Внимание закрытие осуществляется по нажатию кнопки ESC
Прикрепил

Автор: demon13 19.8.2006, 08:26
Чет я никак скачать не магу smile  В обед еще попробую smile

Добавлено @ 08:30 
Я надеюсь на 2006-ой раз скачается smile 

Автор: Alexeis 19.8.2006, 12:02
demon13, Ладно я закачал копию на народ
http://alexei-s1.narod.ru/Sample.7z
p.s. Проверил скачивание по старой ссылке - все ОК!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)