Russian Belarusian English German Japanese Ukrainian

Графика

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

Brush - кисть

У канвы имеется свойство Brush - кисть. Это свойство определяет фон и заполнение замкнутых фигур на канве. Brush - это объект, имеющий в свою очередь ряд свойств. Свойство Color определяет цвет заполнения. Свойство Style определяет шаблон заполнения (Штриховку).
 
Свойство Bitmap, являющееся указателем на объект типа TBitmap и определяющее нестандартное заполнение заданным шаблоном. Шаблон задается битовой матрицей размером 8x8. Если для кисти задан шаблон Bitmap, то заполнение производится именно этим шаблоном, независимо от значения свойства Style.
 
Шаблон Bitmap может создаваться в процессе выполнения приложения или, например, загружаться из файла, как в приведенном ниже примере, в котором фон формы заполняется загруженным шаблоном:
Graphics::TBitmap *BrushBmp = new Graphics::TBitmap;
try
(
BrushBmp->LoadFromFile("MyBitmap.bmp");
Form1->Canvas->Brush->Bitmap = BrushBmp;
Form1->Canvas->FillRect(Rect(0,0,Form1->Width,Form1->Height));
)
__finally
(
Form1->Canvas->Brush->Bitmap = NULL;
delete BrushBmp;
)
В этом примере создается объект BrushBmp типа TBitmap и в него загружается битовая матрица из файла с именем MyBitmap.bmp. Затем свойству Form1->Canvas->Brush->Bitmap присваивается указатель на этот объект. После этого загруженный шаблон можно использовать для заполнения фигур на канве формы. Метод FillRect рисует на канве заполненный шаблоном прямоугольник, занимающий всю площадь формы. Если подобный код вставить в обработчик события формы OnResize, то и при изменении пользователем размеров формы ее поверхность будет вся заполнена шаблоном. После этого (а также в случае генерации каких-то исключений) Bitmap присваивается значение NULL, после чего заполнение опять начинает определяться свойством Style. Затем объект BrushBmp уничтожается, чтобы освободить занимаемую им память.
 
Метод канвы FillReet заполняет заданным стилем или шаблоном прямоугольную область, заданную параметром Rect. Этот параметр имеет тип TRect. Для его задания проще всего использовать функцию Rect(X1,Y1,X2,Y2), возвращающую структуру Rect с координатами углов, заданных параметрами (X1, Y1) и (X2, Y2).
 
Функцию FillReet удобно, в частности, использовать для стирания изображения.
Например, оператор очищает всю площадь канвы компонента Image1:
Image1->Canvas->FillRect(Rect(0,0, Image1->Width,Image1->Height));
Кисть участвует в заполнении фигур не только с помощью этой функции. Все методы рисования замкнутых фигур тоже заполняют их с помощью кисти. Это относится к методам Chord, Ellipse, Pie, Polygon и др.
 
Имеется еще один интересный метод, работающий с кистью. Это метод FloodFill, который заполняет замкнутую область на канве. Точка с координатами X и Y является произвольной внутренней точкой заполняемой области, которая может иметь произвольную форму. Граница этой области определяется сочетанием параметров Color и FillStyle. Параметр Color указывает цвет, который используется при определении границы заполняемой области, а параметр FillStyle определяет, как именно по этому цвету определяется граница. Параметр FillStyle может принимать одно из двух следующих значений: fsSurface или fsBorder. Если FillStyle = fsSurface, то заполняется область, окрашенная цветом Color, а на других цветах метод останавливается. Если FillStyle = fsBorder, то наоборот, заполняется область окрашенная любыми цветами, не равными Color, а на цвете Color метод останавливается.
 
Для определения области закрашивания можно использовать координаты и цвет одного из пикселов, расположенных внутри области (если FillStyle = fsSurface) или снаружи ее (если FillStyle = fsBorder).
Имеется еще один метод канвы, связанный с кистью. Это метод FrameRect. Он рисует на канве текущей кистью прямоугольную рамку, не закрашивая ее.
 
