Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Волченков Проектирование WИНДОWС-приложениы на языке ВИСУАЛ БАСИЦ 2015

.pdf
Скачиваний:
5
Добавлен:
12.11.2022
Размер:
2.37 Mб
Скачать

После старта приложения массив фамилий создаётся с помощью команды меню Генератор слов. Число элементов этого массива, равное числу элементов исходного списка, пользователь задаёт на этапе загрузки формы с помощью окна ввода.

После срабатывания команды Генератор слов она должна стать недоступной. Затем выполняется команда Сортировка. В данном случае элементы массива – это данные строкового типа, поэтому для его сортировки достаточно присвоить свойству Sorted окна списка с исходными данными значение True (Истина), а потом в цикле заполнить этот массив. Только после этого пользователь вносит интересующую его фамилию в поле поискового запроса и щёлкает команду Поиск.

Код 6.2 содержит процедуры для всех перечисленных этапов

работы данного приложения.

Код 6.2

Public Class Form1

Dim w, a() As String

Dim n, k, i, j, imin, imax, limit As Integer Dim d As Double

Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load

n = InputBox("Ведите число слов", _

"Объём массива", "100") ReDim a(n - 1)

РусскиеФамилии.Visible = False End Sub

Private Sub ГенераторСлов_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) _ Handles ГенераторСлов.Click

Randomize()

For i = 0 To n - 1

w = РусскиеФамилии.Items.Item(CInt(Rnd() * _ (РусскиеФамилии.Items.Count - 1)))

If Rnd() > 0.75 Then w = w & "а"

' Женщин будет только 25% ИсходныйСписок.Items.Add(w)

Next

ГенераторСлов.Enabled = False End Sub

81

Private Sub Сортировка_Click(ByVal sender _ As System.Object, _

ByVal e As System.EventArgs) _ Handles Сортировка.Click

ИсходныйСписок.Sorted = True For i = 0 To n - 1

a(i) = ИсходныйСписок.Items.Item(i)

Next End Sub

