在 C++ 中读取 .bmp 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8836017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:11:24  来源:igfitidea点击:

reading a .bmp file in c++

c++bmp

提问by soupdiver

I'm trying to load a bmp file for reusing it in opengl. I've found some code via google on how to load a bmp file. I took this code and put in a class Bitmap in my project. The class is far away from being finished but already the reading of the file headers goes wrong. After reading the bytes for INFOHEADER and FILEHEADER there aren't the right values in my structs. Some ideas?

我正在尝试加载一个 bmp 文件以在 opengl 中重用它。我通过谷歌找到了一些关于如何加载 bmp 文件的代码。我接受了这段代码,并在我的项目中放入了一个 Bitmap 类。该课程远未完成,但文件头的读取已经出错。读取 INFOHEADER 和 FILEHEADER 的字节后,我的结构中没有正确的值。一些想法?

//
//  Bitmap.h
//

#ifndef LaserMaze_Bitmap_h
#define LaserMaze_Bitmap_h

typedef struct                       /**** BMP file header structure ****/
{
    unsigned short bfType;           /* Magic number for file */
    unsigned int   bfSize;           /* Size of file */
    unsigned short bfReserved1;      /* Reserved */
    unsigned short bfReserved2;      /* ... */
    unsigned int   bfOffBits;        /* Offset to bitmap data */
} BITMAPFILEHEADER;

#  define BF_TYPE 0x4D42             /* "MB" */

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;

/*
 * Constants for the biCompression field...
 */

#  define BI_RGB       0             /* No compression - straight BGR data */
#  define BI_RLE8      1             /* 8-bit run-length compression */
#  define BI_RLE4      2             /* 4-bit run-length compression */
#  define BI_BITFIELDS 3             /* RGB bitmap with RGB masks */

typedef struct                       /**** Colormap entry structure ****/
{
    unsigned char  rgbBlue;          /* Blue value */
    unsigned char  rgbGreen;         /* Green value */
    unsigned char  rgbRed;           /* Red value */
    unsigned char  rgbReserved;      /* Reserved */
} RGBQUAD;

class Bitmap {
public:
    Bitmap(const char* filename);
    ~Bitmap();
    RGBQUAD* pixels;
    BITMAPFILEHEADER fh;
    BITMAPINFOHEADER ih;

    private:

};

#endif

the cpp

人民党

//  Bitmap.cpp
//

#include <iostream>
#include <stdio.h>

#include "Bitmap.h"

Bitmap::Bitmap(const char* filename) {
    FILE* file;
    file = fopen(filename, "rb");

    std::cout << sizeof(BITMAPFILEHEADER) << std::endl;

    if(file != NULL) { // file opened
        BITMAPFILEHEADER h;
        size_t x = fread(&h, sizeof(BITMAPFILEHEADER), 1, file); //reading the FILEHEADER

        std::cout << x;
        fread(&this->ih, sizeof(BITMAPINFOHEADER), 1, file);

        fclose(file);
    }
}

回答by Itsik

The header needs to be 2 byte aligned.

标头需要 2 字节对齐。

#pragma pack(2) // Add this

typedef struct
{
    unsigned short bfType;
    unsigned int   bfSize;
    unsigned short bfReserved1;
    unsigned short bfReserved2;
    unsigned int   bfOffBits;
} BITMAPFILEHEADER;

#pragma pack() // and this

回答by jschroedl

How about letting your Windows OS load it for you with LoadImage.

让您的 Windows 操作系统使用LoadImage.

HBITMAP hbm = LoadImage( NULL, path, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);

Use GetObject()to find further info like size, etc. and GetDIBits()if you want to get at the individual bits.

使用GetObject()找到像大小等进一步的信息和GetDIBits(),如果你想在各个位。

回答by AndersK

BITMAPINFOHEADER ::You need to read first the biSizein order to know how large the info header is, you cannot rely on sizeof().

BITMAPINFOHEADER ::您需要先阅读 thebiSize以了解信息标头有多大,您不能依赖sizeof().

Check out this wiki articleabout the file format

查看这篇关于文件格式的维基文章