В приложении камеры растровые массивы пикселей извлекаются из потоковой камеры. Пиксельные массивы захватываются путем записи их в именованный канал, где на другом конце канала ffmpeg извлекает их и создает файл AVI.
Мне нужно будет создать один пользовательский кадр (с включенным пользовательским текстом) и передать пиксели в качестве первого кадра в результирующем mov ie.
. Вопрос в том, как я могу использовать TBitmap (для удобства) для
Создание растрового изображения X по Y mono chrome (8 бит) с нуля, с включенным пользовательским текстом. Я хочу, чтобы фон был белым, а текст - черным. (В основном это был шаг, см. Ниже.)
Получить массив пикселей, который я могу отправить / записать в канал
Шаг 1 : Следующий код создает TBitmap и записывает на него текст:
int w = 658;
int h = 492;
TBitmap* bm = new TBitmap();
bm->Width = w;
bm->Height = h;
bm->HandleType = bmDIB;
bm->PixelFormat = pf8bit;
bm->Canvas->Font->Name = "Tahoma";
bm->Canvas->Font->Size = 8;
int textY = 10;
string info("some Text");
bm->Canvas->TextOut(10, textY, info.c_str());
Вышеприведенный код в основном завершает шаг 1.
Код записи / передачи ожидает байтовый массив с пикселями растровых изображений; например,
unsigned long numWritten;
WriteFile(mPipeHandle, pImage, size, &numWritten, NULL);
, где pImage - указатель на неподписанный буфер символов (пиксели растровых изображений), а размер - длина этого буфера.
Обновление: использование созданного TBitmap и TMemoryStream для передачи данных в конвейер ffmpeg не генерирует правильный результат. Я получаю искаженное изображение с 3 диагональными линиями.
Размер буфера для кадровых буферов камеры, которые я получаю, в точности равен 323736 , что равно числу пикселей в изображении, т.е. 658x492. ПРИМЕЧАНИЕ Я пришел к выводу, что это «растровое изображение» не дополняется. 658 не делится на четыре.
Размер буфера, который я получаю после выгрузки моего сгенерированного растрового изображения в поток памяти, однако, имеет размер 325798 , что на 2062 байт больше, чем должно быть , Как @Spektre указал ниже, это расхождение может быть заполнением?
Использование следующего кода для получения массива пикселей:
ByteBuffer CustomBitmap::getPixArray()
{
// --- Local variables --- //
unsigned int iInfoHeaderSize=0;
unsigned int iImageSize=0;
BITMAPINFO *pBitmapInfoHeader;
unsigned char *pBitmapImageBits;
// First we call GetDIBSizes() to determine the amount of
// memory that must be allocated before calling GetDIB()
// NB: GetDIBSizes() is a part of the VCL.
GetDIBSizes(mTheBitmap->Handle,
iInfoHeaderSize,
iImageSize);
// Next we allocate memory according to the information
// returned by GetDIBSizes()
pBitmapInfoHeader = new BITMAPINFO[iInfoHeaderSize];
pBitmapImageBits = new unsigned char[iImageSize];
// Call GetDIB() to convert a device dependent bitmap into a
// Device Independent Bitmap (a DIB).
// NB: GetDIB() is a part of the VCL.
GetDIB(mTheBitmap->Handle,
mTheBitmap->Palette,
pBitmapInfoHeader,
pBitmapImageBits);
delete []pBitmapInfoHeader;
ByteBuffer buf;
buf.buffer = pBitmapImageBits;
buf.size = iImageSize;
return buf;
}
Таким образом, последняя проблема, похоже, заключается в получении байта массива, который имеет такого же размера, как те, которые приходят из камеры. Как найти и удалить байты заполнения из кода TBitmap ??