Private Sub Поиск_Click(ByVal _ sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Поиск.Click

ПротоколПоиска.Items.Clear() imin = 0 : imax = n + 1

i = n - 1 : k = 0 k = 0

limit = Math.Log(n) / Math.Log(2) + 1 Do Until k > limit

i = (imax + imin) \ 2 If i > n - 1 Then _

РезультатПоиска.Items.Add("Нет") : Exit Sub ПротоколПоиска.Items.Add(Format(k + 1, "00") _

& ":" & Format(i, "0000")) k = k + 1

If a(i) > ИскомыйЭлемент.Text Then imax = i

ElseIf a(i) < ИскомыйЭлемент.Text Then imin = i

Else

Exit Do End If

Loop

If k <= limit Then РезультатПоиска.Items.Add(Format(i, "0000") & _

":" & ИсходныйСписок.Items.Item(i))

Else

РезультатПоиска.Items.Add("Нет") End If

End Sub End Class

2. Можно вместо списка фамилий сгенерировать список дат – так, как было сделано в примере выполнения задания 6.1. Форма изменённого приложения будет выглядеть, как показано на рис. 6.3.

82

Рис. 6.3. Пример бинарного (быстрого) поиска заданной даты

Для перехода от фамилий к датам необходимо несколько откор-

ректировать начало процедуры для команды Поиск:

Код 6.3

Dim dx As Date

dx = CDate(ИскомыйЭлемент.Text)

ПротоколПоиска.Items.Clear() imin = 0 : imax = n + 1

i = n - 1 : k = 0 k = 0

limit = Math.Log(n) / Math.Log(2) + 1 Do Until k > limit

i = (imax + imin) \ 2 If i > n - 1 Then _

РезультатПоиска.Items.Add("Нет") : Exit Sub ПротоколПоиска.Items.Add(Format(k + 1, "00") & _

":" & Format(i, "0000"))

k = k + 1

If d(i) > dx Then imax = i

ElseIf d(i) < dx Then imin = i

Else

Exit Do End If

Loop

83

Варианты задания 6.2. Оба варианта данного задания предполагают, во-первых, отладку проекта задания 6.2 и, во-вторых, дополнение процедуры бинарного поиска дополнительной возможностью получения всех значений индекса для повторяющихся значений фамилии (или даты). С этой целью необходимо сделать «вставку» в код процедуры для команды меню Поиск.

Вариант 1. Найти все индексы (а не только один из индексов) для заданной фамилии – так, как показано на рис. 6.4.

Рис. 6.4. Пример бинарного поиска всех индексов для заданной фамилии

Вариант 2. Найти все индексы (а не только один из индексов) для заданной даты – так, как показано на рис. 6.5.

Рис. 6.5. Пример бинарного поиска всех индексов для заданной даты

84

Указание. Необходимо просмотреть элементы массива a(…) – фамилий, или массива d(…) – дат, которые предшествуют найденному элементу, и добавить их индексы в результат, если они совпадают с найденным элементом:

j = i - 1

If j < 0 Then Exit Sub Do While d(j) = dx

'или a(j) = ИскомыйЭлемент.Text

РезультатПоиска.Items.Add(Format(j, "0000") _ & ":" & ИсходныйСписок.Items.Item(j))

j = j - 1

If j < 0 Then Exit Sub Loop

Также необходимо просмотреть элементы массива a(…) – фамилий, или d(…) – дат, следующие за найденным элементом, и добавить их индексы в результат, если они совпадают с найденным элементом:

j = i + 1

If j >= n Then Exit Sub Do While d(j) = dx

'или a(j) = ИскомыйЭлемент.Text

РезультатПоиска.Items.Add(Format(j, "0000") _ & ":" & ИсходныйСписок.Items.Item(j))

j = j + 1

If j >= n Then Exit Sub Loop

Задание 6.3. Создать и отладить проект Windows приложения «Обработка изображения как двумерного массива пикселей».

Рассмотрим приложение, которое демонстрирует возможность использования двумерного динамического массива для хранения «точек» растрового изображения произвольного размера с целью его обработки. В данном приложении рассматриваются следующие виды обработки:

преобразование данного цветного изображения в чёрно-белое изображение;

получение негативного изображения;

построение изображения, симметричного данному изображению относительно вертикальной оси;

85

построение изображения, симметричного данному изображению относительно горизонтальной оси;

построение увеличенного изображения;

построение уменьшенного изображения.

Под «точкой» изображения в данном случае понимается цвет отдельного пикселя этого изображения с заданными координатами.

На рис. 6.6 показано окно данного приложения после построения негативного изображения.

Идея проектирования данного приложения заключается в следующем. На языке Visual Basic .NET (2005, 2008) можно создать и

использовать особый виртуальный графический объект, например, с именем Page1, который является «bmp-копией» файла произвольного графического формата. Вместо графического файла можно

воспользоваться значением свойства Image объекта класса

PictureBox:

Dim Page1 As Bitmap

Page1 = New Bitmap(PictureBox1.Image)

Рис. 6.6. Окно приложения в процессе работы – после построения негативного изображения и рисования результата

С помощью двойного цикла и метода GetPixel языка VB .NET данный объект может быть «отсканирован» – цвет каждого его

86

пикселя с координатами (x, y) может быть помещён в двумерный массив c(x, y) типа Color (Цвет):

For y …

For x …

c(x, y) = Page1.GetPixel(x, y)

Next

Next

Цвет каждой точки изображения – каждый элемент массива c(x, y) – может быть программно изменён в соответствии с тем, какое преобразование выбрано. Этот изменённый цвет записывается в точку с координатами (x, y) другого виртуального объекта – например, с именем Page2 – с помощью метода SetPixel. Этот объект создаётся следующим образом:

Dim Page2 As Bitmap

Page2 = New Bitmap(PictureBox2.Width, _

PictureBox2.Height)

Рассмотрим преобразование в негативное изображение. Оно реализуется следующим образом:

For y …

For x …

cp = c(x, y)

a = cp.A : r = cp.R : g = cp.G : b = cp.B

cp = Color.FromArgb(a, 255 - r, 255 - g, 255 - b)

Page2.SetPixel(x, y, cp)

Next

Next

На рис. 6.7 показана форма приложения на этапе проектирования – при построении меню. Меню содержит четыре команды. После загрузки формы (старта приложения) команда Загрузить массив должна быть доступна, а две следующие команды – Обрабо-

тать изображение и Нарисовать – должны быть недоступными.

После загрузки массива первая и вторая команды обмениваются значениями «доступности» (значением свойства Enabled). Но команда Нарисовать остаётся пока недоступной.

87

Рис. 6.7. Форма приложения на этапе проектирования

Объявление переменных и две процедуры (загрузки формы и загрузки массива точек изображения) приведены в коде 6.4.

Код 6.4

Public Class Form1

Dim

w0, h0, w, h, x, y As Integer

Dim

Page1, Page2 As Bitmap

Dim

gr As Graphics

Dim

cp, c(,) As Color

Dim

grey, a, r, g, b As Integer

Dim

k As Single

Dim

p As String

 

 

 

 

Private

Sub Form1_Load(ByVal sender As Object, _

 

ByVal e As System.EventArgs) Handles Me.Load

w0 = Me.Width

h0 = Me.Height

w =

PictureBox1.Width - 1

h =

PictureBox1.Height - 1

ReDim c(w, h)

Page1 = New Bitmap(PictureBox1.Image)

ОбработатьИзображение.Enabled = False

Нарисовать.Enabled = False End Sub

88

Private Sub ЗагрузитьМассив_Click(ByVal sender _ As System.Object, _

ByVal e As System.EventArgs) _ Handles ЗагрузитьМассив.Click

For y = 0 To h

For x = 0 To w

c(x, y) = Page1.GetPixel(x, y)

Next

Next

ОбработатьИзображение.Enabled = True ЗагрузитьМассив.Enabled = False

End Sub

Рассмотрим процедуры для команды меню Обработать изо-

бражение, четырёх команд подменю: Черно-белое, Негативное, Увеличенное и Уменьшенное, а также команды меню Нарисо-

вать (код 6.5). Процедуры для команд подменю Слева-направо и Сверху-вниз в данном примере не рассматриваются.

Щелчок команды Обработать изображение вызывает не только

появление подменю, показанного на рис. 6.7, но и меняет размеры как самой формы, так и окна изображения PictureBox2, на котором

будет впоследствии нарисовано новое изображение. Кроме того, создается новый виртуальный объект Page2, в котором будет соз-

даваться это изображение. Размеры объекта Page2 «подгоняются» под размеры окна изображения PictureBox2. Эта же процедура де-

лает доступной команду меню Нарисовать.

Щелчок каждой из команд подменю включает соответствующую процедуру обработки изображения, в результате работы которой формируется содержимое виртуального объекта Page2. Завершается этот процесс присвоением строковой переменной p одного из значений: «черно-белое», «негативное», «увеличенное», «уменьшенное» и т.д. Эти значения будут учитываться в дальнейшем, после щелчка команды меню Нарисовать.

Код 6.5

Private Sub ОбработатьИзображение_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) _ Handles ОбработатьИзображение.Click

