Работа с графикой стандартными средствами Visual Basic
Пожалуй следует начать с масштабов. Масштаб определяется свойством ScaleMode Реальное значение масштаба - пиксели (vbPixels). Каждый пиксель соответствуем реальной точке на экране. Но почему то по умолчанию в VB принят масштаб в твипах (vbTwips). Один пиксел соответствуем 15 твипам. Обрабатывать графику в таком масштабе неудобно, так как при рисовании 15 точек на экране реально появится только одна. Существуют также следующие масштабы
vbPoints -0,75 пикселя;
vbCharacters - содержит 120 твипов по горизонтали и 240 по вертикали;
vbInchs - 96 пикселей;
vbMillimeters и vbCentimeters соответственно 3,8 и 38 пикселей. Эти масштабы соответствуют реальному миллиметру и сантиметру при выводе изображения на принтер.
Также Вы можете определить свой масштаб. Произвольный масштаб задается свойствами ScaleLeft, ScaleTop, ScaleWidth, ScaleHeight или методом Scale. При изменении этих свойств свойство ScaleMode автоматически примет значение vbUser. Произвольный масштаб может быть удобен например для рисования графиков. Например, чтобы нарисовать синусоиду, можно ввести масштаб от -6.28 до 6.28 по оси x, от -1 до 1 по оси y:
Scale (-6.28, 1)-(6.28, -1)
Теперь рассмотрим методы вывода графики (все необязательные параметры помещены в скобки []):
Метод PSet [Step] (x, y), [color] рисует точку с заданными координатами.
Может использоваться следующим образом:
Pset (x, y), color - рисует точку с координатами x,y и цветом color.
PSet Step(x, y) - рисует точку, расположенную от предыдущей на расстояние x по горизонтали и y по вертикали. Например
Pset (10, 10) ' рисуем точку с координатами 10, 10;
Pset Step (20, 10) ' рисуем точку с координатами 30, 20
' т.е. отстоящую от предыдущей нарисованной точки на расстояние 20, 10.
Метод Line [Step] (x1, y1) [Step] (x2, y2), [color], [B][F] рисует линию или прямоугольник с заданными координатами
Может использоваться следующим образом:
Line (x1, y1) - (x2, y2), color - рисует линию, с координатами вершин (x1, y1) и (x2, y2) и цветом color;
Line Step (x1, y1) - (x2,y2) - рисует линию, где x1, y1 - расстояние от предыдущей точки;
Line (x1, y1) - Step (x2, y2) - рисует линию из точки (x1, y1) в точку, отстоящую от нее на расстояние x2, y2;
Line - (x, y) - рисует линию из предыдущей точки в точку с координатами (x, y);
Line (x1, y1) - (x2, y2), , B - рисует прямоугольник;
Line (x1, y1) - (x2, y2), , BF - рисует прямоугольник закрашенный цветом линий. Например
Line (10, 10) - (20, 20) ' рисуем линию из точки (10, 10) в точку (20, 20)
Line Step (10, 20) - (40, 50) ' рисуем линию из точки (30, 40) в точку (40, 50)
Line (50, 50) - Step (20, 30) ' рисуем линию из точки (50, 50) в точку (70, 80)
Line (90, 90) ' рисуем линию из точки (70, 80) в точку (90, 90)
Метод Circle [Step] (x, y), radius, [color, start, end, aspect] рисует окружность, дугу или эллипс
x, y - координаты центра;
radius - радиус окружности;
color - цвет окружности;
start, end - начало и конец дуги в радианах (по умолчанию start=0, end=6.28);
aspect определяет степень сжатия эллипса. По умолчанию aspect=1. Если aspect>1, эллипс будет вытянут по вертикали, если aspect<1 - по горизонтали. При этом максимальный диаметр эллипса будет равен 2*radius. Например
Circle (20, 20), 10 ' рисуем окружность с координатами центра (20, 20) _
' и радиусом 10
pi=3.14
Circle (20, 20), 10, , pi/2, 3*pi/2 ' рисуем дугу от угла 90 градусов _
' до 270 градусов
Circle (20, 20), 10, , , , 2 ' рисуем эллипс с высотой 10 и шириной 5
Для вывода текста существует метод Print. Положение текста определяется свойствами CurrentX и CurrentY. Например
CurrentX = 10
CurrentY = 10
Print "text" ' Печатаем текст левый верхний угол которого соответствует _
' координатам (10, 10)
Теперь рассмотрим цвета. Цвет состоит из трех составляющих - красная, зеленая и синяя. Каждая составляющая может изменяться от 0 до 255. Цвет кодируется следующим образом
red + 256*green + 65536*blue
Эту запись позволяет упростить функция RGB(red, green, blue).
Например желтый цвет=RGB(255, 255, 0).
В идеальном случае можно вывести 256^3=16777216 цветов (24 бита). В реальном случае количество цветов зависит от экранных настроек.
Помимо этой функции есть функция QBColor(color), где color = 0-15, которая возвращает 16 наиболее часто используемых цветов.
Также цвет можно задать предопределенными константами (vbBlack, vbRed, vbGreen, vbYellow, vbBlue, vbMagenta, vbCyan, vbWhite).
Разложить цвет на составляющие можно следующим образом:
Red = Color And 255
Green = Color \ 256 And 255
Blue = Color \ 65536 And 255
Помимо обычных цветов существуют системные цвета т.е. цвета, установленные по умолчанию системой для кнопок, текстовых полей и т.д. Чтобы не спутать эти цвета с обычными они кодируются отрицательными числами. Чтобы получить коды этих цветов используйте предопределенные константы (например vbButtonFace).
Чтобы получить цвет точки используйте функцию Point(x, y).
Цвет фона графического окна определяется свойством BackColor. Цвет линий - свойством ForeColor. Цвет, заданный этим свойством является по умолчанию для графических методов. Например
ForeColor = vbBlue
Line (10, 10) - (20, 10), vbRed ' рисуем красную линию
Line (20, 10) - (20, 20) ' рисуем синюю линию
Толщина линий определяется свойством DrawWidth.
В VB5 есть одна ошибка - если DrawWidth = 1, то метод Pset, если в нем не задать цвет, выведет точку черным цветом независимо от свойства ForeColor.
Свойство DrawStyle определяет тип линии. Например vbDot - пунктирная.
Свойство DrawMode определяет способ наложения линии на картинку. Например vbMaskPen соответствует And, vbInvert - Xor. По умолчанию это свойство равно vbCopyPen т.е. линия рисуется в том виде, в каком она есть. Рассмотрим 2 примера:
Пример 1:
Скопируйте код. Запустите программу. Щелкните мышкой по форме и не отпуская кнопки мыши перемещайте ее по форме.
Dim x0 As Single, y0 As Single, DrawFirst As Boolean
Private Sub Form_Load()
DrawMode = vbInvert
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
x0 = X
y0 = Y
DrawFirst = True
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
' Если кнопка не нажата, то выходим из процедуры
If Button = 0 Then Exit Sub
' Если линия уже была нарисована, то стираем ее
If DrawFirst = False Then
Line (x0, y0)-(CurrentX, CurrentY), , B
End If
' Рисуем новую линию
Line (x0, y0)-(X, Y), , B
DrawFirst = False
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If DrawFirst = False Then
Line (x0, y0)-(CurrentX, CurrentY), , B
End If
End Sub
Пример 2.
Private Sub Form_Load()
DrawMode = vbMaskPen
BackColor = vbBlack
ForeColor = vbWhite
ScaleMode = vbPixels
AutoRedraw = True
FontSize = 100
' Печатаем белый текст на черном фоне
Print "Text"
Dim i As Integer
' Выводим линии произвольным цветом
For i = 0 To ScaleHeight - 1
Line (0, i)-(ScaleWidth - 1, i), QBColor(Int(Rnd * 15) + 1)
Next
End Sub
Теперь рассмотрим заливку. Тип и цвет заливки определяются свойствами FillStyle и FillColor. По умолчанию Fillstyle = 1 и заливки нет. Если FillStyle = 0, то фигура закрашивается полностью цветом FillColor. Например
' Рисуем закрашенный красным цветом прямоугольник
FillStyle = 0
FillColor = vbRed
Line (10, 10) - (100, 50), , B
' Рисуем заштрихованный прямоугольник
FillStyle = 5
Line (10, 60) - (100, 100), , B
Свойство AutoRedraw определяет будет ли сохраняться изображение при перерисовке. Если AutoRedraw = False, и в графическом окошке что-то нарисовано, то когда это окошко скроется из видимости (например на какое-то время над ним появится другая форма или когда свойство Visible = False), то изображение стирается. При AutoRedraw = True изображение остается в любом случае, но скорость работы с графикой снижается. При этом изображение вначале обрабатывается в памяти, а затем выводится на экран. Например поместите на форму кнопку и введите следующий код:
Private Sub Command1_Click()
For X = 0 To ScaleWidth
For Y = 0 To ScaleHeight
Form1.PSet (X, Y)
Next
Next
End Sub
Если AutoRedraw = False, то Вы увидите, как постепенно заполняется экран точками. Если AutoRedraw = True, то после некоторой паузы компьютер выведет готовый результат.
Свойства Picture и Image
Свойство Picture определяет картинку, помещенную в графическое окно. Например картинку, загруженную из файла. Оно содержит информацию о ее размере, палитре, формате (bmp, jpeg, gif). Свойство Image определяет изображение графического окна. т.е. все, что нарисовано в графическом окне. Все графические функции работают именно с изображением, а Picture остается неизменным. Например
' Рисуем линию
Line (10, 10)-(20, 20)
' Присваиваем свойству Picture изображение формы
Picture = Image
' Рисуем окружность
Circle (100, 100), 50
' Очищаем картинку
Cls
В данном примере до очистки картинки в Picture хранилась одна линия, а в Image - линия с окружностью. После очистки нетронутым осталась одна линия так как она храниться в Picture, а окружность стерлась.
Теперь давайте рассмотрим как перенести изображение из одного графического окошка в другое. За основу возьмем предыдущий пример:
' Рисуем линию
Picture1.Line (10, 10)-(20, 20)
' Присваиваем свойству Picture изображение окошка
Picture1.Picture = Picture1.Image
' Рисуем окружность
Picture1.Circle (100, 100), 50
Picture2.Picture = Picture1.Picture ' В этом случае второе графическое окошко
' будет содержать только линию
Picture2.Picture = Picture1.Image ' В этом случае окошко будет содержать
' линию с окружностью
Теперь рассмотрим метод PaintPicture. Этот метод позволяет копировать с выбранным масштабом изображение с одного графического окошка на другое.
PaintPicture picture, x1, y1, [width1], [height1], [x2], [y2], [width2], [height2], [opcode]
Picture - картинка, которую мы копируем;
x1, y1 - левый верхний угол картинки на окошке-приемнике;
width1, height1 - размеры картинки на окошке-приемнике;
x2, y2 - левый верхний угол картинки на окошке-источнике;
width2, height2 - размеры картинки на окошке-источнике;
opcode определяет способ копирования (например просто копирование vbSrcCopy; побитовое умножение vbSrcAnd; побитовое сложение vbSrcPaint)
Если размеры width1 и width2 или height1 и height2 отличаются, то размер картинки изменяется
Пример:
' Копируем изображение с Picture2 на Picture1
Picture1.PaintPicture Picture2.Image, 0, 0
' Копируем часть картинки с Picture2 на Picture1, увеличив ее размер в 2 раза
Picture1.PaintPicture Picture2.Image, 0, 0, 20, 20, 0, 0, 10, 10
' Отображаем картинку по горизонтали
With Picture1
.PaintPicture Picture1.Picture, .ScaleWidth - 1, 0, _
-.ScaleWidth, .ScaleHeight, 0, 0, .ScaleWidth, .ScaleHeight
End With
Ну и наконец открытие, сохранение картинки и работа с буфером
Записываем картинку в файл
SavePicture Picture1.Image, "c:\test.bmp"
Считываем картинку из файла
Picture1.Picture = LoadPicture("c:\test.bmp")
Записываем картинку в буфер
Clipboard.Clear
Clipboard.SetData Picture1.Image
Считываем картинку из буфера
Picture1.Picture = Clipboard.GetData