网站建设策划案模板,网站建站及维护,三明市住房与建设局网站,做网站的集团使用多文档编程 也可以使用单文档编程 建立一个DIB图像的显示类 ImageDib 成员变量#xff1a; 4个指针#xff1a; LPBYTE m_lpDib; //指向DIB的指针 LPBITMAPINFOHEADER m_lpBmpInfoHead; //图像信息头指针 LPRGBQUAD m_lpColorTable; //图像颜色表指针 … 使用多文档编程 也可以使用单文档编程 建立一个DIB图像的显示类 ImageDib 成员变量 4个指针 LPBYTE m_lpDib; //指向DIB的指针 LPBITMAPINFOHEADER m_lpBmpInfoHead; //图像信息头指针 LPRGBQUAD m_lpColorTable; //图像颜色表指针 unsigned char * m_pImgData; //图像数据指针 4个普通变量存放图像的参数 int m_imgWidth; //图像的宽像素为单位 int m_imgHeight; //图像的高像素为单位 int m_nBitCount; //每像素占的位数 int m_nColorTableLength; //颜色表长度多少个表项 1个句柄 HPALETTE m_hPalette; //逻辑调色板句柄 成员函数 带参数构造函数 ImageDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData); //带参数的构造函数 View Code ImageDib::ImageDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,unsigned char *pImgData)
{//如果没有位图数据传入我们认为是空的DIB此时不分配DIB内存if(pImgDataNULL){m_lpDibNULL;m_lpColorTableNULL;m_pImgDataNULL; // 图像数据m_lpBmpInfoHeadNULL; // 图像信息头m_hPalette NULL;}else{//如果有位图数据传入//可以通过调用ReplaceDib()来实现 代码一样的//ReplaceDib(size,nBitCount,lpColorTable,pImgData);//图像的宽、高、每像素位数等成员变量赋值m_imgWidthsize.cx;m_imgHeightsize.cy;m_nBitCountnBitCount;//根据每像素位数计算颜色表长度m_nColorTableLengthComputeColorTabalLength(nBitCount);//每行像素所占字节数必须扩展成4的倍数int lineByte(m_imgWidth*nBitCount/83)/4*4;//位图数据缓冲区的大小图像大小int imgBufSizem_imgHeight*lineByte;//为m_lpDib一次性分配内存生成DIB结构m_lpDibnew BYTE [sizeof(BITMAPINFOHEADER) sizeof(RGBQUAD) * m_nColorTableLengthimgBufSize];//填写BITMAPINFOHEADER结构m_lpBmpInfoHead (LPBITMAPINFOHEADER) m_lpDib;m_lpBmpInfoHead-biSize sizeof(BITMAPINFOHEADER);m_lpBmpInfoHead-biWidth m_imgWidth;m_lpBmpInfoHead-biHeight m_imgHeight;m_lpBmpInfoHead-biPlanes 1;m_lpBmpInfoHead-biBitCount m_nBitCount;m_lpBmpInfoHead-biCompression BI_RGB;m_lpBmpInfoHead-biSizeImage 0;m_lpBmpInfoHead-biXPelsPerMeter 0;m_lpBmpInfoHead-biYPelsPerMeter 0;m_lpBmpInfoHead-biClrUsed m_nColorTableLength;m_lpBmpInfoHead-biClrImportant m_nColorTableLength;//调色板句柄初始化为空有颜色表时MakePalette()函数要生成新的调色板m_hPalette NULL;//如果有颜色表则将颜色表拷贝进DIB的颜色表位置if(m_nColorTableLength!0){//m_lpColorTable指向DIB颜色表的起始位置m_lpColorTable(LPRGBQUAD)(m_lpDibsizeof(BITMAPINFOHEADER));//颜色表拷贝memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) * m_nColorTableLength);//创建逻辑调色板MakePalette();}//m_pImgData指向DIB位图数据起始位置m_pImgData (LPBYTE)m_lpDibsizeof(BITMAPINFOHEADER)sizeof(RGBQUAD) * m_nColorTableLength;//拷贝图像数据进DIB位图数据区memcpy(m_pImgData,pImgData,imgBufSize);}} 读文件 BOOL Read(LPCTSTR lpszPathName); //DIB读函数 View Code BOOL ImageDib::Read(LPCTSTR lpszPathName)
{//读模式打开图像文件CFile file;if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite))return FALSE;BITMAPFILEHEADER bmfh;//读取BITMAPFILEHEADER结构到变量bmfh中int nCountfile.Read((LPVOID) bmfh, sizeof(BITMAPFILEHEADER));//为m_lpDib分配空间读取DIB进内存if(m_lpDib!NULL) delete []m_lpDib;m_lpDibnew BYTE[file.GetLength() -sizeof(BITMAPFILEHEADER)];file.Read(m_lpDib, file.GetLength() -sizeof(BITMAPFILEHEADER));//m_lpBmpInfoHead位置为m_lpDib起始位置m_lpBmpInfoHead (LPBITMAPINFOHEADER)m_lpDib;//为成员变量赋值m_imgWidthm_lpBmpInfoHead-biWidth;m_imgHeightm_lpBmpInfoHead-biHeight;m_nBitCountm_lpBmpInfoHead-biBitCount; //计算颜色表长度m_nColorTableLength ComputeColorTabalLength(m_lpBmpInfoHead-biBitCount);//如果有颜色表,则创建逻辑调色板m_hPalette NULL;if(m_nColorTableLength!0){m_lpColorTable(LPRGBQUAD)(m_lpDibsizeof(BITMAPINFOHEADER));MakePalette();}//m_pImgData指向DIB的位图数据起始位置m_pImgData (LPBYTE)m_lpDibsizeof(BITMAPINFOHEADER) sizeof(RGBQUAD) * m_nColorTableLength;return TRUE;
} 写文件 BOOL Write(LPCTSTR lpszPathName); //DIB写函数 View Code BOOL ImageDib::Write(LPCTSTR lpszPathName)
{//写模式打开文件CFile file;if (!file.Open(lpszPathName, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive))return FALSE;//填写文件头结构BITMAPFILEHEADER bmfh;bmfh.bfType 0x4d42; // BMbmfh.bfSize 0;bmfh.bfReserved1 bmfh.bfReserved2 0;bmfh.bfOffBits sizeof(BITMAPFILEHEADER) sizeof(BITMAPINFOHEADER) sizeof(RGBQUAD) * m_nColorTableLength; try {//文件头结构写进文件file.Write((LPVOID) bmfh, sizeof(BITMAPFILEHEADER));//文件信息头结构写进文件file.Write(m_lpBmpInfoHead, sizeof(BITMAPINFOHEADER));//如果有颜色表的话颜色表写进文件if(m_nColorTableLength!0)file.Write(m_lpColorTable, sizeof(RGBQUAD) * m_nColorTableLength);//位图数据写进文件int imgBufSize(m_imgWidth*m_nBitCount/83)/4*4*m_imgHeight;file.Write(m_pImgData, imgBufSize);}catch(CException* pe) {pe-Delete();AfxMessageBox(write error);return FALSE;}//函数返回return TRUE;
} 计算颜色表长度 int ComputeColorTabalLength(int nBitCount); //计算颜色表的长度 View Code int ImageDib::ComputeColorTabalLength(int nBitCount)
{int colorTableLength;switch(nBitCount) {case 1:colorTableLength 2;break;case 4:colorTableLength 16;break;case 8:colorTableLength 256;break;case 16:case 24:case 32:colorTableLength 0;break;default:ASSERT(FALSE);}ASSERT((colorTableLength 0) (colorTableLength 256)); return colorTableLength;
} 创建逻辑调色板 void MakePalette(); //创建逻辑调色板 View Code void ImageDib::MakePalette()
{//如果颜色表长度为0则不创建逻辑调色板if(m_nColorTableLength 0) return;//删除旧的逻辑调色板句柄if(m_hPalette ! NULL) ::DeleteObject(m_hPalette);//申请空间根据颜色表生成LOGPALETTE结构LPLOGPALETTE pLogPal (LPLOGPALETTE) new char[2 * sizeof(WORD) m_nColorTableLength * sizeof(PALETTEENTRY)];pLogPal-palVersion 0x300;pLogPal-palNumEntries m_nColorTableLength;LPRGBQUAD m_lpDibQuad (LPRGBQUAD) m_lpColorTable;for(int i 0; i m_nColorTableLength; i) {pLogPal-palPalEntry[i].peRed m_lpDibQuad-rgbRed;pLogPal-palPalEntry[i].peGreen m_lpDibQuad-rgbGreen;pLogPal-palPalEntry[i].peBlue m_lpDibQuad-rgbBlue;pLogPal-palPalEntry[i].peFlags 0;m_lpDibQuad;} //创建逻辑调色板m_hPalette ::CreatePalette(pLogPal);//释放空间delete pLogPal;
} 读取图像维数 CSize GetDimensions(); //读取图像维数 View Code CSize ImageDib::GetDimensions()
{ if(m_lpDib NULL) return CSize(0, 0);return CSize(m_imgWidth, m_imgHeight);
} 图像绘制 BOOL Draw(CDC* pDC, CPoint origin, CSize size); //图像绘制 View Code BOOL ImageDib::Draw(CDC* pDC, CPoint origin, CSize size)
{HPALETTE hOldPalNULL; //旧的调色板句柄if(m_lpDib NULL) return FALSE; //如果DIB为空则返回0if(m_hPalette ! NULL) { //如果DIB有调色板//将调色板选进设备环境中hOldPal::SelectPalette(pDC-GetSafeHdc(), m_hPalette, TRUE);pDC-RealizePalette(); }pDC-SetStretchBltMode(COLORONCOLOR); //设置位图伸缩模式//将DIB在pDC所指向的设备上进行显示::StretchDIBits(pDC-GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,0, 0, m_lpBmpInfoHead-biWidth, m_lpBmpInfoHead-biHeight,m_pImgData,(LPBITMAPINFO) m_lpBmpInfoHead, DIB_RGB_COLORS, SRCCOPY);if(hOldPal!NULL) //恢复旧的调色板::SelectPalette(pDC-GetSafeHdc(), hOldPal, TRUE);return TRUE;
} 用新的数据替代DIBvoid ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData); //用新的数据替换DIB View Code void ImageDib::ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,unsigned char *pImgData)
{ //释放原DIB所占空间Empty();//成员变量赋值m_imgWidthsize.cx;m_imgHeightsize.cy;m_nBitCountnBitCount;//计算颜色表的长度m_nColorTableLengthComputeColorTabalLength(nBitCount);//每行像素所占字节数扩展成4的倍数int lineByte(m_imgWidth*nBitCount/83)/4*4;//位图数据的大小int imgBufSizem_imgHeight*lineByte;//为m_lpDib重新分配空间以存放新的DIBm_lpDibnew BYTE [sizeof(BITMAPINFOHEADER) sizeof(RGBQUAD) * m_nColorTableLengthimgBufSize];//填写位图信息头BITMAPINFOHEADER结构m_lpBmpInfoHead (LPBITMAPINFOHEADER) m_lpDib;m_lpBmpInfoHead-biSize sizeof(BITMAPINFOHEADER);m_lpBmpInfoHead-biWidth m_imgWidth;m_lpBmpInfoHead-biHeight m_imgHeight;m_lpBmpInfoHead-biPlanes 1;m_lpBmpInfoHead-biBitCount m_nBitCount;m_lpBmpInfoHead-biCompression BI_RGB;m_lpBmpInfoHead-biSizeImage 0;m_lpBmpInfoHead-biXPelsPerMeter 0;m_lpBmpInfoHead-biYPelsPerMeter 0;m_lpBmpInfoHead-biClrUsed m_nColorTableLength;m_lpBmpInfoHead-biClrImportant m_nColorTableLength;//调色板置空m_hPalette NULL;//如果有颜色表则将颜色表拷贝至新生成的DIB并创建逻辑调色板if(m_nColorTableLength!0){m_lpColorTable(LPRGBQUAD)(m_lpDibsizeof(BITMAPINFOHEADER));memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) * m_nColorTableLength);MakePalette();}//m_pImgData指向DIB的位图数据起始位置m_pImgData (LPBYTE)m_lpDibsizeof(BITMAPINFOHEADER)sizeof(RGBQUAD) * m_nColorTableLength;//将新位图数据拷贝至新的DIB中memcpy(m_pImgData,pImgData,imgBufSize);
} 清理空间函数 void Empty(); //清理空间 View Code void ImageDib::Empty()
{//释放DIB内存缓冲区if(m_lpDib ! NULL) {delete [] m_lpDib;m_lpDibNULL;m_lpColorTableNULL;m_pImgDataNULL; m_lpBmpInfoHeadNULL;}//释放逻辑调色板缓冲区if(m_hPalette ! NULL){::DeleteObject(m_hPalette);m_hPalette NULL;}
} 默认构造函数 View Code ImageDib::ImageDib()
{m_lpDibNULL;//初始化m_lpDib为空。m_lpColorTableNULL; //颜色表指针为空m_pImgDataNULL; //图像数据指针为空m_lpBmpInfoHeadNULL; //图像信息头指针为空m_hPalette NULL; //调色板为空
} 默认析构函数 View Code ImageDib::~ImageDib()
{//释放m_lpDib所指向的内存缓冲区if(m_lpDib ! NULL) delete [] m_lpDib; //如果有调色板释放调色板缓冲区if(m_hPalette ! NULL)::DeleteObject(m_hPalette);
} 编写好ImageDib类后在doc文件类中添加一个ImageDib类的指针在构造函数中new出来在析构函数中delete然后重写OnOpenDocument()函数 在其中调用读函数打开图像 在View类的OnDraw()中调用ImageDib类的绘制函数 将图像绘制在打开的新文件中 总结编程的关键在于几个指针的赋值指向DIB的指针的分配空间位图信息头等结构的赋值等等。 只要记住 BMP文件位图头文件位图信息头颜色表数据块 等号后边的内容按顺序写的 DIB位图信息头颜色表数据块 位图信息位图信息头颜色表 这些图像文件的存储组成及顺序万事OK 转载于:https://www.cnblogs.com/Anidot/archive/2012/04/23/2466495.html