Visual Basic 6. Руководство разработчика

       

Функции вывода пикселей


В большинстве случаев можно не беспокоиться о быстродействии приложений, в которых выводится всего несколько линий (даже если этот процесс занимает пару миллисекунд), за исключением, быть может, отдельных случаев, связанных с выводом сложных с математической точки зрения кривых. Но даже тогда, вероятно, нет смысла возиться с использованием API-функций. Если вспомнить о приложении Image (см. гл. 7), в котором в процессе обработки изображения необходимо было устанавливать значения цвета примерно для миллиона пикселей, то там все выглядит иначе: каждая лишняя миллисекунда, затраченная на обработку одного пикселя, будет приводить к значительной задержке всего цикла в целом. В гл. 12 рассматри­вались функции GetPixelV() и SetPixelV(), которые работают значительно быстрее, чем их аналоги в Visual Basic (методы Point и PSet соответственно) для чтения и установки значения пикселя.

Функция GetPixelV() возвращает значения пикселя в координатах (х, у) в контексте устройства, определенном параметром hdc, следующим образом.

Public Declare Function GetPixel Lib "gdi32" Alias "GetPixel" _

(ByVal hdc As Long, ByVal x As Long, ByVal y As Long) _

As Long

Значение пикселя возвращается как тип Long так же, как это сделал бы метод Point. Первый параметр функции GetPixel() - значение свойства hDC формы, элемента управления PictureBox или любого другого элемента управления, в который можно осуществить вывод графики.

Объявим функцию SetPixel().

Public Declare Function SetPixel Lib "gdi32" Alias "SetPixel" _

(ByVal hdc As Long, ByVal x As Long, ByVal у As Long, _

ByVal crColor As Long) As Long

Здесь

hdc - дескриптор контекста устройства управления, x и у - координаты пикселя, а crColor — его цвет.

На рис 13.12 приведено окно приложения CopyPix, которое выполняет копиро­вание пикселей из левого PictureBox в правый с помощью программы, исполь­зующей операторы Visual Basic (кнопка Сору VB), или API-функции GetPixelV() и SetPixelV() (кнопка Сору API). Запустите приложение, чтобы увидеть, насколько быстрее работают API-функции по сравнению с их эквивалентами в Visual Basic. При этом можно не засекать время, требуемое для выполнения этих операций — разница будет заметна даже "на глаз". Не забудьте, что значение свойства AutoRedraw второго элемента PictureBox должно иметь значение False, чтобы можно было заметить разницу в скорости выполнения операций копирования.




Проект CopyPix необходимо запускать на системе, способной отображать более 256 цветов. Если система поддерживает только 256 цветов, необходимо удостове­риться, что цвет, выбранный для заливки области, является цветом из палитры, а не псевдоцветом. Если цвет является псевдоцветом, то область будет заполнена с помощью шаблона, состоящего из точек разного цвета. Если снова попытаться залить эту же область, то программа выполнит заливку только одного пикселя, поскольку функция ExtFloodFill() позволяет выполнить заливку области, имеющей сплошной цвет, а не псевдоцвет.



Рис. 13.12. В проекте CopyPix демонстрируется различие в быстродействии между методами Visual Basic и эквивалентными API-функциями

Текст программы настолько прост, что здесь приводится только фрагмент, обслуживающий кнопку Copy API. В программе выполняется просмотр каждого пикселя исходного (левого) изображения (с помощью двойного цикла), считывается

значение цвета пикселя, а затем это значение присваивается пикселю с теми же координатами в правом PictureBox. Фрагмент программы приведен ниже.

Программа 13.14.

Копирование пикселей с помощью API-функций

Private Sub Conmiand2_Click ()

Dim i As Integer, 3 As Integer

Dim cIrValue As Long

For i = 0 To Picturel.ScaleWidth - 1

For j = 0 To Picturel.ScaleHeight - 1

   SetPixel Picture2.hdc, i, ~j, GetPixel(Picturel.hdc, i, j)

Next

' DoEvents

Next

End Sub

Чтобы копировать изображение из окна одного элемента управления в другое, можно использовать либо метод PaintPicture, либо API-функцию BitBlt(). Они работают одинаково быстро. Если же возникает необходимость обработать отдельные пиксели, то использование двух API-функций, рассмотренных ранее, позволит значительно ускорить процесс обработки. В гл. 12 рассматривалось использование соответствующих функций для оптимизации быстродействия приложения Image, в котором большая часть времени уходила на чтение и установку значений пикселей.


Содержание раздела