89

Me.Width = w0

Me.Height = h0 PictureBox2.Width = w + 1 PictureBox2.Height = h + 1

Page2 = New Bitmap(PictureBox2.Width, _ PictureBox2.Height)

ОбработатьИзображение.Enabled = False

Нарисовать.Enabled = True End Sub

Private Sub ЧёрноБелое_Click(ByVal sender _ As System.Object, _

ByVal e As System.EventArgs) _ Handles ЧёрноБелое.Click

For y = 0 To h

For x = 0 To w cp = c(x, y)

a = cp.A : r = cp.R : g = cp.G : b = cp.B grey = (r + g + b) / 3

cp = Color.FromArgb(a, grey, grey, grey) Page2.SetPixel(x, y, cp)

Next

Next

MsgBox("Черно-белое - на Page2") p = "черно-белое"

End Sub

Private Sub Негативное_Click(ByVal sender _ As System.Object, _

ByVal e As System.EventArgs) _ Handles Негативное.Click

For y = 0 To h

For x = 0 To w cp = c(x, y) a = cp.A

r = cp.R g = cp.G b = cp.B

cp = Color.FromArgb(a, _

255 - r, 255 - g, 255 - b) Page2.SetPixel(x, y, cp)

Next

Next

MsgBox("Негативное - на Page2") p = "негативное"

End Sub

90

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]