J'écris actuellement une fonction de capture d'écran BMP pour un framework OpenGL et je suis confronté à un problème étrange d'écriture des données. Les données importées de glReadPixels
avec les en-têtes BMP sont correctes, mais il semble que l'opération ofstream.write
insère des valeurs non valables au hasard.Création BMP - Corruption C++ ofstream en sortie
Des extraits d'une image BMP correcte de l'image (créée par Paint) et de celle de ma fonction sont affichés, mettant en évidence les octets incorrects. La ligne correcte sera toujours la première.
Row 0x08C
3B 0D 4A 3A 0A 48 38 08 45 36
3B 0D 4A 3A 0D 0A 48 38 08 45
^^
Row 0x0DC (déjà éteint par une, à ce stade)
3E 2F 07 3D 2E 0A 3F 31 0E 44
07 3E 2F 07 3D 2E 0D 0A 3F 31
^^
Row 0x0E68 (très rangée suivante, et en dehors par deux)
35 13 48 3A 10 44 36 0A 3F 31
0E 44 35 13 48 3A 10 44 36 0D
^^
Donc, il semble un modèle où la valeur non valide est toujours 0x0D
et il est inséré devant un 0x0A
. Je n'ai aucune idée pourquoi cela pourrait se produire, car j'ai confirmé que les en-têtes et les données de glReadPixels
sont tous corrects. Le code de la méthode suit.
bool captureScreen(const char* name, unsigned originX, unsigned originY, unsigned width, unsigned height)
{
//...
GLubyte* imageData = new GLubyte[ width * height * 3 ];
glReadPixels(originX, originY, width, height, GL_BGR, GL_UNSIGNED_BYTE, imageData);
//...
captureAsBMP(imageData, width, height, path.c_str());
//...
}
bool captureAsBMP(GLubyte* data, GLuint width, GLuint height, const char* path)
{
std::ofstream stream(path, std::ios_base::out);
if(!stream.is_open())
return false;
unsigned char BMPHeader[ 14 ] = { /* cut for brevity */ };
unsigned char DIBHeader[ 40 ] = { /* cut for brevity */ };
unsigned char padding[ 4 ] = { 0x00, 0x00, 0x00, 0x00 };
unsigned int paddingLength = 4 - ((width * 3) % 4);
paddingLength = (paddingLength == 4 ? 0 : paddingLength);
long fileSize = (width * height * 3) + (paddingLength * height) + 54;
long dataSize = fileSize - 54;
memcpy(&BMPHeader[ 2 ], &fileSize, sizeof(long));
memcpy(&DIBHeader[ 4 ], &width, sizeof(unsigned int));
memcpy(&DIBHeader[ 8 ], &height, sizeof(unsigned int));
memcpy(&DIBHeader[ 20 ], &dataSize, sizeof(long));
stream.write(reinterpret_cast< char* >(BMPHeader), 14);
stream.write(reinterpret_cast< char* >(DIBHeader), 40);
unsigned pos = 0;
// Write out one row at a time
for(int i = 0; i < height; i++)
{
stream.write(reinterpret_cast< char* >(&data[ pos ]), (width * 3));
// Is there padding that needs to be added?
if(paddingLength != 0)
stream.write(reinterpret_cast< char* >(padding), paddingLength);
// Update where we are in data
pos += width * 3;
}
stream.close();
return true;
}
A noter également, l'image en question est un 800x600 et si cette erreur se produit lors de la première écriture de flux des lignes, avant de rembourrage et pos
incrémenter.
Enfin, comment il devrait apparaître: http://imgur.com/oziid
et comment il le: http://imgur.com/SrXgA (re-enregistré dans la peinture comme Imgur plaignit corrompu bien sûr)
C'est toujours quelque chose de simple, n'est-ce pas? Merci pour l'aide. Je suppose que j'avais juste besoin d'une nouvelle paire d'yeux. – ssell