2016-06-02 3 views
0

에 픽셀의 벡터를 작성하기위한 일반적인 방법은 가능한 픽셀의 벡터를 수행하는 클래스를 작성하는 것입니다. 기본 예제부터 시작하려고합니다. 그래서 저는 단지 4 픽셀 만 가지고 노력하고 있습니다. 그래서 헤더 값 중 일부는 하드 코딩되어 있습니다. 여기 C++ BMP

내 헤더입니다 :

uint16_t const BITMAP_FILE_TYPE = 0x4d42; //BM, little-endian 
static uint32_t const BITS_PER_BYTE = 8; 
static uint32_t const BITS_PER_PIXEL = 24; 

#pragma pack(1) 
struct BITMAPFILEHEADER { 
     //uint16_t bfType; 
     uint32_t bfSize; 
     uint16_t bfReserved1; 
     uint16_t bfReserved2; 
     uint32_t bfOffBits; 
}; BITMAPFILEHEADER; 

struct BITMAPINFOHEADER { 
     uint32_t  biSize; 
     int32_t  biWidth; 
     int32_t  biHeight; 
     uint16_t  biPlanes; 
     uint16_t  biBitCount; 
     uint32_t  biCompression; 
     uint32_t  biSizeImage; 
     int32_t  biXPelsPerMeter; 
     int32_t  biYPelsPerMeter; 
     uint32_t  biClrUsed; 
     uint32_t  biClrImportant; 
}; BITMAPINFOHEADER; 
#pragma pack() 

inline uint64_t CalcBitmapFileSize(uint32_t widthBytes, uint32_t height) { 
     uint64_t fileSize = widthBytes * height; 

     uint32_t padSize = (widthBytes) % sizeof(uint32_t); 
     if (padSize > 0) { 
       padSize = sizeof(uint32_t) - padSize; 
       padSize *= height; 
     } 
     fileSize += padSize; 
     fileSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 


     return fileSize; 
} 

class BitMapFileWriter 
{ 
public: 
    BitMapFileWriter(); 
    void WriteBMPFile(vector<Pixel> pixelVec, string fileName, uint32_t WIDTH, uint32_t HEIGHT); 
}; 

그리고 여기 내 IMPL입니다 :

void BitMapFileWriter::WriteBMPFile(vector<Pixel> pixelVec, string fileName, uint32_t WIDTH, uint32_t HEIGHT) 
{ 
     FILE    *filePtr;   // file pointer 
     BITMAPFILEHEADER bitmapFileHeader; // bitmap file header 
     BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header 
     memset(&bitmapFileHeader, 0, sizeof(bitmapFileHeader)); 
     memset(&bitmapInfoHeader, 0, sizeof(bitmapInfoHeader)); 

                    // open file for writing binary mode 
     filePtr = fopen("C:\\BMP\\4PixelOutPut.bmp", "wb"); 

     // define the bitmap file header 
     //bitmapFileHeader.bfType = BITMAP_FILE_TYPE; 
     unsigned short bfType=0x4d42; 
     bitmapFileHeader.bfSize = static_cast<uint32_t>(CalcBitmapFileSize(WIDTH * (BITS_PER_PIXEL/BITS_PER_BYTE), HEIGHT)); 
     bitmapFileHeader.bfReserved1 = 0; 
     bitmapFileHeader.bfReserved2 = 0; 
     bitmapFileHeader.bfOffBits = sizeof(bitmapFileHeader) + sizeof(bitmapInfoHeader); 

     // define the bitmap information header 
     bitmapInfoHeader.biSize = sizeof(bitmapInfoHeader); 
     bitmapInfoHeader.biWidth = WIDTH;      // bitmap width 
     bitmapInfoHeader.biHeight = HEIGHT;     // bitmap height 
     bitmapInfoHeader.biPlanes = 1; 
     bitmapInfoHeader.biBitCount = BITS_PER_PIXEL;       
     bitmapInfoHeader.biCompression = 0;    // no compression 
     bitmapInfoHeader.biSizeImage = (WIDTH * HEIGHT) * 4;   // width * height 
     bitmapInfoHeader.biXPelsPerMeter = 5000; 
     bitmapInfoHeader.biYPelsPerMeter = 5000; 
     bitmapInfoHeader.biClrUsed = 0; 
     bitmapInfoHeader.biClrImportant = 0; 

     fwrite(&bfType,1,sizeof(bfType),filePtr); 
                            // write the bitmap file header 
     fwrite(&bitmapFileHeader, 1, sizeof(BITMAPFILEHEADER), filePtr); 

     // write the bitmap info header 
     fwrite(&bitmapInfoHeader, 1, sizeof(BITMAPINFOHEADER), filePtr); 

     for(int i=0; i<4; i++) 
     { 
      Pixel pixel = pixelVec[i]; 
      fwrite(&pixel.Blue, 1, 1, filePtr); 
      fwrite(&pixel.Green, 1, 1, filePtr); 
      fwrite(&pixel.Red, 1, 1, filePtr); 
     } 


     // close our file 
     fclose(filePtr); 
} 

