AV_PIX_FMT_BGR0像素格式的AvFrame保存成 BMP 图片
Linux中使用ffmpeg的x11grab设备捕获屏幕,它捕获上来解码之后的AvFrame的像素格式(AVPixelFormat)是AV_PIX_FMT_BGR0,其枚举定义如下
值:123
AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX… X=unused/undefined
后面的0,没有什么实际意义,但是保存成BMP还是需要把他一起写出去的。
BMP结构体
typedef struct /**** BMP file header structure ****/
{
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data */
} BITMAPFILEHEADER;
typedef struct /**** BMP file info structure ****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BITMAPINFOHEADER;
代码
//ipFrame 就是解码后的 AvFrame
{
static int i = 0;
if(i < 10)
{
QString name = QString("%1.bmp").arg(QString::number(++i).rightJustified(5, '0'));
QFile file(QString("./img/%1").arg(name));
file.open(QIODevice::WriteOnly);
int w = ipFrame->width;
int h = ipFrame->height;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
unsigned short bfType=0x4d42; //'BM'
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfSize = 2/* 2B魔术字 */+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+w*h*4;
bfh.bfOffBits = 2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = w;
bih.biHeight = -h; //翻转一下图片
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = 0;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 5000;
bih.biYPelsPerMeter = 5000;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
/*Write headers*/
file.write((const char *)&bfType, sizeof(bfType));
file.write((const char *)&bfh, sizeof(bfh));
file.write((const char *)&bih, sizeof(bih));
file.write((const char *)ipFrame->data[0], w*h*4);
file.flush();
file.close();
}
}