【发布时间】:2015-10-23 14:53:37
【问题描述】:
我有以下代码来创建位图:
//raw data
PBYTE firstPixel = (PBYTE)((PBYTE)AnsiBdbRecord) + sizeof(WINBIO_BDB_ANSI_381_RECORD);
// declare other bmp structures
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
RGBQUAD rq[256];
// create the grayscale palette
for (int i = 0; i<256; i++)
{
rq[i].rgbBlue = i;
rq[i].rgbGreen = i;
rq[i].rgbRed = i;
rq[i].rgbReserved = 0;
}
//RGBQUAD bl = { 0,0,0,0 }; //black color
//RGBQUAD wh = { 0xff,0xff,0xff,0xff }; // white color
// andinitialize them to zero
memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
memset(&info, 0, sizeof(BITMAPINFOHEADER));
// fill the fileheader with data
bmfh.bfType = 0x4d42; // 0x4d42 = 'BM'
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // + padding;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD);
// fill the infoheader
info.biSize = sizeof(BITMAPINFOHEADER);
info.biWidth = Width;
info.biHeight = Height;
info.biPlanes = 1; // we only have one bitplane
info.biBitCount = PixelDepth; // RGB mode is 24 bits
info.biCompression = BI_RGB;
info.biSizeImage = 0; // can be 0 for 24 bit images
info.biXPelsPerMeter = 0x0ec4; // paint and PSP use this values
info.biYPelsPerMeter = 0x0ec4;
info.biClrUsed = 0; // we are in RGB mode and have no palette
info.biClrImportant = 0; // all colors are importantenter code here
我保存如下:
HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == NULL)
{
DWORD dw = GetLastError();
CloseHandle(file);
}
// write file header
if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false)
{
DWORD dw = GetLastError();
CloseHandle(file);
}
// write infoheader
if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false)
{
DWORD dw = GetLastError();
CloseHandle(file);
}
//write rgbquad for black
if (WriteFile(file, &rq, sizeof(rq), &bwritten, NULL) == false)
{
DWORD dw = GetLastError();
CloseHandle(file);
}
// write image data
if (WriteFile(file, &firstPixel[0], imageSize, &bwritten, NULL) == false)
{
DWORD dw = GetLastError();
CloseHandle(file);
}
// and clean up
CloseHandle(file);
我认为以上是保存位图图像的标准方法。但是,我不希望保存图像,而是希望它以 BASE64 的形式提供并在 HTTP Post 中传递。因此,这个问题与this one 有关,但是我在将 bmp 结构转换为 BASE64 时遇到了很多困难。我从here 获取了BASE64 编码器,但我不知道如何将BMPFILEHEADER、BMPINFOHEADER、RGBQUAD 和原始数据结构作为参数传递给BASE64 编码器。
关于如何结合我收集的信息有什么想法或建议吗?
更新
感谢 Roman Pustylnikov,我已经走得更远了: 我正在创建一个这样的结构:
struct ImageBuffer
{
BITMAPFILEHEADER bfheader;
BITMAPINFOHEADER infobmp;
RGBQUAD rgb[256];
PBYTE bitmap;
};
填写如下:
ImageBuffer capture;
capture.bfheader = bmfh;
capture.infobmp = info;
// create the grayscale palette
for (int i = 0; i<256; i++)
{
capture.rgb[i].rgbBlue = i;
capture.rgb[i].rgbGreen = i;
capture.rgb[i].rgbRed = i;
capture.rgb[i].rgbReserved = 0;
}
capture.bitmap = firstPixel;
并将其转换如下:
int totalSize = sizeof(capture.bfheader) + sizeof(capture.infobmp) + sizeof(capture.rgb) + imageSize;
std::string encodedImage = base64_encode(reinterpret_cast<const unsigned char*>(&capture), totalSize);
但是,它给了我一个无效的位图。此外,当我从磁盘加载位图(使用 writefile 生成的位图)时,我得到一个不同的 base64 字符串。我使用 C# 代码比较两个 Base64 字符串:
// generated base64 string
string test = "Put base64string generated from C++ here";
byte[] imageBytes = Convert.FromBase64String(test);
// generate the same string based on the actual bmp
byte[] data = File.ReadAllBytes(@"c:\successtest.bmp");
string original = Convert.ToBase64String(data);
更新二:解决方案
可以在 Roman Pustylnikov 答案的最新更新中找到解决方案。
【问题讨论】:
标签: c++ bitmap biometrics