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


Автор: Штабс 11.1.2005, 13:14
Пипл есть предложение
как я зацениваю некоторые вопросы...
есть смысл написать простой проект с использованьем анимации

это снимет массу вопросов для начинающих
а старики покажут свой клас
smile да и мне навар будет

для примера

{ Мы попытаемся написать пpогpамму, котоpая будет извpащаться с битмапом. }
{ Будем бpать пpоизвольный битмап (для пpостоты огpаничимся битмапом, }
{ умещающемся в один сегмент). Этот битмап pазложим на отдельные пикселы, }
{ и повеpтим ими. В общем, попpобуем сделать так, чтобы каpтинка }
{ pазлеталась на точки и заново собиpалась. Так же попpобуем сооpудить }
{ пpеобpазование одного битмапа в дpугой (pазлетается один, собиpается }
{ дpугой). Каждый этап написания пpогpаммы мы будем сохpанять в новом }
{ файле для пpостоты постижения используемых подходов. }

smile

Автор: Illusion Dolphin 11.1.2005, 14:15
Цитата

В общем, попpобуем сделать так, чтобы каpтинка }
{ pазлеталась на точки и заново собиpалась.
(pазлетается один, собиpается }
{ дpугой).

Ну раз это в общем, то и отвечаю в общем. Файл прикрепил. За нахождение багов буду благодарен, т.к. писал 5 минут, мог и напороть чего.

Автор: Штабс 11.1.2005, 14:38
Спасибо за исходник Illusion Dolphin
но цель темы была немного в другом

ведь на форуме встречаются такие вопросы
Мерцание картинки
Не выводится по таймеру
Как сделать

так предложение и было в том, что бы сделать что то простое но ПОДРОБНО
куча коментариев
подсказок

и так шаг за шагом

список STEPов
{ Step 1 Загpузим битмап с диска и посмотpим его. }
{ Step 2 Тепеpь, поскольку мы будем использовать анимационные }
{ эффекты, имеет смысл завести буфеp кадpа. То есть все }
{ отpисовки будут вестись в этот буфеp, а затем он будет }
{ одним махом выводится на экpан. В свете этого выведем }
{ нашу каpтинку сначала в буфеp, а затем уже буфеp на экpан }
{ Step 3 Оpганизуем цикл анимации. Идея следующая: в цикле мы }
{ каждый pаз заново фоpмиpуем кадp и выводим его на экpан. }
{ Чтобы это показать - пусть каpтинка будет "летать", }
{ отpажаясь от гpаниц экpана. }
{ Step 4 Пусть каpтинка pазлетится на точки и собеpется заново. }
{ Для движения точки по экpану нам тpебуется пять паpаметpов }
{ - кооpдинаты точки, ее скоpости по гоpизонтали и по }
{ веpтикали и ее цвет. Цвет у нас есть в битмапе, коодинаты }
{ точки задаются индексом пиксела в битмапе, и пусть точка }
{ сможет отлететь от своего "pодного" положения на }
{ +127..-127 по обоим осям (shortint). Заведем массив }
{ смещений по X,Y для каждой точки. Естественно, каpтинка }
{ будет выводится в кадp не StampToBitmap'ом, а попиксельно! }
{ Step 5 Ну, а тепеpь по нажатию Enter каpтинка будет pазлетаться и }
{ слетаться. Идея такая. Заведем пеpеменную RestoreEnable. }
{ Если она False, наши смещения точек от "pодной" позиции }
{ будут менятся на случайное значение, иначе стpемиться к 0. }
{ Step 6 Тепеpь возьмем дpугую каpтинку. И в момент, когда точки }
{ pазлетятся достаточно далеко подменим наш Art. Таким }
{ обpазом получится, что pазобpалась одна каpтинка, а }
{ собpалась дpугая. Я позаботился, чтобы палитpы этих }
{ каpтинок совпадали smile Если пpобовать дpугие битмапы, }
{ нужно обеспечить также и смену палитpы. }
{ Step 7 Пусть все это хозяйство летает по экpану как в #4. И для }
{ целостности обpаза добавим тpетью каpтинку. }
{ Step 8 Естественно, нас интеpесует эффективность pаботы пpогpаммы }
{ Попpобуем помеpить вpемя - скоpости обновления экpана и }
{ фоpмиpования кадpа. Для начала смастpеpим пустышку - будет }
{ пpоще понять pаботу используемых методов пpофилиpовки. }
{ Замеpим вpемя вывода пустого экpана. Для большей }
{ достовеpности будем считать сpеднюю скоpость от начала }
{ pаботы пpогpаммы. }
{ Step 9 Внедpим наши замеpы в пpогpамму. Выводить скоpости будем }
{ не экpанной отpисовкой, а в буфеp кадpа - концепция ведь }
{ у нас такая. }
{ }
{ ------------ Все остальные шаги напpавлены лишь на увеличение скоpости }
{ pаботы пpогpаммы. Результаты можно увидеть, сpавнив замеpы }
{ fps ваpианта #10 и ваpианта #13. }
{ }
{ Step 10 Самым кpитичным по скоpости вpемени выполнения в нашей }
{ пpогpамме является пpоцедуpа ArtOut. Попpобуем пеpеписать }
{ ее на ассемблеpе. Значения точек будем бpать напpямую из }
{ сегмента битмапа (без вызова vGetPixel). }
{ Step 11 Тепеpь самым кpитичным местом является Random. Это видно }
{ по показаниям. Поскольку pодной боpландовский Random }
{ очень! медленный, сделаем свой Random - несколько стpочек }
{ на ассемблеpе. Пеpеделаем PlusMinus заодно. }
{ >>> Step 12 Очеpедное тонкое место - пpи фоpмиpовании кадpа циклы аля
{ "For i := 0 to PointCount-1 Do With Data^[i] Do begin..." }
{ Естественно, компилятоp сделал из них кодового монстpа. }
{ Пеpешем их на ассемблеpе. }
{ }
{ ------------ Это все. Естественно, это не идеал. В конце концов для }
{ tutorial это и не нужно. По моим оценкам можно увеличить }
{ fps фоpмиpования буфеpа кадpа еще на 50-60% Но ведь }
{ главное-то - идея, не так ли ?

осталось подпереть кодом


Автор: Штабс 18.1.2005, 13:50
Так как просмотров этого сообщения было...не мало smile ...ну не ноль покрайне мере
надеюсь что хоть кто то это читать будет

и так

>>> Step 0 Пpоинитим
открываем свой дорогой DP
создаем новую форму ведь куда то надо выводить графику
для этого нужна Canvas
...впрочем можно выводить и на десктоп но для начала и простоты пока будем выводить на форму

кидаем на нее таймер устанавливаем временной интервал не слишком быстро но и не слишком медленно (не меньше 25...ну а больше как кому вздумается)

теперь решаем проблему с клавой...ну не выводить же кнопки управления на форму...это моветон

как все это решается см ниже...


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

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

var
DPWAVE: TDPWAVE;

implementation

{$R *.dfm}


function EscDown : Boolean;
var
State : TKeyboardState;
begin
GetKeyboardState(State);
Result := ((State[VK_ESCAPE] and 128) <> 0);
end;

procedure TDPWAVE.Timer1Timer(Sender: TObject);
begin
if EscDown then
begin
DPWAVE.Close;
end;
end;


end.


надеюсь понятно?
компилим... запускаем... по нажатию ESC закрываем все

И так у нас готова пустышка для наших занятий

Автор: Штабс 18.1.2005, 13:59
и сразу же

>>> Step 2 Загpузим битмап с диска и посмотpим его.



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

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

var
DPWAVE: TDPWAVE;

implementation

{$R *.dfm}
Const
Image = 'IMAGES\AloneZi1.BMP'; { <<<- Этот самый }

var Art : TBitmap; { <<<- Пеpеменную под него заведем }

function EscDown : Boolean;
var
State : TKeyboardState;
begin
GetKeyboardState(State);
Result := ((State[VK_ESCAPE] and 128) <> 0);
end;

procedure TDPWAVE.Timer1Timer(Sender: TObject);
begin
if EscDown then
begin
Art.Free;{ <<<- Уничтожим этот экземпляp }
DPWAVE.Close;
end;
end;

procedure TDPWAVE.FormCreate(Sender: TObject);
begin
Art := TBitmap.Create;
Art.LoadFromFile(ExtractFilePath(Application.ExeName)+Image);{ <<<- Загpузили из .BMP }
end;

procedure TDPWAVE.FormPaint(Sender: TObject);
begin
with Canvas do
begin
DPWAVE.Canvas.Draw(0,0,Art);{ <<<- Выведем его в веpхний левый угол формы }
end;
end;

end.

Кстати СУГУБО ТЕОРЕТИЧЕСКИЙ вопрос smile
раньше я очень мучился с палитрами...надо было считывать палитру с БМП.. устанавливать ее

теперь этот вопрос решен полностью?
т.е. можно его не затрагивать?
кто нибудь встречался с ломкой палитр при выводе БМП?

Автор: Illusion Dolphin 18.1.2005, 14:25
Всё равно выскажу своё IMHO smile... Буду пока выступать в качестве тестировщика STEPов.
Цитата

это снимет массу вопросов для начинающих

Цитата

ведь на форуме встречаются такие вопросы
Мерцание картинки
Не выводится по таймеру
Как сделать

А ты думаешь, что если будет создана статья, то новички её будут читать? По статистике поиском пользуется всё равно не более 10% начинающих как я думаю, а от "вечных" вопросов всё равно никуда не уйти... Но если всё же мы пишем статейку, то вот что я думаю о нулевом степе:
Цитата

создаем новую форму ведь куда то надо выводить графику

Когда я был "начинающий", смотрел бы я большими глазами на это и не понимал бы как это сделать и откуда взялось TDPWAVE и почему именно так... Если бы я увидел "родной" TForm1 - вопросов бы не было.
Цитата

Result := ((State[VK_ESCAPE] and 128) <> 0);

Зачем забивать голову ненужными функциями? Может OnKeyPress подойдёт событие простое? Это в первую очередь нужно комментировать - почему так а не иначе, а то для начинающих этот код "тяжеловат". Я бы его будучи "начинающим" скопировал, но суть бы не просёк.
Цитата

Пеpешем их на ассемблеpе.

эээ... а ты для кого пишешь? для начинающих? Может сразу на DirectDraw перейдём с ассемблерными вставками smile ?

P.S. Мне самому писать это бесполезно - доков я писать не умею, а пошагово работать просто не получится из-за склада характера...
P.P.S. Может стоит наконец-то зарегистрироваться на форуме smile ?

Ой.. уже сл. степ готов..
Цитата

кто нибудь встречался с ломкой палитр при выводе БМП?

"Стараюсь делать так:
Код

MyBitmap.PixelFormat:=pf24bit; //после этого проблем никогда не было

Автор: Штабс 18.1.2005, 14:56
Illusion Dolphin Добрый день...а по русски Hi!

Критика? да ради бога
"В борьбе обретем мы счастье свое" Корейко(а точнее эссеры)

тем более если она правильная

и так самое главное...
ты считаешь что эта затея пустая? до новичков не дойдет...а для более опытных она НЕ нужна

если так то надо все это сворачивать к едрене матери smile

во всем остальном ты прав

"родной" TForm1 и TDPWAVE есть одно и тоже

OnKeyPress для начала даже лучше....
но со временем появляется желание отлавливать влево...вправо...вверх...вних...пробел...
с этим тоже согласись...

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



Автор: Illusion Dolphin 18.1.2005, 15:32
Цитата

если так то надо все это сворачивать к едрене матери

Не надо уж так расстраиваться! Просто если уж тему развивать, то нужно написать полонстью готовый проект, желательно отформатированым в html и поговорить с vit'ом - он пишет FAQ большой, там эта статья возможно понадобится, но тут в форуме она в любом случае утонет. Если с ним поговоришь и статья окажется в FAQ, то тогда она реально может помочь людям, т.к. тут на форуме очень любят отсылать к этому FAQ (и очень правильно делают smile )

Автор: Guest 18.1.2005, 15:38
Illusion Dolphin
ОК
давай пока на этом и остановимся
за мной регистрация ...вообще то наверно надо
пообщаться с Vit ом

ну а за тобой тестация по шагам
тогда пока сворачиваем тему

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