如何将BMP像素值读入数组? 我在C++中编写代码(在Windows上),我试图提取灰度BMP的像素值。我不关心保留任何元数据,只想将像素值存储在一个char数组中。我还没有找到一种标准或“典型”的手动方式,所以我想知道是否有一个简单的库,人们可以用来将位图加载到内存中

如何将BMP像素值读入数组? 我在C++中编写代码(在Windows上),我试图提取灰度BMP的像素值。我不关心保留任何元数据,只想将像素值存储在一个char数组中。我还没有找到一种标准或“典型”的手动方式,所以我想知道是否有一个简单的库,人们可以用来将位图加载到内存中,c++,windows,image,bmp,C++,Windows,Image,Bmp,提前谢谢 你可以试试这个库的API。肯定有一些库(见其他答案),但很快,它就是一种简单的文件格式,你可以很容易地解析自己。详情如下: (我已经离开Win32好几年了,但是LoadImage函数可以从BMP文件中获取HBITMAP。我不确定如何直接将其转换为像素阵列,但我可以想象DC会有一些扭曲,可以让您获取值 更多提示:)将整个文件读入内存。前面将有一个小标题,其余部分将是像素值 第一部分是结构。您唯一关心的部分是bOffBits,它给出了从文件开始到像素值的字节数 BITMAPFILEHEA

提前谢谢

你可以试试这个库的API。

肯定有一些库(见其他答案),但很快,它就是一种简单的文件格式,你可以很容易地解析自己。详情如下:

(我已经离开Win32好几年了,但是
LoadImage
函数可以从BMP文件中获取HBITMAP。我不确定如何直接将其转换为像素阵列,但我可以想象DC会有一些扭曲,可以让您获取值


更多提示:)

将整个文件读入内存。前面将有一个小标题,其余部分将是像素值

第一部分是结构。您唯一关心的部分是bOffBits,它给出了从文件开始到像素值的字节数

BITMAPFILEHEADER
后面的下一部分将是一个。这将有助于确定像素的格式

如果位深度需要调色板,则随后将显示调色板

像素值有两个陷阱。首先,顺序是(蓝色、绿色、红色),与其他人的做法正好相反。第二,行从图像的底部到顶部,再次从其他所有行向后移动。最后,一行中的字节数将始终填充到4的下一个倍数


我几乎忘了提到,JPEG或PNG文件可以编码为BMP,但这并不常见。查看
BitMapInfo标头的双压缩字段,如果它不是BI\u RGB,您将需要更多帮助。

