Компонент Image находится на странице Дополнительно библиотеки компонентов. Он имеет свойство Canvas (канва, холст), представляющее собой область компонента, на которой можно рисовать или отображать готовые изображения. Канва содержит свойства и методы, существенно упрощающие графику C++Builder.
Каждая точка канвы имеет координаты X и Y. Система координат канвы, как и везде в C++Builder, имеет началом левый верхний угол канвы. Координата X возрастает при перемещении слева направо, а координата Y − при перемещении сверху вниз.
Координаты измеряются в пикселах. Пиксел − это наименьший элемент поверхности рисунка, с которым можно манипулировать. Важнейшее свойство пиксела − его цвет. Для описания цвета используется тип TColor. В C++Builder определено множество констант типа TColor. Одни из них непосредственно определяют цвета (например, clBlue − синий), другие определяют цвета элементов окон, которые могут меняться в зависимости от выбранной пользователем палитры цветов Windows (например, clBtnFace − цвет поверхности кнопок).
Рисование по пикселам
Для рисования по пикселам используется свойство канвы Pixels. Это свойство представляет собой двумерный массив Canvas->Pixels[int X][int Y], который отвечает за цвета канвы. Например, Canvas->Pixels[10][20] соответствует цвету пиксела, 10-го слева и 20-го сверху. С массивом пикселов можно обращаться как с любым свойством: изменять цвет, задавая пикселу новое значение, или определять его цвет по хранящемуся в нем значению. Например, Canvas->Pixels[10][20]=clBlack − это задание пикселу черного цвета.
Предположим, нужно нарисовать график некоторой функции F(X) на канве компонента Image1, если известен диапазон ее изменения Ymax и Ymin и диапазон изменения аргумента Xmin и Xmax. Это можно сделать так:
float X,Y; // координаты функции
int PX,PY; // координаты пикселов
for(PX=0;PX<=Image1->Width;PX++)
{
// X - координата, соответствующая пикселу с координатой PX
X=Xmin+PX*(Xmax-Xmin)/Image1->Width;
Y=F(X);
// PY - координата пиксела, соответствующая координате Y
PY=Image1->Height-(Y-Ymin)* Image1->Height/(Ymax-Ymin);
// Устанавливается красный цвет выбранного пиксела
Image1->Canvas->Pixels[PX][PY]=clRed;
}
Цикл выполняется по всем значениям горизонтальной координаты пикселов PX компонента Image1. Сначала выбранное значение PX пересчитывается в соответствующее значение X. Затем производится вызов функции и определяется ее значение Y. Это значение пересчитывается в вертикальную координату пиксела PY. И в заключение цвет пиксела с координатами (PX, PY) устанавливается красным.
Ниже приведено приложение для функции sin(X), для которой Xmin =0, Xmax =4
(2 периода), Ymin =-1 и Ymax =1.
Рисование пером
У канвы есть свойство − Pen − перо. Это объект, в свою очередь имеющий ряд свойств. Одно из них Color − цвет, которым наносится рисунок. Второе свойство − Width (ширина линии). Ширина задается в пикселах. По умолчанию ширина равна 1.
Свойство Style определяет вид линии и может принимать следующие значения:
| psSolid | Сплошная линия |
| psDash | Штриховая линия |
| psDot | Пунктирная линия |
| psDashDot | Штрих-пунктирная линия |
| psDashDotDot | Линия, чередующая штрих и два пунктира |
| psClear | Отсутствие линии |
| psInsideFrame | Сплошная линия, но при Width>1 допускающая цвета, отличные от палитры Windows |
Все стили со штрихами и пунктирами доступны только при Width =1. В противном случае линии этих стилей рисуются как сплошные.
Стиль psInsideFrame − единственный, который допускает произвольные цвета. Цвет линии при остальных стилях округляется до ближайшего из палитры Windows.
У канвы имеется свойство PenPos. Это свойство определяет в координатах канвы текущую позицию пера. Перемещение пера без прорисовки линии, т.е. изменение PenPos, производится методом канвы MoveTo(X,Y). Здесь (X,Y) − координаты точки, в которую перемещается перо. Эта текущая точка становится исходной, от которой методом LineTo(X,Y) можно провести линию в точку с координатами (X,Y). При этом текущая точка перемещается в конечную точку линии, и новый вызов LineTo будет проводить линию из этой новой текущей точки.
Нарисуем по пикселам и пером графики синуса и сравним качество графиков.
1. Создайте для проекта приложения каталог (папку Windows), запустите C++Builder 6, создайте новый проект, назовите форму ДЕМОНСТРАЦИЯ КОМПОНЕНТА IMAGE и командой Сохранить все сохраните файл модуля и проект под разными именами.
2. На пустую форму перенесите два компонента Image и разместите их по горизонтали рядом. Размеры обоих компонентов сделайте абсолютно одинаковыми, так как на этом для экономии размера кода основана программа. Сделать размеры компонентов абсолютно одинаковыми можно, выделив их оба и воспользовавшись командой всплывающего меню Size.
3. Над первым, левым компонентом поместите первую метку Label1 и назовите ее рисунок по пикселам, над вторым − Label2, с названием рисунок пером.
4. В правом верхнем углу поместите кнопку Button1 и назовите ее КОНЕЦ. В обработчик щелчка кнопки впишите Close();.
5. Под компонентами поместите вторую кнопку Button2, назовите ее НАРИСОВАТЬ, а в обработчик щелчка впишите:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
#define Pi 3.14159
float X,Y; // координаты функции
int PX,PY; // координаты пикселов
// Переводится перо в начало координат второго графика -
// на левый край канвы в середину ее высоты
Image2->Canvas->MoveTo(0,Image2->Height/2);
// Устанавливается красный цвет рисования пером
Image2->Canvas->Pen->Color=clRed;
// Устанавливается ширина линии рисования в три пиксела
Image2->Canvas->Pen->Width=3;
for(PX=0;PX<=Image1->Width;PX++)
{
// X - координата, соответствующая пикселу с координатой PX
X=PX*4*Pi/Image1->Width;
Y=sin(X);
// PY - координата пиксела, соответствующая координате Y
PY=Image1->Height-(Y+1)* Image1->Height/2;
// Устанавливается красный цвет выбранного пиксела
Image1->Canvas->Pixels[PX][PY]=clRed;
// Проводится линия на втором графике
Image2->Canvas->LineTo(PX,PY);
}
}
6. В заголовочный файл модуля впишите #include <math.h>. Сохраните проект и запустите на выполнение. Нетрудно видеть, что качество графиков сильно различается. В левом на крутых участках сплошной линии нет − она распадается на отдельные точки − пикселы. А правый график весь сплошной. Это показывает, что при прочих равных условиях рисовать лучше не по пикселам, а пером.
Отметим еще одно ценное свойство компонента Image и его канвы − можно задавать координаты пикселов, выходящие за пределы размеров канвы. Это позволяет не заботиться о том, какая часть рисунка попадает в рамку Image, а какая нет. Например, соответствующий оператор изменим так: Y=2*sin(X);. Сохраним проект и выполним. Увидим, что изобразилась только та часть рисунка, которая помещается в рамку канвы. Это позволяет без затруднений осуществлять приложения, в которых пользователю предоставляется возможность увеличивать и просматривать в деталях какие-то фрагменты графиков.
Контрольные вопросы
1. Расскажите о назначении и свойствах компонента Chart.






