|
|
在vc 6中设置好opengl开发环境,视口的大小设置成与客户区大小一样,欲将客户区的图像保存为24位真彩色位图,源代码如下,可是存在这样的问题:
程序运行,窗口刚创建时(此时不拉动边框改变客户区大小),可以正常保存。
当最大化窗口或将最大化窗口复原,都可以正常保存。
而当人为拉动边框改变客户区大小后,保存的图像出现问题,如下:
1.图像出现错位
2.调试信息出错
Debug Error!
DAMAGE:after Normal block(#7711) at 0x04A40040.
调试信息如下:
源代码如下:
void CMySDOpenGLView::OnCaptureImage() //保存位图的消息函数
{
// TODO: Add your command handler code here
CString s("Windows Bitmap(*.bmp)|*.bmp||");
CFileDialog fd(FALSE,"bmp",0,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,s);
if(fd.DoModal()==IDOK)
{
BeginWaitCursor();
int viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
bool success = false;
DWORD nFileType=0;
if(strcmp(fd.GetFileExt(),"bmp")==0) nFileType=1;
if(nFileType==1)
{
success=m_imagecapture.CaptureGLBufferToBMP(fd.GetPathName(), //调用保存位图类的
viewport[0],viewport[1],//函数保存位图
viewport[2],viewport[3]);
}
else
{
// Invalid file extension specified.
MessageBox("WTF? Unknown file extension specified for screen capture.\n","Error",MB_OK);
}
if (!success)
{
char errorMsg[64];
if(nFileType == 0)
sprintf(errorMsg, "Specified file extension is not recognized.");
else
sprintf(errorMsg, "Could not save image file.");
MessageBox(errorMsg, "Error", MB_OK | MB_ICONERROR);
}
EndWaitCursor();
}
}
保存位图类的定义
class CImageCapture{
public:
CImageCapture();
virtual ~CImageCapture();
bool CaptureGLBufferToBMP(CString filename, int x, int y,
int width, int height);
int WriteBitmapFile(CString filename, int width, int height,
unsigned char *imageData);
};
CImageCapture::CImageCapture()
{
}
CImageCapture::~CImageCapture()
{
}
bool CImageCapture::CaptureGLBufferToBMP(CString filename,
int x, int y,
int width, int height)
{
void* imageData = malloc(width*height*3);// allocate memory for the imageData
memset(imageData, 0, width*height*3); // clear imageData memory contents
// read the image data from the window
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char*)imageData);
// write the image data to a file
WriteBitmapFile(filename, width, height, (unsigned char*)imageData);
// free the image data memory
free(imageData);
return true;
}
// WriteBitmapFile()
// desc: takes image data and saves it into a 24-bit RGB .BMP file
// with width X height dimensions
int CImageCapture::WriteBitmapFile(CString filename, int width, int height, unsigned char *imageData)
{
FILE *filePtr; // file pointer
BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header
unsigned int imageIdx; // used for swapping RGB->BGR
unsigned char tempRGB; // used for swapping
// open file for writing binary mode
filePtr = fopen(filename, "wb");
if (!filePtr)
return 0;
// define the bitmap file header
bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(4*((width*24+31)/32) * height);
bitmapFileHeader.bfType = 0x4D42;
bitmapFileHeader.bfReserved1 = 0;
bitmapFileHeader.bfReserved2 = 0;
bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// define the bitmap information header
bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader.biPlanes = 1;
bitmapInfoHeader.biBitCount = 24; // 24-bit
bitmapInfoHeader.biCompression = BI_RGB; // no compression
bitmapInfoHeader.biSizeImage = 4*((width*24+31)/32) * height; // width * height * (RGB bytes)
bitmapInfoHeader.biXPelsPerMeter = 0;
bitmapInfoHeader.biYPelsPerMeter = 0;
bitmapInfoHeader.biClrUsed = 0;
bitmapInfoHeader.biClrImportant = 0;
bitmapInfoHeader.biWidth = width; // bitmap width
bitmapInfoHeader.biHeight = height; // bitmap height
// switch the image data from RGB to BGR
for (imageIdx = 0; imageIdx < bitmapInfoHeader.biSizeImage; imageIdx+=3)
{
tempRGB = imageData[imageIdx];
imageData[imageIdx] = imageData[imageIdx + 2];
imageData[imageIdx + 2] = tempRGB;
}
//add empty Byte to every row, if this row cannot be divided exactly by 4.
unsigned char *imageDataAfterAdding =(unsigned char *) malloc(4*((width*24+31)/32) * height);
memset(imageDataAfterAdding, 0, 4*((width*24+31)/32) * height);
for(int k=0; k<height; k++){
for(int i=0; i<width*3; i++){
imageDataAfterAdding[k*width*3+i+k*(4*((width*24+31)/32)- width*3)]= imageData[k*width*3+i];
}
}
// write the bitmap file header
fwrite(&bitmapFileHeader, 1, sizeof(BITMAPFILEHEADER), filePtr);
// write the bitmap info header
fwrite(&bitmapInfoHeader, 1, sizeof(BITMAPINFOHEADER), filePtr);
// write the image data
fwrite(imageDataAfterAdding, 1, bitmapInfoHeader.biSizeImage, filePtr);
// close our file
fclose(filePtr);
free(imageDataAfterAdding);
return 1;
}
不知道错在什么地方,请各位高手不吝赐教,不胜感激,谢谢!
[code][/code] [em7] [em7] |
|