Параметр Rect определяет позицию и размеры прямоугольной рамки. Толщина рамки 1 пиксел. Область внутри рамки кистью не заполняется. Метод FrameRect отличается от метода Rectangle тем, что рамка рисуется цветом кисти (в методе Rectangle - цветом пера) и область не закрашивается (в методе Rectangle закрашивается).

Image Editor - редактор изображений

В C++Builder имеется встроенный Редактор изображений - Image Editor, который вызывается командой Tools | Image Editor. Это сравнительно простой редактор с не очень богатыми возможностями. Он позволяет создавать изображения в виде битовых матриц, пиктограмм, изображений курсоров и не только сохранять созданные изображения в виде файлов, но и сразу включать их в файл ресурсов приложения. В этом и заключается его основное отличие от других, более мощных графических редакторов.
 
Работа начинается с меню File, в котором можно выбрать раздел Open - открыть новый файл изображения или ресурсов, или раздел New - создать новый файл. Если вы выбрали New, то вам предлагается сделать дополнительный выбор, определяющий вид файла, который вы хотите создать:
Значение Описание
Resource File (.res) файл ресурсов.
Component Resource File (.dcr) файл ресурсов компонента.
Bitmap File (.bmp) файл битовой матрицы.
Icon File (.ico) файл пиктограммы.
Cursor File (.cur) файл изображения курсора.
Пусть, например, вы хотите создать свой рисунок для битовой матрицы. Тогда, выбрав раздел Bitmap File, вы попадаете в окно, в котором должны выбрать размер (Size) матрицы по горизонтали (Width) и вертикали (Height), а также выбрать набор цветов: 2, 16 или 256. Вероятно, для начала вам будет вполне достаточно 16 цветов.
 
После сделанного выбора вы увидите в окне Редактора изображений границы вашего будущего рисунка. Раздел меню View предоставляет вам возможность увеличить изображение в 2 раза (раздел Zoom in), уменьшить ранее увеличенное изображение (раздел Zoom Out) или посмотреть изображение в его реальном размере (раздел Actual Size).
 
В нижней части Редактора изображений расположена палитра цветов. В ее левой части имеются два квадрата. Цвет левого из них - основной, используется, если при рисовании вы нажимаете левую кнопку мыши; цвет правого - вспомогательный, используется, если при рисовании вы нажимаете правую кнопку мыши.

TPicture, TBitmap, Tlcon и TMetafile - хранения графических объектов

Для хранения графических объектов, содержащихся в битовых матрицах, пиктограммах и метафайлах, в C++Builder определены соответствующие классы TBitmap, Tlcon и TMetafile. Все они являются производными от абстрактного базового класса графических объектов TGraphic. Кроме того, определен класс, являющийся надстройкой над TBitmap, Tlcon и TMetafile и способный хранить любой из этих объектов. TPicture имеет свойство Graphic, которое может содержать и битовые матрицы, и пиктограммы, и метафайлы. Более того, он может содержать и объекты определенных пользователем графических классов, производных от TGraphic. Для доступа к графическому объекту можно использовать свойство TPicture->Graphic, но если тип графического объекта известен, то можно непосредственно обращаться к свойствам TPicture->Bitmap, TPicture->Icon или TPicture->Metafile.
Для всех рассмотренных классов определены методы загрузки и сохранения в файл:
void __fastcall LoadFromFile(const System::AnsiString Filename);
void __fastcall SaveToFile(const System::AnsiString Filename);
При этом для классов TBitmap, Tlcon и TMetafile формат файла должен соответствовать классу объекта. Объект класса TPicture может оперировать с любым форматом.
 
Для всех рассмотренных классов определены методы присваивания значений объектов:
void __fastcall Assign(TPersistent* Source);
Однако для классов TBitmap, TIcon и TMetafile присваивать можно только значения однородных объектов: соответственно битовых матриц, пиктограмм, метафайлов. При попытке присвоить значения разнородных объектов генерируется исключение. Класс TPicture универсальный, ему можно присваивать значения объектов любых из остальных трех классов. А значение TPicture можно присваивать только тому объекту, тип которого совпадает с типом объекта, хранящегося в нем.
 
