要用C语言实现bmp图像底层数据读写与创建,需要对bmp图像文件格式非常了解,如果不太熟悉bmp图像文件格式请先移步bmp图像文件格式超详解
创建bmp图像文件的方式有很多,比如用halcon,用qt,这些都是把已经画好的图像保存为bmp图像,有时候我们需要自己实现bmp图像底层数据的写入,进而创建一张bmp图像,比如我之前业务上的一个需求,喷印机喷头需要识别2bit图像,但是现有的图像处理库比如halcon,opencv,qt都无法直接生成一张2bit图像,这就需要我们自己创建一个文件,然后把bmp图像的底层数据写进去。
创建方式如下:文章来源:https://www.toymoban.com/news/detail-783476.html
//1.定义2位深图像调色板
colors2[0].rgbBlue = 0; // 黑色
colors2[0].rgbGreen = 0;
colors2[0].rgbRed = 0;
colors2[0].rgbReserved = 0;
colors2[1].rgbBlue = 96; // 灰色1
colors2[1].rgbGreen = 96;
colors2[1].rgbRed = 96;
colors2[1].rgbReserved = 0;
colors2[2].rgbBlue = 48; // 灰色2
colors2[2].rgbGreen = 48;
colors2[2].rgbRed = 48;
colors2[2].rgbReserved = 0;
colors2[3].rgbBlue = 255; // 白色
colors2[3].rgbGreen = 255;
colors2[3].rgbRed = 255;
colors2[3].rgbReserved = 0;
//2.创建并设置BMP文件头和信息头
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
//2.1设置文件头基本信息
fileHeader.bfType = 0x4D42;
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (pixelWidth * 2 + 31) / 32 * 4 * pixelHeight;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(colors2);
//2.2设置信息头基本信息
infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = pixelWidth;
infoHeader.biHeight = pixelHeight;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 2;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
//3.写入文件头、信息头和调色板
ofstream image2bit = ofstream("D:/vsdata/0100.bmp", ios::binary);
if (!image2bit.is_open())
{
qDebug() << "generate2bit: file of 2bit open failed";
return false;
}
image2bit.write(reinterpret_cast<const char*>(&fileHeader), sizeof(BITMAPFILEHEADER));
image2bit.write(reinterpret_cast<const char*>(&infoHeader), sizeof(BITMAPINFOHEADER));
image2bit.write(reinterpret_cast<const char*>(&colors2), sizeof(colors2));
//4.根据业务需求写入图像数据
//5.写入完毕,关掉文件
image2bit.close();
那如何读取BMP图像文件的底层数据呢?文章来源地址https://www.toymoban.com/news/detail-783476.html
//先打开一个bmp图像文件,这是一个8bit的图像文件
ifstream inputFile(“D:vsdata/8bit.bmp”, std::ios::binary | std::ios::in);
int acturalBytesPerLine_eight = pixelWidth;//每行像素有效字节数
int bytesPerLine_eight = (pixelWidth * 8 + 31) / 32 * 4;//考虑了内存对齐的每行字节数,即总字节数>=每行像素有效字节数
vector<unsigned char*>allLineData_8bit;//存储读取后的8位深图像数据
//如果文件打开失败,输出调试信息
if(!inputFile.is_open())
{
cout << "generate1bit:8 bit file open error";
}
inputFile.seekg(1078, std::ios::beg); //定位到第一行的起始位置,1078是偏移量=文件头+信息头+调色板大小
for (int i = 0; i < pixelHeight; i++)
{
//遍历每一行
unsigned char* lineData = nullptr;
try
{
lineData = new unsigned char[bytesPerLine_eight];//存储8位深图像的行有效数据部分
}
catch (bad_alloc& my_bad_alloc)
{
qDebug() << "generate1Bit:lineData bad_alloc:" << my_bad_alloc.what();
return;
}
//注意,这里read的第二个参数是acturalBytesPerLine_eight,因为只读取行有效字节数据,填充的部分不用读取
inputFile.read((char*)lineData, acturalBytesPerLine_eight);
allLineData_8bit.push_back(lineData);
}
inputFile.close();
到了这里,关于C语言实现bmp图像底层数据写入与创建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!