Incorrect Bitmap Copy/Output

前端 未结 1 1524
忘掉有多难
忘掉有多难 2021-01-23 12:01

So I am having a problem figuring out exactly what is going wrong with trying to read any 24bpp bitmap image and re-create it in the same folder. It works with one image, but n

1条回答
  •  滥情空心
    2021-01-23 12:45

    You can do it like this.. Also, if you don't want to make a temporary array to copy the pixels, you can easily read, seek, read, seek, etc.. OR you can just read all at once. There are so many ways to read a bitmap and be efficient/inefficient. It's up to you how you want to do it. Another efficient way to do it is to SAVE the BitmapInfoHeader and BitmapFileHeader. Then when you decide to write the bitmap to the disk, just write them headers first then the pixels. WAY faster and easier.. I did NOT do that in this example. I'll leave that up to you to figure out.

    Here is a sample code I wrote for answering your question. I prefer to use 1-dimensional arrays.

    #include 
    #include 
    #include 
    
    typedef struct
    {
        unsigned int width, height;
        unsigned char* pixels;
    } Bitmap;
    
    void InitBitmap(Bitmap* bmp)
    {
        if (bmp)
        {
            bmp->width = 0;
            bmp->height = 0;
            bmp->pixels = NULL;
        }
    }
    
    void FreeBitmap(Bitmap* bmp)
    {
        if (bmp && bmp->pixels)
        {
            bmp->width = 0;
            bmp->height = 0;
            delete[] bmp->pixels;
            bmp->pixels = NULL;
        }
    }
    
    bool ReadBitmap(const char* FilePath, Bitmap* bmp)
    {
        std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
    
        if (!bmp || !hFile.is_open())
            return false;
    
        BITMAPINFO Info;
        BITMAPFILEHEADER Header;
        memset(&Info, 0, sizeof(Info));
        memset(&Header, 0, sizeof(Header));
    
        hFile.read((char*)&Header, sizeof(Header));
        hFile.read((char*)&Info.bmiHeader, sizeof(Info.bmiHeader));
    
        bmp->width = Info.bmiHeader.biWidth;
        bmp->height = Info.bmiHeader.biHeight < 0 ? -Info.bmiHeader.biHeight : Info.bmiHeader.biHeight;
        size_t size = Info.bmiHeader.biSizeImage;
    
        bmp->pixels = new unsigned char[size];
        hFile.seekg(Header.bfOffBits, std::ios::beg);
        hFile.read((char*)bmp->pixels, size);
        hFile.close();
    
        return true;
    }
    
    bool WriteBitmap(const char* FilePath, Bitmap* bmp)
    {
        std::fstream hFile(FilePath, std::ios::out | std::ios::binary);
    
        if (!bmp || !hFile)
            return false;
    
        BITMAPINFO Info;
        BITMAPFILEHEADER Header;
        memset(&Info, 0, sizeof(Info));
        memset(&Header, 0, sizeof(Header));
    
        Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        Info.bmiHeader.biWidth = bmp->width;
        Info.bmiHeader.biHeight = bmp->height;
        Info.bmiHeader.biPlanes = 1;
        Info.bmiHeader.biBitCount = 24;
        Info.bmiHeader.biCompression = BI_RGB;
        Info.bmiHeader.biSizeImage = 0;
        Header.bfType = 0x4D42;
        Header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
        size_t size = (((24 * bmp->width + 31) & ~31) / 8) * bmp->height;
    
        hFile.write((char*)&Header, sizeof(Header));
        hFile.write((char*)&Info.bmiHeader, sizeof(Info.bmiHeader));
        hFile.write((char*)bmp->pixels, size);
        hFile.close();
        return true;
    }
    
    int main()
    {
        Bitmap bmp;
        InitBitmap(&bmp);
    
        ReadBitmap("C:/Users/Brandon/Desktop/foo.bmp", &bmp);
        WriteBitmap("C:/Users/Brandon/Desktop/foo2.bmp", &bmp);
    
        FreeBitmap(&bmp);
    }
    

    0 讨论(0)
提交回复
热议问题