Если надо переписать в Bitmap отредактированное пользователем в Image1 изображение, это можно сделать следующим оператором (процедура MSaveClick):
Bitmap->Assign(Image1->Picture);
Если же надо восстановить в Image1 прежнее изображение, испорченное по каким-то причинам, то это можно сделать следующим оператором (процедура MRestoreClick):
Image1->Picture->Assign(Bitmap);

Канва и пикселы

Многие компоненты в C++Builder имеют свойство Canvas (канва, холст), представляющее собой область компонента, на которой можно рисовать или отображать готовые изображения. Это свойство имеют формы, графические компоненты Image, PaintBox, Bitmap и многие другие. Канва содержит свойства и методы, существенно упрощающие графику C++Builder. Все сложные взаимодействия с системой спрятаны для пользователя, так что рисовать в C++Builder может человек, совершенно не искушенный в машинной графике.
 
Каждая точка канвы имеет координаты X и Y. Система координат канвы, как и везде в C++Builder, имеет началом левый верхний угол канвы. Координата X возрастает при перемещении слева направо, а координата Y при перемещении сверху вниз.
 
Координаты измеряются в пикселах. Пиксель - это наименьший элемент поверхности рисунка, с которым можно манипулировать. Важнейшее свойство пиксела его цвет. Для описания цвета используется тип TCoIor. Одни из них непосредственно определяют цвета (например cIRed - красный), другие определяют цвета элементов окон, которые могут меняться в зависимости от выбранной пользователем палитры цветов Windows (например, clBtnFace - цвет поверхности кнопок).
 
Но для графики иногда этих предопределенных констант не хватает. Вам могут понадобиться такие оттенки, которых нет в стандартных палитрах. В этом случае можно задавать цвет 4-байтовым шестнадцатеричным числом, три младших разряда которого представляют собой интенсивности синего, зеленого и красного цвета соответственно. Например, значение $00FF0000 соответствует синему цвету, $0000FF00 зеленому, $000000FF красному, $00000000 черному, $00FFFFFF белому.

Основы работы с событием OnPaint

Все, что можно рисовать на канве с помощью компонента TImage, можно рисовать и на форме. Кроме того, имеется специальный компонент PaintBox, имеющий канву и позволяющий рисовать на ней. Рисование на PaintBox вместо формы не имеет никаких преимуществ, кроме может быть некоторого облегчения в расположении одного или нескольких рисунков в площади окна. При рисовании на канве формы или PaintBox надо учитывать некоторые особенности.
 
Откройте новое приложение, перенесите на него диалог OpenPictureDialog, кнопку и в обработчик щелчка на ней вставьте операторы:
if(OpenPictureDialog1->Execute()}
{
Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
try
{
Bitmap->LoadFromFile(OpenPictureDialog1->FileName);
Canvas->Draw(0,0,Bitmap);
}
__finally
{
Bitmap->Free();
}
}
Эти операторы обеспечивают загрузку выбранного пользователем графического файла и отображение изображения непосредственно на канве формы (поскольку оператор Canvas->Draw относится к канве формы, можно было бы это уточнить, написав Form1->Canvas->Draw). Запустите приложение, выберите файл. А теперь, не закрывая своего приложения, вернитесь в C++Builder и, ничего там не делая, опять перейдите в свое выполняющееся приложение. Если окно Редактора Кода, выступившее на первый план при вашем переходе в C++Builder, целиком перекрыло окно вашего приложения, то вернувшись в него вы увидите, что картинка в окне исчезла. Если же вы опять загрузите в него картинку и сдвинете окно приложения так, чтобы окно Редактора Кода не могло целиком его закрыть, то, повторив эксперимент с переходом в C++Builder и обратно вы, возможно, увидите уже иной результат.
 