그리고 전화 : BitMapFileWriter bmfw을; bmfw.WriteBMPFile (pixelVec, "c : \ BMP \ 4PixelBMP.txt", 2, 2);

+1

예, 픽셀의 비트 맵 (또는 행렬)을 나타내는 클래스를 작성하여 BMP 형식으로 출력 할 수 있습니다. –

답변

1

참조 용으로 사용할 수있는이 클래스가 있습니다. 너비와 높이를위한 멤버와 (32 비트) 픽셀 색상의 std::vector을 가진 "표면"클래스입니다.

멤버 함수 Save 멤버 함수는 서페이스를 .bmp 파일로 저장합니다. 너비, 높이 및 벡터를 취하는 독립 실행 형 함수로 쉽게 변형 될 수 있습니다.

Writer 클래스는 ofstream 개체를 래핑하고 Save에서 사용되는 파일 출력 인터페이스를 제공합니다.

구조체는 익숙한 모양이어야하며 Surface의 나머지 멤버 함수는 매우 최소한의 그리기 API를 제공합니다.

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <algorithm> 

struct Color { 
    union { 
     struct { unsigned char b,g,r,a; }; 
     unsigned char bytes[4]; 
     unsigned int ref; 
    }; 
    Color(unsigned int ref=0) : ref(ref) {} 
}; 

class Surface { 
    int width, height; 
    std::vector<Color> pixels; 
public: 
    void Fill(Color color) { std::fill(pixels.begin(), pixels.end(), color); } 
    void HLine(int left, int y, int len, Color color) { 
     if(y < 0 || y >= height || left >= width) { return; } 
     if(left < 0) { len += left; left = 0; } 
     if(left + len > width) { len = width - left; } 
     int offset = y * width + left; 
     std::fill(pixels.begin() + offset, pixels.begin() + offset + len, color); 
    } 
    void RectFill(int x, int y, int w, int h, Color color) { 
     for(int i=0; i<h; ++i) { HLine(x, y + i, w, color); } 
    } 
    Surface(int width, int height) : 
     width(width), 
     height(height), 
     pixels(width*height, Color()) 
    {} 
    template <typename I>  Color& operator() (const I& x, const I& y)  { return pixels[y*width+x]; } 
    template <typename I> const Color& operator() (const I& x, const I& y) const { return pixels[y*width+x]; } 

    class Writer { 
     std::ofstream ofs; 
    public: 
     Writer(const char* filename) : ofs(filename, std::ios_base::out | std::ios_base::binary) {} 
     void operator() (const void* pbuf, int size) { ofs.write(static_cast<const char*>(pbuf), size); } 
     template <typename T> void operator() (const T& obj) { operator() (&obj, sizeof(obj)); } 
    }; 

    struct BIH { 
     unsigned int sz; 
     int   width, height; 
     unsigned short planes; 
     short   bits; 
     unsigned int compress, szimage; 
     int   xppm, yppm; 
     unsigned int clrused, clrimp; 
    }; 

    void Save(const char* filename) const { 
     Writer w(filename);; 
     w("BM", 2); 
     BIH bih = {sizeof(bih)}; 
     bih.width = width; 
     bih.height = -height; 
     bih.planes = 1; 
     bih.bits = 32; 
     const unsigned int headersize = sizeof(bih) + 14; 
     const int szbuf = int(sizeof(Color) * pixels.size()); 
     const unsigned int filesize = static_cast<unsigned int>(headersize + szbuf); 
     w(filesize); 
     const unsigned short z = 0; 
     w(z); 
     w(z); 
     w(headersize); 
     w(bih); 
     w(pixels.data(), szbuf); 
    } 
}; 

int main() { 
    Surface surf(600, 600); 
    Color color; 
    for(int j=0; j<12; ++j) { 
     color.g = 0; 
     for(int i=0; i<12; ++i) { 
      color.b = 255 - (color.g + color.r)/2; 
      surf.RectFill(i*50, j*50, 50, 50, color); 
      color.g += 21; 
     } 
     color.r += 21; 
    } 
    surf.Save("MyBmpFile.bmp"); 
}