BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */) { // nueva función que lee el BMP del disco y crea una sección de DIB // permite la modificación de mapas de bits de disco // 1. leer cabecera de archivo para obtener el tamaño de la cabecera de info + tabla de colores // 2. leer cabecera de info (para obtener el tamaño de la imagen) y la tabla de colores // 3. crear sección de DIB en función de los parámetros de la cabecera // 4. leer la imagen en memoria que asigna CreateDibSection Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; try { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { //throw new CException; throw new std::exception; } if(bmfh.bfType != 0x4d42) { //throw new CException; throw new std::exception; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = crtAlloc; m_nImageAlloc = noAlloc; nCount = pFile->Read(m_lpBMIH, nSize); // cabecera de info y tabla de colores if(m_lpBMIH->biCompression != BI_RGB) { //throw new CException; throw new std::exception; } ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); UsePalette(pDC); m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0); ASSERT(m_lpImage != NULL); nCount = pFile->Read(m_lpImage, m_dwSizeImage); // solo la imagen } catch(CException* pe) { AfxMessageBox(_T("Error de ReadSection")); pe->Delete(); return FALSE; } return TRUE; }
/************************************************************************* * * \函数名称: * ReadSection() * * \输入参数: * CFile* pFile - 指向CFile对象的指针;对应的磁盘 * - 文件中包含DIB * CDC* pDC - 设备上下文指针 * * \返回值: * BOOL - 如果成功,则返回TRUE * * \说明: * 该函数从BMP文件中读取信息头,调用CreateDIBSection来分配图象内存,然后将 * 图象从该文件读入刚才分配的内存。如果你想从磁盘读取一个DIB,然后通过调用 * GDI函数编辑它的话,可以使用该函数。你可以用Write或CopyToMapFile将DIB写 * 回到磁盘 * ************************************************************************ */ BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */) { // 释放已经分配的内存 Empty(); // 临时变量 int nCount, nSize; BITMAPFILEHEADER bmfh; // 从文件中读取数据 try { // 读取文件头 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { throw new CException; } // 如果文件类型部位"BM",则返回并进行相应错误处理 if(bmfh.bfType != 0x4d42) { throw new CException; } // 计算信息头加上调色板的大小,并分配相应的内存 nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = crtAlloc; m_nImageAlloc = noAlloc; // 读取信息头和调色板 nCount = pFile->Read(m_lpBMIH, nSize); // 如果图象为压缩格式,则不进行后续处理 if(m_lpBMIH->biCompression != BI_RGB) { throw new CException; } // 计算图象数据大小并设置调色板指针 ComputeMetrics(); // 计算调色板的表项数 ComputePaletteSize(m_lpBMIH->biBitCount); // 如果DIB中存在调色板,则创建一个Windows调色板 MakePalette(); // 将CDib对象的逻辑调色板选入设备上下文 UsePalette(pDC); // 创建一个DIB段,并分配图象内存 m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0); ASSERT(m_lpImage != NULL); // 从文件中读取图象数据 nCount = pFile->Read(m_lpImage, m_dwSizeImage); } // 错误处理 catch(CException* pe) { AfxMessageBox("ReadSection error"); pe->Delete(); return FALSE; } return TRUE; }