Как создать текст с контуром на изображении RGB в буфере?

366
22 мая 2017, 00:01

Есть буфер с байтами RGB (раcжатый jpeg кадра с веб-камеры, без альфы, естественно). Нужно заменить часть этих байт (правый верхний угол) байтами переведенного в изображение текста с сохранением просветов в буквах, где он есть. То есть подписать кадр именем транслирующего клиента.

Заменить буфер по линиям со смещениями не проблема... Но как создать такой текст в сырых байтах, с просветами и контуром? ()

PS: контур нужен, чтобы текст было видно как на тёмном участке кадра, так и на светлом - например, белый текст с чёрной или тёмно-серой обводкой.

Answer 1

Набросаю относительно простой пример для Windows, на чистом API получить текст с надписью в массиве байт RGB.

char* myFunct(int width,int height, char* text){
  HBITMAP bmp1 = CreateBitmap(width,height,24,0);
  HDC d0 = GetDC(0);
  HDC dc = CreateCompatibleDC(d0);      
  SelectObject(dc,bmp1);
  TextOut(dc,0/*x*/,0/*y*/, text, lstrlenA(text));
  // из microsoft      
BITMAPFILEHEADER   bmfHeader;    
BITMAPINFOHEADER   bi;
bi.biSize = sizeof(BITMAPINFOHEADER);    
bi.biWidth = width;    
bi.biHeight = height;  
bi.biPlanes = 1;    
bi.biBitCount = 24/* тут было 32*/;    
bi.biCompression = BI_RGB;    
bi.biSizeImage = 0;  
bi.biXPelsPerMeter = 0;    
bi.biYPelsPerMeter = 0;    
bi.biClrUsed = 0;    
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
// have greater overhead than HeapAlloc.
char *lpbitmap  = (char*)GlobalAlloc(GMEM_FIXED,dwBmpSize);  // сюда можно поставить как массив, так и malloc или что вам нужно
// Gets the "bits" from the bitmap and copies them into a buffer 
// which is pointed to by lpbitmap.
GetDIBits(dc, bmp1, 0,
    (UINT)height /*высота экрана*/,
    lpbitmap,
    (BITMAPINFO *)&bi, DIB_RGB_COLORS);
DeleteObject(bmp1); // Освобождение
DeleteDC(dc);
ReleaseDC(0,d0);
return lpbitmap;
}

Надеюсь что это работает. Не проверял. Нижная часть взята тут https://msdn.microsoft.com/en-us/library/windows/desktop/dd183402%28v=vs.85%29.aspx

Прелесть работы под виндой в том, что нужно правильно создать контекст DC и bitmap, потом связать их. Дальше у вас два варианта, либо "вручную" рендерить текст, либо не удалять контексты и использовать TransparentBlt и подобное. На мой взгляд это на WinAPI сложно и будет страдать быстродействие.

Вручную будет в простейшем случае выглядеть где-то так (чёрный цвет-прозрачный, R!=0 G!=0 B!=0 вместо нуля можно использовать 1):

for (i=0;i<max;i++) if (buftext[i]!=0) bufdest[i] = buftext[i];
READ ALSO
Вызов шаблонной функции через Qtconcurrent::run

Вызов шаблонной функции через Qtconcurrent::run

Есть шаблонная функция:

439
Проблема с алгоритмом

Проблема с алгоритмом

Нужно построить алгоритм с временем работы O(mn)На вход подается список положительных целых чисел a_1, a_2,

303
Получить список всех доменов c++

Получить список всех доменов c++

Как получить список всех доменов? ну хотя бы на 1 ип

419
Реализация метода Хопфилда

Реализация метода Хопфилда

Добрый день! Много прочитал в интернете статей на эту тему и не до конца понял как этот метод реализуетсяМожет есть блок схема или псевдокод...

329