Вы видите, что если окно какого-то другого приложения перекрывает на время окно вашего приложения, то изображение, нарисованное на канве формы, портится. В компоненте Image этого не происходило, поскольку в классе TImage уже предусмотрены все необходимые действия, осуществляющие перерисовку испорченного изображения. А при рисовании на канве формы или других оконных компонентов эти меры должен принимать сам разработчик приложения.
 
Если окно было перекрыто и изображение испортилось, операционная система сообщает приложению, что в окружении что-то изменилось и что приложение должно предпринять соответствующие действия. Как только требуется обновление окна, для него генерируется событие OnPaint. В обработчике этого события (в нашем случае события формы) нужно перерисовать изображение.
 
Перерисовка может производиться разными способами в зависимости от приложения. В нашем примере можно было бы вынести объявление указателя Bitmap за пределы приведенной выше процедуры, т.е. сделать эту переменную глобальной:
Graphics::TBitmap*Bitmap;
Тогда приведенная выше процедура загрузки файла сокращается на следующий код:
if(OpenPictureDialog1->Execute())
{
Bitmap = new Graphics::TBitmap;
Bitmap->LoadFromFile(OpenPictureDialog1->FileName);
Canvas->Draw(0,0,Bitmap);
}
Оператор Bitmap->Free(), содержавшийся ранее в этой процедуре, переносится в обработчик события формы OnDestroy. Тогда в течение всего времени выполнения вашего приложения вы будете иметь копию картинки в компоненте Bitmap и вам достаточно ввести в обработчик события OnPaint формы всего один оператор:
if(Bitmap != NULL)
Canvas->Draw(0,0,Bitmap);
Оператор if используется, чтобы избежать ошибочного обращения к Bitmap, пока графический файл еще не загружался и объект Bitmap не создан. Сделайте это, и увидите, что изображение на форме не портится при любых перекрытиях окон.
 
Сделанный вами обработчик перерисовывает все изображение, хотя, может быть, испорчена только часть его. При больших изображениях это может существенно замедлять перерисовку и вызывать неприятные зрительные эффекты. Перерисовку можно существенно ускорить, если перерисовывать только испорченную область канвы. У канвы есть свойство ClipRect типа TRect, которое в момент обработки события OnPaint указывает область, которая подлежит перерисовке. Поэтому более экономным будет обработчик:
if(Bitmap !- NULL)
Canvas->CopyRect(Canvas->ClipRect,Bitmap->Canvas,Canvas->ClipRect);
Он перерисовывает только область ClipRect, которая испорчена.

Приложение для просмотра графических файлов

Создаем приложение, в котором будет отображать выбранная вами в процессе проектирования картинка. Вы можете легко превратить его в более интересное приложение, в котором пользователь сможет просматривать и загружать любые графические файлы. Для этого достаточно перенести на форму компонент ОpenPictureDialog, расположенный в библиотеке на странице Dialogs и вызывающий диалоговое окно открытия и предварительного просмотра изображения, а также кнопку, запускающую просмотр или меню с единственным разделом Файл.
 
А теперь осталось только написать всего один оператор в обработчике щелчка на кнопке или на разделе меню:
if(OpenPictureDialog1->Execute())
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
Этот оператор загружает в свойство Picture компонента Image1 файл, выбранный в диалоге пользователем. Выполните свое приложение и проверьте его в работе. Щелкая на кнопке вы можете выбрать любой графический файл и загрузить его в компонент Image1.
 
В таком приложении есть один недостаток - изображения могут быть разных размеров и их положение на форме или будет несимметричным, или они не будут помещаться в окне. Это легко изменить, заставив форму автоматически настраиваться на размеры изображения. Для этого надо установить в компоненте Image1 свойство AutoSize равным true, а приведенный ранее оператор изменить следующим образом:
if(OpenPictureDialog1->Execute())
{
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
Form1->C1ientHeight = Image1->Height + 10;
Image1->Top = Form1->ClientRect.Top + (Form1->ClientHeight - Image1->Height)/2;
Form1->ClientWidth - Image1->Width + 10;
Image1->Left = Form1->ClientRect.Left + (Form1->ClientWidth - Image1->Width)/2;
}
В этом коде размеры клиентской области формы устанавливаются несколько больше размеров компонента Image1, которые в свою очередь адаптируются к размеру картинки благодаря свойству AutoSize.