您有两个很好的选择:

  • 自己加载并解析BMP文件。BMP文件以BITMAPFILEHADER开头,后跟BitMapInfo标头,后跟0个或多个RGBQUAD(调色板条目)。像素数据的偏移量在BITMAPFILEHADER中,但应检查BitMapInfo标头以确保图像格式符合您的期望/支持

  • 使用LR_CREATEDIBSECTION标志调用LoadImage()API,它将返回DIB节的句柄。接下来调用GetObject(),传入返回的句柄和指向DIBSECTION结构的指针。然后读取位图大小、格式、指向像素数据的指针等的DIBSECTION结构

  • 如果您在Windows上,选项2会更好,因为LoadImage()可能会为您检查无效的文件格式,并且可以加载的不仅仅是BMP文件


    访问Windows BMP像素时,请记住线条始终是DWORD对齐的。

    和准备就绪的代码,使用g++进行测试(不是Windows,但可能会帮助某些人):


    如果在Visual Studio中编码,在声明tagBITMAPFILEHEADER和TagBitMapInfo结构(如Yola的响应中所示)之前,请确保包含“#pragma pack(2)”。Ohterwise结构将填充到下一个4字节边界,而不是下一个2字节边界,数据将是垃圾


    参考资料

    扩展了Yola所写的内容,应该能够读入和输出文件。它没有经过很好的测试,但似乎有效。它使用输出时读入的文件格式

    #include <iostream>
    #include <unistd.h>
    #include <fstream>
    
    using std::cout;
    using std::endl;
    using std::ofstream;
    using std::ifstream;
    
    #pragma pack(1)
    #pragma once
    
    typedef int LONG;
    typedef unsigned short WORD;
    typedef unsigned int DWORD;
    
    typedef struct tagBITMAPFILEHEADER {
        WORD bfType;
        DWORD bfSize;
        WORD bfReserved1;
        WORD bfReserved2;
        DWORD bfOffBits;
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER {
        DWORD biSize;
        LONG biWidth;
        LONG biHeight;
        WORD biPlanes;
        WORD biBitCount;
        DWORD biCompression;
        DWORD biSizeImage;
        LONG biXPelsPerMeter;
        LONG biYPelsPerMeter;
        DWORD biClrUsed;
        DWORD biClrImportant;
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    
    unsigned char** reds;
    unsigned char** greens;
    unsigned char** blues;
    int rows;
    int cols;
    
    void ColorTest() {
        // Makes Red Rectangle in top left corner. Rectangle stretches to right alot
        for (int i = rows / 10; i < 3 * rows / 10; i++)
            for (int j = cols / 10; j < 7 * cols / 10; j++)
                reds[i][j] = 0xff;
    
    // Makes small green box in bottom right
        for (int i = 8 * rows / 10; i < rows; i++)
            for (int j = 8 * cols / 10; j < cols; j++)
                greens[i][j] = 0xff;
    
    // Makes White box in the middle of the screeene    
        for (int i = rows * 4 / 10; i < rows * 6 / 10; i++)
            for (int j = cols * 4 / 10; j < cols * 6 / 10; j++) {
                greens[i][j] = 0xff;
                reds[i][j] = 0xff;
                blues[i][j] = 0xff;
            }
    
    // Blue verticle rectangle bottom left
        for (int i = rows * 6 / 10; i < rows; i++)
            for (int j = cols * 0; j < cols * 1 / 10; j++)
                blues[i][j] = 0xff;
    }
    
    void RGB_Allocate(unsigned char**& dude) {
        dude = new unsigned char*[rows];
        for (int i = 0; i < rows; i++)
            dude[i] = new unsigned char[cols];
    }
    
    bool FillAndAllocate(char*& buffer, const char* Picture, int& rows, int& cols, int& BufferSize) { //Returns 1 if executed sucessfully, 0 if not sucessfull
        std::ifstream file(Picture);
    
        if (file) {
            file.seekg(0, std::ios::end);
            std::streampos length = file.tellg();
            file.seekg(0, std::ios::beg);
    
            buffer = new char[length];
            file.read(&buffer[0], length);
    
            PBITMAPFILEHEADER file_header;
            PBITMAPINFOHEADER info_header;
    
            file_header = (PBITMAPFILEHEADER) (&buffer[0]);
            info_header = (PBITMAPINFOHEADER) (&buffer[0] + sizeof(BITMAPFILEHEADER));
            rows = info_header->biHeight;
            cols = info_header->biWidth;
            BufferSize = file_header->bfSize;
            return 1;
        }
        else {
            cout << "File" << Picture << " don't Exist!" << endl;
            return 0;
        }
    }
    
    void GetPixlesFromBMP24(unsigned char** reds, unsigned char** greens, unsigned char** blues, int end, int rows, int cols, char* FileReadBuffer) { // end is BufferSize (total size of file)
        int count = 1;
    int extra = cols % 4; // The nubmer of bytes in a row (cols) will be a multiple of 4.
        for (int i = 0; i < rows; i++){
    count += extra;
        for (int j = cols - 1; j >= 0; j--)
            for (int k = 0; k < 3; k++) {
                    switch (k) {
                    case 0:
                        reds[i][j] = FileReadBuffer[end - count++];
                        break;
                    case 1:
                        greens[i][j] = FileReadBuffer[end - count++];
                        break;
                    case 2:
                        blues[i][j] = FileReadBuffer[end - count++];
                        break;
                    }
                }
                }
    }
    
    void WriteOutBmp24(char* FileBuffer, const char* NameOfFileToCreate, int BufferSize) {
        std::ofstream write(NameOfFileToCreate);
        if (!write) {
            cout << "Failed to write " << NameOfFileToCreate << endl;
            return;
        }
        int count = 1;
        int extra = cols % 4; // The nubmer of bytes in a row (cols) will be a multiple of 4.
        for (int i = 0; i < rows; i++){
            count += extra;
            for (int j = cols - 1; j >= 0; j--)
                for (int k = 0; k < 3; k++) {
                    switch (k) {
                    case 0: //reds
                        FileBuffer[BufferSize - count] = reds[i][j];
                        break;
                    case 1: //green
                        FileBuffer[BufferSize - count] = greens[i][j];
                        break;
                    case 2: //blue
                        FileBuffer[BufferSize - count] = blues[i][j];
                        break;
                    }
                    count++;
                }
                }
        write.write(FileBuffer, BufferSize);
    }
    
    
    int main(int args, char** cat) {
    char* FileBuffer; int BufferSize;
    
    #define Picture "ReadInPicture.bmp"
    if (!FillAndAllocate(FileBuffer, Picture, rows, cols, BufferSize)){cout << "File read error" << endl; return 0;}
    cout << "Rows: " << rows << " Cols: " << cols << endl;
    
    RGB_Allocate(reds);
    RGB_Allocate(greens);
    RGB_Allocate(blues);
    GetPixlesFromBMP24( reds,  greens, blues,BufferSize, rows, cols, FileBuffer);
    ColorTest();
    #define WriteOutFile "OutputPicture.bmp"
    WriteOutBmp24(FileBuffer,  WriteOutFile,BufferSize);
        return 1;
    }
    
    #包括
    #包括
    #包括
    使用std::cout;
    使用std::endl;
    使用std::of流;
    使用std::ifstream;
    #布拉格语包(1)
    #布拉格语一次
    typedef int LONG;
    typedef无符号短字;
    typedef无符号整数双字;
    typedef结构tagBITMAPFILEHEADER{
    字型;
    德沃德尺寸;
    保留字1;
    保留字2;
    德沃德;
    }BITMAPFILEHEADER,*PBITMAPFILEHEADER;
    typedef结构TagBitMapInfo标头{
    德沃德·比西泽;
    长双宽;
    长双峰高度;
    单词双平面;
    单词双比特计数;
    德沃德双压缩;
    德沃德·比西泽迈格;
    长双峰渗透计;
    长双渗透计;
    德沃德·比克尔鲁斯;
    德沃德·比克勒;
    }BitMapInfo头,*PBITMapInfo头;
    未签名字符**红色;
    无符号字符**绿色;
    未签名字符**蓝色;
    int行;
    int cols;
    void ColorTest(){
    //在左上角形成红色矩形。矩形向右延伸很多
    对于(int i=行/10;i<3*行/10;i++)
    对于(int j=cols/10;j<7*cols/10;j++)
    红色[i][j]=0xff;
    //在右下角创建一个绿色的小框
    对于(int i=8*行/10;i#pragma once
    
    typedef int LONG;
    typedef unsigned short WORD;
    typedef unsigned int DWORD;
    
    typedef struct tagBITMAPFILEHEADER {
      WORD  bfType;
      DWORD bfSize;
      WORD  bfReserved1;
      WORD  bfReserved2;
      DWORD bfOffBits;
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER {
      DWORD biSize;
      LONG  biWidth;
      LONG  biHeight;
      WORD  biPlanes;
      WORD  biBitCount;
      DWORD biCompression;
      DWORD biSizeImage;
      LONG  biXPelsPerMeter;
      LONG  biYPelsPerMeter;
      DWORD biClrUsed;
      DWORD biClrImportant;
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    
    #include <iostream>
    #include <unistd.h>
    #include <fstream>
    
    using std::cout;
    using std::endl;
    using std::ofstream;
    using std::ifstream;
    
    #pragma pack(1)
    #pragma once
    
    typedef int LONG;
    typedef unsigned short WORD;
    typedef unsigned int DWORD;
    
    typedef struct tagBITMAPFILEHEADER {
        WORD bfType;
        DWORD bfSize;
        WORD bfReserved1;
        WORD bfReserved2;
        DWORD bfOffBits;
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER {
        DWORD biSize;
        LONG biWidth;
        LONG biHeight;
        WORD biPlanes;
        WORD biBitCount;
        DWORD biCompression;
        DWORD biSizeImage;
        LONG biXPelsPerMeter;
        LONG biYPelsPerMeter;
        DWORD biClrUsed;
        DWORD biClrImportant;
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    
    unsigned char** reds;
    unsigned char** greens;
    unsigned char** blues;
    int rows;
    int cols;
    
    void ColorTest() {
        // Makes Red Rectangle in top left corner. Rectangle stretches to right alot
        for (int i = rows / 10; i < 3 * rows / 10; i++)
            for (int j = cols / 10; j < 7 * cols / 10; j++)
                reds[i][j] = 0xff;
    
    // Makes small green box in bottom right
        for (int i = 8 * rows / 10; i < rows; i++)
            for (int j = 8 * cols / 10; j < cols; j++)
                greens[i][j] = 0xff;
    
    // Makes White box in the middle of the screeene    
        for (int i = rows * 4 / 10; i < rows * 6 / 10; i++)
            for (int j = cols * 4 / 10; j < cols * 6 / 10; j++) {
                greens[i][j] = 0xff;
                reds[i][j] = 0xff;
                blues[i][j] = 0xff;
            }
    
    // Blue verticle rectangle bottom left
        for (int i = rows * 6 / 10; i < rows; i++)
            for (int j = cols * 0; j < cols * 1 / 10; j++)
                blues[i][j] = 0xff;
    }
    
    void RGB_Allocate(unsigned char**& dude) {
        dude = new unsigned char*[rows];
        for (int i = 0; i < rows; i++)
            dude[i] = new unsigned char[cols];
    }
    
    bool FillAndAllocate(char*& buffer, const char* Picture, int& rows, int& cols, int& BufferSize) { //Returns 1 if executed sucessfully, 0 if not sucessfull
        std::ifstream file(Picture);
    
        if (file) {
            file.seekg(0, std::ios::end);
            std::streampos length = file.tellg();
            file.seekg(0, std::ios::beg);
    
            buffer = new char[length];
            file.read(&buffer[0], length);
    
            PBITMAPFILEHEADER file_header;
            PBITMAPINFOHEADER info_header;
    
            file_header = (PBITMAPFILEHEADER) (&buffer[0]);
            info_header = (PBITMAPINFOHEADER) (&buffer[0] + sizeof(BITMAPFILEHEADER));
            rows = info_header->biHeight;
            cols = info_header->biWidth;
            BufferSize = file_header->bfSize;
            return 1;
        }
        else {
            cout << "File" << Picture << " don't Exist!" << endl;
            return 0;
        }
    }
    
    void GetPixlesFromBMP24(unsigned char** reds, unsigned char** greens, unsigned char** blues, int end, int rows, int cols, char* FileReadBuffer) { // end is BufferSize (total size of file)
        int count = 1;
    int extra = cols % 4; // The nubmer of bytes in a row (cols) will be a multiple of 4.
        for (int i = 0; i < rows; i++){
    count += extra;
        for (int j = cols - 1; j >= 0; j--)
            for (int k = 0; k < 3; k++) {
                    switch (k) {
                    case 0:
                        reds[i][j] = FileReadBuffer[end - count++];
                        break;
                    case 1:
                        greens[i][j] = FileReadBuffer[end - count++];
                        break;
                    case 2:
                        blues[i][j] = FileReadBuffer[end - count++];
                        break;
                    }
                }
                }
    }
    
    void WriteOutBmp24(char* FileBuffer, const char* NameOfFileToCreate, int BufferSize) {
        std::ofstream write(NameOfFileToCreate);
        if (!write) {
            cout << "Failed to write " << NameOfFileToCreate << endl;
            return;
        }
        int count = 1;
        int extra = cols % 4; // The nubmer of bytes in a row (cols) will be a multiple of 4.
        for (int i = 0; i < rows; i++){
            count += extra;
            for (int j = cols - 1; j >= 0; j--)
                for (int k = 0; k < 3; k++) {
                    switch (k) {
                    case 0: //reds
                        FileBuffer[BufferSize - count] = reds[i][j];
                        break;
                    case 1: //green
                        FileBuffer[BufferSize - count] = greens[i][j];
                        break;
                    case 2: //blue
                        FileBuffer[BufferSize - count] = blues[i][j];
                        break;
                    }
                    count++;
                }
                }
        write.write(FileBuffer, BufferSize);
    }
    
    
    int main(int args, char** cat) {
    char* FileBuffer; int BufferSize;
    
    #define Picture "ReadInPicture.bmp"
    if (!FillAndAllocate(FileBuffer, Picture, rows, cols, BufferSize)){cout << "File read error" << endl; return 0;}
    cout << "Rows: " << rows << " Cols: " << cols << endl;
    
    RGB_Allocate(reds);
    RGB_Allocate(greens);
    RGB_Allocate(blues);
    GetPixlesFromBMP24( reds,  greens, blues,BufferSize, rows, cols, FileBuffer);
    ColorTest();
    #define WriteOutFile "OutputPicture.bmp"
    WriteOutBmp24(FileBuffer,  WriteOutFile,BufferSize);
        return 1;
    }