是否可以编写一个将采用像素矢量的类:
struct Pixel
{
unsigned char Blue;
unsigned char Green;
unsigned char Red;
unsigned char Alpha;
};
从矢量生成BMP。我试图从一个基本的例子开始,所以我只尝试4个像素,所以这就是为什么一些标题值是硬编码的。
这是我的标题:
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);
};
这是我的意思:
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,&#34; c:\ BMP \ 4PixelBMP.txt&#34;,2,2);
答案 0 :(得分:1)
我发现这个课程可以作为参考使用。它是一个“表面”类,其成员包括宽度,高度和std::vector
(32位)像素颜色。
其Save
成员函数将表面保存为.bmp文件。它可以很容易地转换成一个带有宽度,高度和矢量的独立函数。
Writer
类包装ofstream
对象并提供Save
中使用的文件输出接口。
BIH
结构应该看起来很熟悉,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");
}