Работа с файлами ресурсов

Допустим требуется включить картинку, пиктограмму или курсор в файл ресурсов какого-то проекта или компонента. Файлы ресурсов проектов имеют расширение .res и содержат битовые матрицы (.bmp), пиктограммы (.ico), изображения курсоров (.cur), используемые в проекте. Файлы ресурсов компонентов имеют расширение .dcr (dynamic component resource - динамические ресурсы компонента) и могут включать такие же элементы, как и файлы .res.
 
В некоторых случаях включение изображений в файл ресурса - единственная возможность решить ту или иную задачу. Например, если нужно ввести в приложение какой-то нестандартный курсор, это можно сделать, зарегистрировав его с помощью функции LoadCursor в свойстве Cursors компонента Screen. Однако для использования своего курсора надо сначала создать его и включить в ресурс приложения с помощью Редактора изображений. Другой пример - создание пиктограммы для нового компонента (не шаблона), включаемого вами в библиотеку C++Builder. Эта пиктограмма также должна быть создана не в виде отдельного файла, а как элемент ресурса компонента.
 
Работа с файлом ресурса приложения в Редакторе изображений обычно начинается командой File | Open, открывающей файл ресурсов приложения .res, в котором нужно что-то изменить. Перед вами открывается окно, содержащее структуру файла в виде дерева. Сначала в нем может быть только один узел - Icon, содержащий вершину MAINICON, соответствующую стандартной пиктограмме приложения. Добавить новые узлы можно с помощью команды Resource | New (ее можно найти и во всплывающем меню Редактора изображений), выполняя которую предоставляется возможность выбрать один из типов элементов: Bitmap, Cursor или Icon. Пусть, например, нужно использовать в своем приложении нестандартный курсор в виде человечка с указкой. После выполнения Resource | New | Cursor и в дереве структуры файла ресурсов приложения появляется новая вершина. Нужно задать ей то имя, которое в дальнейшем будете использовать в приложении при регистрации курсора функцией LoadCursor. Затем щелкнув на созданной вершине, откроется заготовка изображения курсора, в которой можно рисовать нужную картинку.
 
При рисовании курсора в главном меню Редактора изображений появляется раздел Cursor с двумя подразделами: Set Hot Cpot - указание горячей точки, и Test - тестирование. Горячая точка - это та точка изображения курсора, координатами которой являются параметры X и Y, передающиеся в обработчики событий мыши. При выборе раздела меню Set Hot Cpot открывается диалоговое окно, в котором нужно задать горизонтальную и вертикальную координаты горячей точки. Координаты задаются в пикселах, т.е. чтобы правильно указать координату надо посчитать, на сколько клеточек требуемая точка отстоит от левого верхнего угла рисунка.
 
После задания горячей точки можно выбрать раздел меню Cursor | Test. Перед вами откроется окно, в котором курсор приобретет нарисованный вами вид. Нажав кнопку мыши и передвинув курсор, можно увидеть, что за курсором тянется нарисованная линия. Можно видеть, из правильной ли точки курсора выходит эта линия, и при необходимости можете подкорректировать координаты горячей точки или само изображение курсора.
 
После завершения создания курсора, надо вернуться в окно структуры файла ресурса и выполнить команду File | Save. Несколько иначе, но подобным же образом создаются файлы ресурсов компонентов. Начинается работа с команды File | New | Component Resource File (.dcr). Затем, если нужно создать пиктограмму для регистрации вашего нового компонента в библиотеке, необходимо выполнить команду Resource | New | Bitmap и в открывшемся диалоговом окне задать размер картинки 24x24. Только такой размер воспримется при регистрации вашего компонента в библиотеке.
Затем нужно назвать соответствующую вершину в дереве структуры файла ресурсов тем же именем, которое имеет вводимый вами класс компонента. В противном случае C++Builder не воспримет это изображение как пиктограмму вашего компонента. В файл .dcr необходимо сохранить с именем, совпадающим с именем файла модуля, в котором создается компонент, и в том же самом каталоге, в котором хранится этот файл модуля. Только при соблюдении всех перечисленных выше условий ваше изображение будет воспринято C++Builder как пиктограмма компонента и она будет использована при установке компонента на странице библиотеки. А само создание изображения ничем не отличается от создания пиктограммы шаблона компонента.

