ПОНЯТНО О Visual Basic NET (том 2)

Мультфильм «Летающая тарелка»


Богатство графических методов и свойств объектов VB позволяет делать мультфильмы разными способами. Я выберу те, что ведут к цели проще и быстрее.

Покажите своим друзьям фильм, снятый «секретной видеокамерой»: В небе над вашим домом летит летающая тарелка.

Для этого вам понадобится ввести в компьютер фотографию, на которой были бы видны ваш дом и небо. Если такой фотографии у вас нет, возьмите любой графический файл из тех, что есть на вашем диске – для тренировки сойдет.

Затем зайдите в любой графический редактор, например, в Paint, настройте очень маленький размер листа, на котором будете рисовать, и на белом фоне нарисуйте во весь этот маленький лист летающую тарелку. Сохраните ее изображение в файл в формате BMP или другом каком-нибудь, не искажающем цвета пикселей (например, для рисунков очень хорош формат PNG, он и цвета пикселей не искажает и размеры файла сильно уменьшает). Формат JPEG не подойдет, потому что он цвета пикселей чуть-чуть, почти незаметно для глаза, но искажает. Почему нельзя искажать даже чуть-чуть, скажу чуть-чуть позже. JPEG, однако, хорош для фотографий, потому что он сильно уменьшает размеры файла.

Создайте проект с формой, таймером и PictureBox. Будем писать программу, постепенно ее улучшая.

1 версия (плохая):

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

        Me.BackgroundImage = Image.FromFile("Ландшафт.jpg")

        PictureBox1.Image = Image.FromFile("Тарелка.bmp")

End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        PictureBox1.Left = PictureBox1.Left + 1

End Sub



Результаты работы программы вы видите на Рис. 13.9. Тарелка действительно летит по небу слева направо. Плохо то, что летит она в обрамлении большого серого и маленького белого прямоугольников. Большой серый прямоугольник – это наш PictureBox. Займемся им во 2 версии программы, а маленьким белым – в 3 версии.



Рис. 13.9
2 версия (получше). Для избавления от серого прямоугольника сделаем 3 вещи:
Избавим PictureBox от бордюра:
        PictureBox1.BorderStyle = BorderStyle.None
Чтобы избавиться от серого цвета, сделаем PictureBox «прозрачным». Для этого или в режиме проектирования установим его свойству BackColor значение Transparent (в закладке Web), или напишем в коде:
        PictureBox1.BackColor = Color.Transparent
Помогло. А теперь замечаем, что движение чуть притормаживает. Происходит это от того, что PictureBox слишком велик и двигать его компьютеру в нашем случае трудно. Заставим PictureBox сжаться до размеров тарелки:
        PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
Вот программа:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackgroundImage = Image.FromFile("Ландшафт.jpg")
        PictureBox1.Image = Image.FromFile("Тарелка.bmp")
        PictureBox1.BorderStyle = BorderStyle.None
        PictureBox1.BackColor = Color.Transparent
        PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        PictureBox1.Left = PictureBox1.Left + 1
End Sub
Результаты работы программы вы видите на Рис. 13.10.

Рис. 13.10
3 версия (нормальная). Белый прямоугольник вокруг тарелки достался нам в наследство от графического редактора. Ведь сохранилась в файле не только сама тарелка, но весь прямоугольный лист, на котором ее рисовали. А лист-то был белый.
Мы имеем возможность, работая с объектом Bitmap, объявить любой цвет прозрачным. Поэтому для избавления от белого прямоугольника сделаем 3 вещи: Образуем из нашей тарелки объект Bitmap, объявим белый цвет прозрачным и присвоим Bitmap свойству Image нашего PictureBox. Вот программа:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackgroundImage = Image.FromFile("Ландшафт.jpg")


        Dim Тарелка As New Bitmap("Тарелка.bmp")
        Тарелка.MakeTransparent(Color.White)
        PictureBox1.Image = Тарелка
        PictureBox1.BorderStyle = BorderStyle.None
        PictureBox1.BackColor = Color.Transparent
        PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        PictureBox1.Left = PictureBox1.Left + 1
End Sub
Здесь я полужирным выделил три новых оператора. Использован метод MakeTransparent объекта Bitmap, который делает прозрачным цвет, указанный в качестве параметра.  Удовлетворительные результаты работы программы вы видите на Рис. 13.11.

Рис. 13.11
Вопрос: Что делать, если тарелка нарисована в графическом редакторе не на белом фоне, а на другом, причем, что за цвет у фона, неизвестно? Не беда. Выберите на картинке пиксель, который наверняка имеет этот самый цвет фона и узнайте его цвет при помощи функции GetPixel, как мы это делали в 12.7.4. А затем используйте его в качестве параметра метода MakeTransparent:
        Dim Цвет As Color = Тарелка.GetPixel(1, 1)
        Тарелка.MakeTransparent(Цвет)
Чем плох JPEG. Сейчас становится ясно, почему нельзя было сохранять тарелку в формате JPEG. Дело в том, что этот формат платит за свою компактность некоторым искажением мельчайших деталей фотографии. При этом однородный фон вполне может превратиться в пестрый набор пикселей, имеющих очень близкие, но все-таки не абсолютно одинаковые цвета. Для глаза незаметно, но компьютер не проведешь! Он видит,  что белый фон на рисунке тарелки не абсолютно белый, вернее – не везде абсолютно белый. Ведь что такое белый цвет для компьютера? Это когда все три составляющие цвета (красная, зеленая и синяя) равны 255. JPEG же может какие-нибудь из них для некоторых пикселей сделать, например, 254. И все! Компьютер отказывается считать этот цвет белым, а значит и не делает его прозрачным. Белая окантовка тарелки местами остается.
Задание 92.          
Пусть тарелка, полетав туда-сюда, совершит посадку. Указание: Для этого вы можете организовать счетчик импульсов таймера и в зависимости от его величины при помощи операторов выбора выбирать в процедуре Timer1_Tick то или иное направление полета тарелки.
Пусть тарелка время от времени выстреливает вниз лазерным лучом. Указание: Для этого вы можете использовать летающий вместе с тарелкой высокий узкий PictureBox и менять его фон с прозрачного на белый и обратно или делать PictureBox иногда видимым.

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