Мігаценне, якое можна было назіраць у прыкладзе 17.6 узнікае з прычыны таго, што малюнак даводзіцца перамалёваць на форме пры кожным спрацоўванні таймера. Чым больш будуць памеры аб'екта, які рухаецца, тым мацней будзе мігаценне. Выкарыстанне ўласцівасцей формы AlphaBlend і DoubleBuffered не заўсёды дае вынік.
Для арганізацыі анімацыі руху можна выкарыстоўваць бітавыя вобразы, якія былі разгледжаны ў §14. Для вываду бітавага вобраза на Image можна выкарыстоўваць розныя метады (прыклад 17.7). Выкарыстанне метаду Draw было разгледжана ў §14. Для прымянення іншых метадаў неабходна вылучаць на малюнку прамавугольную вобласць.
Пераменныя Pr1 і Pr2 з табліцы прыкладу 17.7 апісаны тыпам TRect. Тып TRect — гэта структура з 4 палямі (Left, Top, Right, Bottom), якая выкарыстоўваецца для захоўвання верхняй левай і ніжняй правай вяршынь прамавугольніка. Задаваць значэнні можна непасрэдным прысвойваннем значэнняў або з дапамогай функцый Rect або Bounds (прыклад 17.8).
Прыклад 17.9. Змяніць праект з прыкладу 14.5 так, каб жывёл можна было маляваць у абраным маштабе.
Этапы выканання задання
- Змясціць на форму два кампаненты Image, кампаненты LabeledEdit, Button і дыялог OpenPictureDialog.
- Змяніць уласцівасці Caption у кампанента Button1 на «Выбрать».
- Устанавіць у кампанента Image2 значэнне true для ўласцівасці AutoSize (малюнак будзе загружацца ў рэальным памеры).
- Змяніць у кампанента LabeledEdit1 уласцівасць Caption на «Коэффициент масштабирования», уласцівасць Text — на 1,3.
- Апісаць як глабальныя пераменныя два бітавых вобраза: Ris1 — для захоўвання зыходнага малюнка, Ris2 — для захоўвання малюнка з улікам маштабу;
- Напісаць апрацоўшчык падзеі OnCreate для формы, у якім загрузіць з файла малюнак лесу ў кампанент Image1.
- Напісаць апрацоўшчык падзеі OnClick для кампанента Button1.
7.1. Загрузіць у бітавы вобраз Ris1 малюнак з абранага файла. 7.2. Вывесці яго ў Image2 метадам Assign.
- Напісаць апрацоўшчык падзеі OnMouseDown для кампанента Image1, у якім
8.1. Задаць прамавугольнік, даўжыні бакоў якога атрымліваюцца як даўжыні бакоў зыходнага малюнка, памножаныя на каэфіцыент маштабавання. 8.2. Задаць памеры Ris2 у адпаведнасці з маштабам. 8.3. Скапіраваць малюнак з Ris1 на Ris2, выкарыстоўваючы метад StretchDraw. 8.4. Метадам Draw вывесці малюнак на Image1.
Пры выкарыстанні метаду CopyRect можна капіраваць прамавугольную вобласць, якая знаходзіцца на адной канве, у прамавугольную вобласць, якая знаходзіцца на іншай канве (прыклад 17.10).
Калі памеры прамавугольнікаў супадаюць, то атрымліваем дакладную копію. Калі памер крыніцы менш або больш, то копія маштабуецца так, каб упісацца ў прамавугольнік (прыклад 17.11). Празрыстасць фону пры гэтым не падтрымліваецца.
Пры выкарыстанні метаду CopyRect малюнкі можна выводзіць, адбіўшы іх злева-направа або зверху-уніз. Для гэтага трэба замяніць значэнні палёў у структуры, якая апісвае прамавугольнік:
//зверху-ўніз Pr2 = Pr1; Pr2.bottom = Pr1.top;[1] Pr2.top = Pr1.bottom; //злева-направа Pr3 = Pr1; Pr3.left = Pr1.right; Pr3.right = Pr1.left;
Пры неабходнасці можна змяніць усе чатыры значэнні — у гэтым выпадку атрымаем люстэркавае адлюстраванне малюнка.
У прыкладзе 17.12. малюнкі капіраваліся з бітавага вобраза Pict1 ў бітавы вобраз Pict2 для таго, каб можна было затым вывесці малюнак з празрыстым фонам.
[1] Часам неабходна адабраць 1, паколькі пункт, які апісвае ніжні правы вугал, не належыць вобласці капіравання. З прычыны чаго, пры даданні празрыстасці, можа заставацца белая паласа таўшчынёй у 1 піксель.
|
Прыклад 17.7. Метады вываду бітавага ладу (Ris1):
Патрабаваны вынік
|
Метад
|
Капіраванне графікі
|
Draw(x, y, Ris1)
|
Капіраванне з маштабаваннем
|
StretchDraw(Pr1, Ris1)
|
Капіраванне прамавугольнага ўчастка канвы
|
CopyRect(Pr1, Ris -> Canvas, Pr2)
|
Поўнае капіраванне ўсіх уласцівасцей (у тым ліку і памераў)
|
Picture->Assign(Ris1)
|
Прыклад 17.8. Вызначэнне прамавугольнай вобласці:
TRect Pr1, Pr2, Pr3;
//Вызначэнне прамавугольнай //вобласці указаннем значэнняў палёў
Pr1.left = x1;
Pr1.top = y1;
Pr1.right = x2;
Pr1.bottom = y2;
//Вызначэнне прамавугольнай //вобласці па каардынатах
Pr2 = Rect(x1, y1, x2, y2);
//Вызначэнне прамавугольнай //вобласці шляхам задання
//верхняга левага вугла і
//даўжыні, шырыні прамавугольніка
Pr3 = Bounds(x1, y1, w, h);
|
Прыклад 17.9. Форма на этапе праектавання:

Апрацоўшчык падзеі OnCreate для формы.
void __fastcall TForm1:: FormCreate(TObject *Sender)
{
Image1 ->Picture -> LoadFromFile("лес.bmp");
OpenPictureDialog1 -> InitialDir =
ExtractFilePath(ParamStr(0));
}
|
Апрацоўшчык падзеі OnClick для кампанента Button1.
void __fastcall TForm1:: Button1Click(TObject *Sender)
{
if (OpenPictureDialog1 ->Execute()){
Ris1 -> LoadFromFile (OpenPictureDialog1 ->FileName);
Image2 -> Picture -> Assign(Ris1);
w = Ris1 -> Width;
h = Ris1 -> Height;
}
}
|
Апрацоўшчык падзеі OnMouseDown для кампанента Image1.
void __fastcall TForm1:: Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TRect Pr1; double k = StrToFloat (LabeledEdit1 -> Text); Pr1 = Bounds(0, 0, int(k * w), int(k * h)); Ris2 -> Width = int(k * w); Ris2 -> Height = int(k * h); Ris2 -> Canvas ->StretchDraw(Pr1, Ris1); Ris2 -> Transparent = true; Image1 -> Canvas -> Draw(X, Y, Ris2); }
|
Дадатак у час працы:

Прыклад 17.10. Фармат каманды CopyRect:

Прыклад 17.11. Выкарыстанне метаду CopyRect:

Прыклад 17.12. Капіраванне з адлюстраваннем:

Апрацоўшчык падзеі для кнопкі:
void __fastcall TForm1:: Button1Click(TObject *Sender)
{
TRect Pr1, Pr2, Pr3, Pr4;
Pr1 = Bounds(0, 0, w, h);
Image1 -> Canvas -> Draw(250, 200, Pict1);
//зверху-ўніз
Pr2 = Pr1;
Pr2.bottom = Pr1.top - 1;
Pr2.top = Pr1.bottom;
Pict2 -> Canvas -> CopyRect(Pr2,
Pict1 -> Canvas, Pr1);
Image1 -> Canvas -> Draw(50, 300, Pict2);
//злева-направа
Pr3 = Pr1;
Pr3.left = Pr1.right;
Pr3.right = Pr1.left;
Pict2 -> Canvas -> CopyRect(Pr3,
Pict1 -> Canvas, Pr1);
Image1 -> Canvas -> Draw(100, 200, Pict2);
//зверху-уніз, злева-направа
Pr4 = Pr1;
Pr4.left = Pr1.right;
Pr4.right = Pr1.left;
Pr4.top = Pr1.bottom;
Pr4.bottom = Pr1.top;
Pict2 -> Canvas -> CopyRect(Pr4,
Pict1 -> Canvas, Pr1);
Image1 -> Canvas -> Draw(350, 300, Pict2);
}
|
|