Режимы копирования и рисования канвы

У канвы имеются методы копирования. Это прежде всего метод CopyRect, позволяющий копировать прямоугольную область источника изображения в прямоугольную область данной канвы. Метод определен следующим образом:
void __fastcall CopyRect(const Windows::TRect $Dest, TCanvas* Canvas, const Windows::TRect $Source);
Параметр Dest определяет прямоугольную область канвы, в которую производится копирование. Параметр Canvas указывает источник, из которого копируется изображение. Это может быть канва любого компонента: типа TImage, типа TBitmap и др. В частном случае источником может быть и канва того же компонента, в который производится копирование. Параметр Source определяет прямоугольную область в источнике изображения, которая копируется в область Dest. Обе прямоугольные области и в источнике, и в приемнике имеют тип TRect.
 
Копирование - это не просто перенос изображения. В общем случае копирование означает сложное взаимодействие копируемого изображения и того, которое было до этого в области, куда производится копирование. Характер этого взаимодействия определяется параметром CopyMode (режим копирования) той канвы, в которую производится копирование. По умолчанию значение CopyMode равно cmSrcCopy. Это единственный режим, при котором производится действительное копирование: изображение в Dest стирается и заменяется скопированным.
 
Есть два значения - cmWhiteness и cmBlackness, при которых собственно никакое копирование не производится: просто область закрашивается соответственно белым или черным цветом. А все остальные режимы определяют сложное взаимодействие копируемого изображения с тем, которое было в Dest. Особый интерес представляет режим cmSrcInvert, при котором изображения канвы и источника комбинируются, используя булеву операцию XOR. Так же, как для пера, повторное копирование в подобном режиме восстанавливает прежнее изображение на канве. Интересен также режим cmSrcAnd.
 
Если копируемое изображение представляет собой контурный черный рисунок на белом фоне, то этот рисунок наложится на прежнее изображение канвы, а белый фон будет прозрачным, так что под ним будет видно первоначальное изображение. В режиме cmSrcPaint аналогичный эффект будет, если копируемое изображение представляет собой белый контурный рисунок на черном фоне.
 
Еще один метод копирования - BrushCopy. Он сохраняется, как заявляют сами авторы C++Builder, только для совместимости с более ранними версиями системы. Помимо методов копирования свойство CopyMode используется также методом рисования на канве Draw.
 
Пример №1

Операторы обеспечивают копирование изображения фрагмента канвы компонента Image2 в указанную область канвы компонента Image1. Изображение, которое ранее было на канве компонента Image1 в пределах области с координатами углов (0, 0) и (200, 200), просто заменяется новым.
Image1->Canvas->CopyMode = cmSrcCopy;
Image1->Canvas->CopyRect(Rect(0,0,200,200),Image2->Canvas,Rect(0,0,200,200));
 
Пример №2

Операторы обеспечивают копирование изображения фрагмента канвы компонента Image2 в указанную область канвы компонента Image1 в режиме cmSrcInvert. После выполнения функции CopyRect в первый раз изображения в компонентах Image1 и Image2 налагаются друг на друга, а в результате выполнения функции CopyRect во второй раз исходное изображение на канве компонента Image1 восстанавливается.
Image1->Canvas->CopyMode = cmSrcInvert;
Image1->Canvas->CopyRect(Rect(0,0,200,200),Image2->Canvas,Rect(0,0,200,200));
Image1->Canvas->CopyRect(Rect(0,0,200,200),Image2->Canvas,Rect(0,0,200,200));
 
Пример №3

