OpenGL中的BMP截图

时间:2017-01-10 16:17:41

标签: c++ opengl

我正在尝试以我正在运行的应用程序的BMP格式截取屏幕截图。当它被窗口化时,它很好地截取屏幕截图,无论窗口的大小如何都很好。但是,当我使用glutFullScreen()将我的应用程序全屏显示时,它不能正确保存BMP文件。任何想法为什么会发生?

这是函数调用

hacerCaptura(ancho, alto);

其中

ancho = glutGet(GLUT_SCREEN_WIDTH);
alto  = glutGet(GLUT_SCREEN_HEIGHT);

以下是代码:

    void hacerCaptura(int anchura, int altura)
{
    BMP_Data = malloc (anchura * altura * 3);
    memset (BMP_Data, 0, anchura * altura * 3);

    glReadPixels (0, 0, anchura, altura, GL_RGB, GL_UNSIGNED_BYTE, BMP_Data);
    guardaBMP ("captura.bmp", anchura, altura, (unsigned char*)BMP_Data);

    free (BMP_Data);
}


    int guardaBMP (char *filename, int anchura, int altura, unsigned char *BMP_Data)
{
    FILE *punteroFich;
    BITMAPINFOHEADER infoBMP;
    BITMAPFILEHEADER cabeceraBMP;
    unsigned int contador;
    unsigned char tempRGB;

    punteroFich = fopen (filename, "wb"); 
    if (!punteroFich)
    {
        return 0;
    }

    cabeceraBMP.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);
    cabeceraBMP.bfReserved1 = 0;
    cabeceraBMP.bfReserved2 = 0;
    cabeceraBMP.bfSize = sizeof (BITMAPFILEHEADER);
    cabeceraBMP.bfType = 0x4D42; 

    infoBMP.biBitCount = 24;
    infoBMP.biClrImportant = 0;
    infoBMP.biClrUsed = 0;
    infoBMP.biCompression = BI_RGB;
    infoBMP.biHeight = altura;
    infoBMP.biPlanes = 1;
    infoBMP.biSize = sizeof (BITMAPINFOHEADER);
    infoBMP.biSizeImage = anchura * abs (altura) * 3;
    infoBMP.biWidth = anchura;
    infoBMP.biXPelsPerMeter = 0;
    infoBMP.biYPelsPerMeter = 0;

    for (contador = 0; contador < infoBMP.biSizeImage; contador += 3)
    {
        tempRGB = BMP_Data [contador];
        BMP_Data [contador] = BMP_Data [contador + 2];
        BMP_Data [contador + 2] = tempRGB;
    }

    fwrite (&cabeceraBMP, 1, sizeof (BITMAPFILEHEADER), punteroFich);
    fwrite (&infoBMP, 1, sizeof (BITMAPINFOHEADER), punteroFich);
    fwrite (BMP_Data, 1, infoBMP.biSizeImage, punteroFich);

    fclose (punteroFich);
    return 1;
}

1 个答案:

答案 0 :(得分:1)

我怀疑违规行是这一行:

cabeceraBMP.bfSize = sizeof (BITMAPFILEHEADER);

来自documentation for BITMAPFILEHEADER

  

<强> bfSize   位图文件的大小(以字节为单位)。

因此bfSize的正确值为sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + anchura * altura * 3

我使用我创建的小型20x20位图测试了这个:

Raw Data Values of bitmap image

根据standardized bitmap format

符合您所期望的值。

我没有理智检查所有其他必填字段,但我的建议是您参考文档页面,并确保您使用正确的值替换所有这些字段。

编辑:

可能影响图像输出的另一个潜在问题。

Bitmap格式要求所有位图数据行与最多3个字节的填充对齐,具体取决于实际的行长度,以便每行数据是4个字节的倍数。如果您的图像宽度是4的倍数(如1920x1080),这不是什么大问题,但如果您使用的分辨率并不像那样整齐排列(如1366x768,则可能会成为问题)。这是一个非常常见的1080p前分辨率)。如果您的分辨率异常,请检查并确保来自glReadPixels的数据已正确填充,如果不是,则将其转换为原样。