je le code suivant pour créer une image bitmap:C++ bitmap à base64
//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
Et je l'enregistre comme suit:
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);
Je pense que ce qui précède est le moyen standard d'enregistrement d'images bitmap . Cependant, au lieu de sauvegarder l'image, je veux qu'elle soit disponible en tant que BASE64 et transmettez-la dans un message HTTP. Par conséquent, cette question concerne this one, mais j'ai beaucoup de difficultés à convertir la structure bmp en BASE64. J'ai pris l'encodeur BASE64 de here, mais je n'ai aucune idée comment passer la structure de données BMPFILEHEADER, BMPINFOHEADER, RGBQUAD, et de données brutes en tant que paramètre à l'encodeur BASE64.
Des idées ou des conseils sur la façon de combiner les informations que j'ai recueillies?
MISE À JOUR
Merci à Roman Pustylnikov, j'ai obtenu un peu plus loin déjà: Je crée une structure comme ceci:
struct ImageBuffer
{
BITMAPFILEHEADER bfheader;
BITMAPINFOHEADER infobmp;
RGBQUAD rgb[256];
PBYTE bitmap;
};
Remplissez comme suit:
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;
Et le convertir comme suit:
int totalSize = sizeof(capture.bfheader) + sizeof(capture.infobmp) + sizeof(capture.rgb) + imageSize;
std::string encodedImage = base64_encode(reinterpret_cast<const unsigned char*>(&capture), totalSize);
Cependant, il me donne un bitmap invalide. De plus, lorsque je charge le bitmap à partir du disque (celui qui est généré avec writefile), j'obtiens une chaîne base64 différente. J'utilise le code C# pour comparer les deux chaînes 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);
MISE À JOUR DEUX: solution
La solution peut être trouvée dans la dernière mise à jour de la réponse de Roman Pustylnikov.
Cela semble aller dans la bonne direction. Je devrais concaténer le bitmapfileheader, infoheader, RGBQuad et rawdata ensemble d'abord alors? – Michael
Je crois que vous pouvez utiliser la structure et concaténer les en-têtes avec l'image comme résultat. Puisque l'en-tête doit toujours être de la longueur constante (comme la longueur des en-têtes combinés et encodés), le reste sera la donnée d'image. Devrait être facile à décoder. J'ai mis à jour la réponse. –
Je pense que vous êtes proche, même si cela ne fonctionne toujours pas. Voir la mise à jour de ma question pour plus de détails. – Michael