Операторы просто очищают указанную область канвы компонента Image1, закрашивая ее белым цветом. При этом изображение в компоненте Image2 никак не участвует в операциях копирования.
Image1->Canvas->CopyMode = cmWhiteness;
Image1->Canvas->CopyRect(Rect(0,0,200,200),Image2->Canvas,Rect(0,0,200,200));

Режимы пера

У пера Реn имеется свойство Mode (режим). По умолчанию значение Mode = pmCopy. Это означает, что линии проводятся цветом, заданным в свойстве Color. Но возможны и другие режимы, в которых учитывается не только цвет Color, но и цвет соответствующих пикселов фона. Наиболее интересным из этих режимов является режим pmNotXor - сложение с фоном по инверсному исключающему ИЛИ. Операция инверсного исключающего ИЛИ анализирует по битам два своих операнда. Результирующий бит равен 0, если соответствующие биты двух операндов не равны друг другу, а при равенстве битов операндов результирующий бит равен 1.
 
Вспомните, что каждый пиксел хранит цвет как набор битов. Пусть, например, фоновый пиксел имеет значение 0110011, а цвет пера установлен в 1111000. Применение, операции pmNotXor к этим двум числам даст цвет со значением 0110100. Этот цвет перо задаст данному пикселу. А теперь посмотрим, что получится, если перо повторно пройдет по тому же пикселу. В этом случае опять будет выполнена операция pmNotXor по отношению к цвету пера 1111000 и текущему цвету пиксела, который стал равен 0110100. Применение pmNotXor к этим числам даст в результате 0110011, т.е. первоначальный цвет пиксела.
 
Это значит, что если нарисовать на фоне какую-то фигуру один раз, а затем нарисовать ту же фигуру повторно, то нарисованная фигура исчезнет и каждый пиксел вернется к своему первоначальному цвету. Эту особенность режима pmNotXor, свойственную также режиму pmXor - сложение с фоном по исключающему ИЛИ, можно использовать для создания простенькой анимации. Достаточно нарисовать нечто, затем стереть нарисованное, перерисовать немного измененным и рисунок будет представляться ожившим.

Рисование по пикселям

Рисовать на канве можно разными способами. Первый вариант - рисование по пикселям. Для этого используется свойство канвы Pixels. Это свойство представляет собой двумерный массив Canvas->Pixels[int X][int Y], который отвечает за цвета канвы. Например, Canvas->Pixels[10][20] соответствует цвету пиксела, 10-го слева и 20-го сверху. С массивом пикселов можно обращаться как с любым свойством: изменять цвет, задавая пикселу новое значение или определять его цвет по хранящемуся в нем значению.
Например, делаем пиксел черного цвета:
Canvas->Pixels[10][20] = clBlack
Нарисуем график некоторой функции F(X) на канве компонента Image1, если известен диапазон ее изменения Ymax и Ymin и диапазон изменения аргумента Xmin и Xmах. Это можно сделать такой процедурой:
float X,Y; // координаты функции
int PX,PY; // координаты пикселов
for (PX = 0; PX <= Image1->Width; PX++)
{
//X - координата, соответствующая пикселу с координатой PX
X = Xmin + PX * (Xmах - Xmin) / Image1->Width;
Y = F (X);
//PY - координата пиксела, соответствующая координате Y
PY = Image1->Height - (Y - Ymin) * Image1->Height / (Ymax - Ymin);
//Устанавливается черный цвет выбранного пиксела
Image1->Canvas->Pixels[PX][PY] = clBlack;
}
В этом коде вводятся переменные X и Y, являющиеся значениями аргумента и функции, а также переменные PX и PY, являющиеся координатами пикселов, соответствующими X и Y. Сама процедура состоит из цикла по всем значениям горизонтальной координаты пикселов PX компонента Image1. Сначала выбранное значение PX пересчитывается в соответствующее значение X. Затем производится вызов функции и определяется ее значение Y. Это значение пересчитывается в вертикальную координату пиксела PY. И в заключение цвет пиксела с координатами (PX, PY) устанавливается черным.
  • 1
  • 2