Cimage类异常(m_hBitmap != 0)

一:m_hBitmap != 0这个Bug困扰我甚久,无意之中不知何故就被解决了。

重新整理代码时发现该异常的原因:

             1:文件读取路径错误

             2:Cimage 创建成全局对象时,读取一次后就不能再次读取,否则就会异常。

 

            个人理解:应该是读取一次后CImage对象地址改变,当再次赋值时地址不在是起始位置,因此出现m_hBitmap != 0,无法再次创建头文件(图像格式定义段)。

 

            解决方法:1、修改读取文件地址,注意带上正确的文件格式。

                              2、创建局部变量,每次运行到局部变量时都会自动更新CImage类,从文件头开始处理,不会出现此类异常

  

但是这个错误,给我太多的警示了。

1:C++语言对指针的管理要求很严格,在使用完成后一定要删除相应的指针,避免野指针的出现。

2:遇到问题先思考,不要第一步就先找问题的解决方案,切记根据现有的条件去思考问题的源头,如何解决,理清思路后,验证解决问题。实在解决不了的在动手查找答案,看答案也要带着问题去,这个问题的解决思路有哪些,看清楚,理解之后自己 在验证问题的解决方案。

3:可通过stackoverflow、MSDN、CSDN、GitHub等寻找解决方案。

 

CImage类,若第一次用完之后没有及时销毁指针,会导致野指针的问题,当第二次在创建类时就会出现问题。

CImage         image;

image.load("E:\\DATA.JPG");  //加载图像

//image.create(width,height,channel,alpha);      //创建图像文件

BYTE* ptr =   (BYTE*)image.GetsBits();            //获取图像文件头指针‘’

int    channel    = image.GetBpp();                      // 获取图像通道数

int       pitch       =image.GetPitch();                  //获取图像行距,正负决定图像头是从上还是从下开始读取


BYTE* buffer = new BYTE[m_nheight * m_nwidth];  //保存的图像数据初始化            

//按行拷贝m_ptr指针下的数据区域到数组
for (int i = 0; i < m_nheight; ++i)
         memcpy(buffer + i * m_nwidth,m_ptr + i * (m_Image.GetPitch()) ,m_nwidth);//注意此处的pictch要带符号

 

//保存数组到图像操作
    BYTE* data = (BYTE*)outImage.GetBits();
    
    for (int Y = 0; Y < m_nheight; Y++)
        {
        for (int X = 0; X<m_nwidth ; X++)
        {            
            //地址操作符
            *(data  + pitch * Y +  X) =  (int)buffer[X + Y * m_nwidth];
        }
    }    
    outImage.Save(savepath);

二:再次遇到Debug Assertion Failed异常。

函数:AfxMessageBox( cols.get_Count());异常,

参数设置错误的问题,不能设置为long格式。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,如果您不想使用CImage,您可以使用Windows GDI API和文件I/O函数来加载、转换和保存位图文件。以下是一个示例代码,用于将24位位图文件压缩为RLE 8位格式并保存: ```cpp // 打开位图文件 CFile file(_T("test.bmp"), CFile::modeRead | CFile::typeBinary); BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; file.Read(&bmfh, sizeof(BITMAPFILEHEADER)); file.Read(&bmih, sizeof(BITMAPINFOHEADER)); // 计算行字节数 int rowSize = (bmih.biWidth * 3 + 3) & ~3; // 分配位图数据缓冲区 BYTE* pBits = new BYTE[rowSize * bmih.biHeight]; file.Read(pBits, rowSize * bmih.biHeight); // 关闭位图文件 file.Close(); // 创建DC HDC hDC = ::GetDC(NULL); HDC hMemDC = CreateCompatibleDC(hDC); // 创建调色板 RGBQUAD pal[256]; for (int i = 0; i < 256; i++) { pal[i].rgbBlue = i; pal[i].rgbGreen = i; pal[i].rgbRed = i; } // 创建位图 BITMAPINFO bmi = { 0 }; bmi.bmiHeader = bmih; bmi.bmiHeader.biBitCount = 8; bmi.bmiHeader.biCompression = BI_RLE8; bmi.bmiHeader.biClrUsed = 256; bmi.bmiHeader.biSizeImage = rowSize * bmih.biHeight; bmi.bmiColors[0].rgbRed = 0; bmi.bmiColors[0].rgbGreen = 0; bmi.bmiColors[0].rgbBlue = 0; bmi.bmiColors[0].rgbReserved = 0; memcpy(&bmi.bmiColors[1], pal, 256 * sizeof(RGBQUAD)); HBITMAP hBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0); // 绘制位图 HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); StretchDIBits(hMemDC, 0, 0, bmih.biWidth, bmih.biHeight, 0, 0, bmih.biWidth, bmih.biHeight, pBits, &bmi, DIB_RGB_COLORS, SRCCOPY); SelectObject(hMemDC, hOldBitmap); // 保存位图 CFile outFile(_T("compressed.bmp"), CFile::modeWrite | CFile::modeCreate); outFile.Write(&bmfh, sizeof(BITMAPFILEHEADER)); outFile.Write(&bmih, sizeof(BITMAPINFOHEADER)); BYTE* pCompressedBits = NULL; DWORD dwSize = 0; GetBitmapBits(pBits, bmi.bmiHeader.biSizeImage, &pCompressedBits, &dwSize, BI_RLE8); outFile.Write(pCompressedBits, dwSize); outFile.Close(); // 释放资源 delete[] pCompressedBits; DeleteObject(hBitmap); DeleteDC(hMemDC); ::ReleaseDC(NULL, hDC); ``` 在上述代码中,我们首先打开位图文件并读取位图文件头和信息头。然后,我们计算每行的字节数,并分配位图数据缓冲区。接下来,我们创建一个DC和调色板,并使用CreateDIBSection函数创建一个新的8位位图。然后,我们使用StretchDIBits函数将原始位图绘制到新位图中。最后,我们使用GetBitmapBits函数将位图数据压缩为RLE 8位格式,并将其写入最终的位图文件中。最后,我们释放所有分配的内存。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值