
- •«Программа создания мультимедийного полиэкрана»
- •Оглавление
- •Введение.
- •Язык программирования Microsoft Visual Basic
- •Классический Visual Basic (версии 5-6)
- •Элементы управления, используемые в проекте:
- •Функции Windows api, используемые в проекте.
- •Структуры, используемые в приложении «Video2Bmp».
- •Члены структуры:
- •Составные части приложения «Video2Bmp».
- •Результирующие файлы.
- •Заключение.
- •Используемые источники.
Структуры, используемые в приложении «Video2Bmp».
Структура BITMAPINFOHEADER - содержит информацию о размерах и цветовом формате аппаратно-независимого растрового формата (DIB).
Члены структуры:
biSize - определяет число байтов необходимое для структуры.
biWidth - определяет ширину точечного рисунка, в пикселях.
biHeight - устанавливает высоту точечного рисунка, в пикселях.
biPlanes - устанавливает число плоскостей целевого устройства. Это значение должно быть установлено в 1.
biBitCount - устанавливает число битов на пиксель.
biCompression - определяет тип сжатия для сжатого идущего снизу вверх точечного рисунка (идущий сверху вниз аппаратно-независимый растровый формат (DIB) не может сжиматься). Этот член структуры может быть одним из нижеперечисленных значений.
biSizeImage - устанавливает размер изображения, в байтах. Он может быть установлен в нуль для BI_RGB точечных рисунков.
biXPelsPerMeter - устанавливает разрешающую способность по вертикали для принимающего устройства точечного рисунка, в пикселях на метр. Приложение может использовать это значение, чтобы выбирать битовый образ из группы ресурсов, который лучше всего соответствует характеристикам текущего устройства.
biYPelsPerMeter - устанавливает разрешающую способность по вертикали для принимающего устройства точечного рисунка, в пикселях на метр.
biClrUsed - устанавливает число индексов цвета в таблице цветов, которые фактически используются точечным рисунком. Если это значение равняется нулю, точечный рисунок использует максимальное число цветов, соответствующих значению члена структуры biBitCount для метода сжатия, заданного членом biCompression.
biClrImportant - устанавливает число индексов цвета, которые требуются чтобы показать на экране точечный рисунок. Если это значение равняется нулю, требуются все цвета .
BITMAPFILEHEADER - эта структура содержит информацию о типе, размер и расположение файла, содержащего аппаратно-независимый растр (DIB).
RGBQUAD - структура описывает цвета, состоящий из относительной интенсивности красного, зеленого и синего цветов.
BITMAP - инкапсулирует точечный рисунок GDI+, состоящий из данных пикселей графического изображения и атрибутов рисунка. Объект Bitmap используется для работы с изображениями, определяемыми данными пикселей.
BrowseInfo - Содержит параметры для SHBrowseForFolder функции и получает информацию о папке, выбранной пользователем.
Составные части приложения «Video2Bmp».
Приложение «Video2Bmp» состоит из трех форм. Первая форма позволяет пользователю выбрать один из двух режимов:
Склейка кадров – режим для объединения двух кадров в один
Запись видео – режим для создания avi файлов из набора кадров bmp.
Во второй форме реализуется режим склейки кадров. На третьей форме реализуется режим создания видео файла из набора кадров.
Опишем структуру программы ввиде блок-схемы:
Рассмотрим самые важные функции программы: для склейки кадров, в режиме «Склейка» программа использует три PictureBox. В первый и второй загружаются картинки из соответствующих папок. Затем они перерисовываются в третий PictureBox с соответствующими размерами и соединенными вместе и сохраняются в указанной папке в формате bmp.
{Картинки из папок загружаются в соответствующие PictureBox}
Picture1.Picture = LoadPicture(Ima1 + List1.List(i))
Picture3.Picture = LoadPicture(Ima2 + List2.List(i))
{Определяются размеры картинок}
Shirina = ScaleX(Picture1.Picture.Width, vbHimetric, vbPixels)
Visota = ScaleY(Picture1.Picture.Height, vbHimetric, vbPixels)
Shirina2 = ScaleX(Picture3.Picture.Width, vbHimetric, vbPixels)
Visota2 = ScaleY(Picture3.Picture.Height, vbHimetric, vbPixels)
{Определяются новые размеры будущей объединенной картинки}
Picture2.Height = Visota + Visota2 - a - b
If Shirina > Shirina2
Then
Picture2.Width = Shirina
Else
Picture2.Width = Shirina2
Shirina = Shirina2
End If
{Файлы из первого и второго PictureBox перерисовываются в третий с соответствующими размерами}
Picture2.PaintPicture Picture1, 0, 0, Shirina, Visota - b, 0, b, , , vbSrcCopy
Picture2.PaintPicture Picture3, 0, Visota - b, Shirina, Visota2 - a, 0, a, , , vbSrcCopy
{Сохраняем полученную картинку с новым именем в формате bmp}
SavePicture Picture2.Image, sFileName + s
Для создания видео из полученных кадров создаем новый видео поток. Поток может создаваться путем инициализации структуры AVI_STREAM_INFO и передачи ее в функцию AVIFileCreateStream. Когда эта функция выполнится, второй параметр будет содержать верный указатель на вновь созданный интерфейс потока:
{Заполняем заголовок для видео потока} With strhdr .fccType = mmioStringToFOURCC("vids", 0&) {тип видео потока} .fccHandler = 0& {ссылка по умолчанию} .dwScale = 1 .dwRate = k {кадров в секунду} .dwSuggestedBufferSize = bmp.SizeImage {размер одного кадра в пикселах} Call SetRect(.rcFrame, 0, 0, bmp.Width, bmp.Height) {прямоугольник для потока} End With
{проверяем ввод пользователя} If strhdr.dwRate < 1 Then strhdr.dwRate = 1 If strhdr.dwRate > 30 Then strhdr.dwRate = 30
{и создаем поток} res = AVIFileCreateStream(pfile, ps, strhdr) If (res <> AVIERR_OK) Then GoTo error
Теперь, когда переменная ps указывает на поток, мы можем использовать ее для создания сжатого потока, содержащего всю необходимую информацию для записи его в файл. Прежде всего, пользователь должен выбрать кодек для сжатия потока:
Получаем параметры сжатия от пользователя Внимание! Эти вызовы API требуют указателя на указатель на структуру
pOpts = VarPtr(opts) res = AVISaveOptions(Form1.hWnd, _ ICMF_CHOOSE_KEYFRAME Or ICMF_CHOOSE_DATARATE, _ 1, _ ps, _ pOpts) If res <> 1 Then 'In C TRUE = 1 Call AVISaveOptionsFree(1, pOpts) GoTo error End If
Затем мы передаем эту информацию вместе с самим потоком в функцию AVIMakeCompressedStream:
{создаем сжатый поток} res = AVIMakeCompressedStream(psCompressed, ps, opts, 0&) If res <> AVIERR_OK Then GoTo error
Когда эта функция завершается успешно, переменная psCompressed указывает на интерфейс сжатого потока, который может записывать сжатый видео поток в формате, заданном структурами AVI_STREAM_INFO и AVI_COMPRESS_OPTIONS. Все, что мы должны сделать далее - установить параметры DIB, которые должны быть переданы в поток. Это требует использования структуры BITMAPINFO, что означает переменную изменяющегося размера, которую достаточно трудно использовать в VB. К счастью, здесь нам поможет класс cDIB. В этом классе имеется функция, принимающая файл с диска. Ранее я вызывал эту функцию для считывания первого кадра потока из файла для того, чтобы получить размер буфера для структуры AVI_STREAM_INFO:
{получаем первый кадр потока из файла}
Set bmp = New cDib
Directorios = Dir(RutaOpen & "*.bmp")
MsgBox "Нужно выбрать параметр сжатия", , "Предупреждение"
Do While Directorios <> ""
If bmp.CreateFromFile(RutaOpen & Directorios) <> True Then
MsgBox "No File!", vbExclamation + vbOKOnly, "KO!"
GoTo error
End If
Directorios = Dir Loop
Сейчас мы можем использовать ту же структуру для установки формата видео-потока. Прежде всего нам необходимо записать всю необходимую информацию в структуру BITMAPINFO:
With BI .biBitCount = bmp.BitCount .biClrImportant = bmp.ClrImportant .biClrUsed = bmp.ClrUsed .biCompression = bmp.Compression .biHeight = bmp.Height .biWidth = bmp.Width .biPlanes = bmp.Planes .biSize = bmp.SizeInfoHeader .biSizeImage = bmp.SizeImage .biXPelsPerMeter = bmp.XPPM .biYPelsPerMeter = bmp.YPPM End With
И затем передаем эту структуру вместе с потоком в функцию AVIStreamSetFormat:
{устанавливаем формат сжатого потока}
res = AVIStreamSetFormat(psCompressed, 0, ByVal bmp.PointerToBitmapInfo, bmp.SizeBitmapInfo) If (res <> AVIERR_OK) Then GoTo error
Если эта функция завершается успешно, то сжатый поток полностью инициализирован и готов принять несколько DIB для записи. Вы сделаете это путем передачи этого потока и позиции, с которой нужно начать запись, в функцию AVIStreamWrite. Обратите внимание, что здесь вновь используется класс cDIB, так как он содержит метод, который возвращает прямой указатель на биты, которые нужно передать в функцию:
{Записываем каждый кадр видео}
Static Posicion As Long
Posicion = 1
Directorios = Dir(RutaOpen & "*.bmp")
Do
Posicion = Posicion + 1
bmp.CreateFromFile (RutaOpen & Directorios)
res = AVIStreamWrite(psCompressed, Posicion, 1, bmp.PointerToBits, bmp.SizeImage, AVIIF_KEYFRAME, ByVal 0&, ByVal 0&)
Directorios = Dir
Loop While Directorios <> ""
Как только этот цикл завершит запись изображений, Вам нужно освободить все ресурсы и файловые указатели. Файл, созданный Вами в начале этой процедуры, теперь содержит обычный видео поток, и его можно воспроизвести в Windows Media Player или в другом проигрывателе.
Подробный разбор работы с приложением «Video2Bmp».
При запуске программы открывается форма с двумя кнопками «Склейка кадров» и «Создание видео». В этом окне выбирается режим работы программы.
При нажатии на кнопку «Склейка кадров» выбирается режим, позволяющий пользователю объединить два набора кадров в один. На форме располагаются два элемента Image, в которых будет отображаться процесс объединения кадров, по два элемента DriveListBox, Directory ListBox и ListBox – которые используются для выбора папок с кадрами.
Верхние DriveListBox, Directory ListBox используются для выбора папки с кадрами, которые будут отображаться в верхней части полиэкрана. Верхний ListBox используется для отображения названий всех кадров из этой папки.
Нижние DriveListBox, Directory ListBox используются для выбора папки с кадрами, которые будут отображаться в нижней части полиэкрана. Нижний ListBox используется для отображения названий всех кадров из соответствующей папки.
При этом нужно помнить о том, что изображения в папках должны быть в формате bmp, и лучше чтобы размеры изображений из обоих папок были равными, в противном случае кадры с меньшей шириной будут растягиваться.
Высота же полиэкрана по умолчанию устанавливается, как сумма высот кадров из первой и второй папки. Если пользователю нужно изменить высоту кадров, то он может это сделать, нажав на кнопку «Установить высоту».
После выбора нужных папок, нажимаем на кнопку «Загрузить» и в элементах ListBox отобразятся имена всех файлов из соответствующих папок. Имена в элементах ListBox отсортируются по названию. Если щелкнуть на любой элемент списка, то соответствующая картинка отобразится в элементе Image.
Также рекомендуется, чтобы количество кадров в списках совпадало, иначе оставшиеся кадры не будут использоваться, т.е. в результате объединения количество кадров будет равно меньшему количеству из списков ListBox. Кнопки «Очистить список 1» и «Очистить список 2» используются для очистки соответствующих элементов ListBox.
Если же в списках имеются лишние кадры, то с помощью кнопок «Удалить из списка» можно удалить выделенный элемент в соответствующем списке ListBox.
При нажатии на кнопку «Склеить» открывается диалоговое окно для выбора папки, в которую будет сохраняться результат.
После выбора папки начнётся процесс объединения. Файлы из первого списка будут соединятся с соответствующими по номеру файлами из второго списка и результат будет сохраняться в выбранной папке.
При завершении процесса объединения выскочит диалоговое окно, сообщающее пользователю о завершении объединения. После чего мы можем снова вернуться в меню выбора режима, нажав на кнопку «Вернуться в главное меню».
Кнопка «Создание видео» открывается форма, реализующая режим создания avi файла из кадров. С помощью кнопки «Выбрать папку с кадрами и файл сохранения» вызываются два диалоговых окна подряд. Первое для выбора папки с кадрами из которых будет собираться avi файл. Второе для выбора имени файла в котором будет сохранен результат.
После этого жмем на кнопку «Записать видео» и запускаем процесс преобразования файлов bmp в видео файл. Перед запуском этого процесса пользователю предоставляется окно выбора режима сжатия, который позволит пользователю выбрать способ сжатия. Список будет зависеть от того, какие кодеки имеются на компьютере пользователя. Выбрав способ сжатия, пользователь запускает процесс преобразования. Результат будет сохранен в указанном файле.
После записи пользователь может вернуться в главное меню с помощью кнопки «В главное меню».