?? cdib.cpp
字號:
::DeleteObject(hBitmap); delete [] lpBMIH; ::SelectPalette(hdc, hOldPalette, FALSE); return FALSE; } else { m_dwSizeImage = lpBMIH->biSizeImage; } } else { lpBMIH->biCompression = BI_RGB; // decompress // figure the image size from the bitmap width and height DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32; if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) { dwBytes++; } dwBytes *= 4; m_dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression lpBMIH->biSizeImage = m_dwSizeImage; } // second GetDIBits call to make DIB LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage]; VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight, lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)); TRACE("dib successfully created - height = %d\n", lpBMIH->biHeight); ::DeleteObject(hBitmap); Empty(); m_nBmihAlloc = m_nImageAlloc = crtAlloc; m_lpBMIH = lpBMIH; m_lpImage = lpImage; ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); ::SelectPalette(hdc, hOldPalette, FALSE); TRACE("Compress: new palette size = %d\n", m_nColorTableEntries); return TRUE;}BOOL CDib::Read(CFile* pFile){ // 1. read file header to get size of info hdr + color table // 2. read info hdr (to get image size) and color table // 3. read image // can't use bfSize in file header // 清除DIB Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; // 嘗試讀取BMP文件 try { // 讀BMP文件頭 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); // 判斷讀取文件頭的大小是否 if(nCount != sizeof(BITMAPFILEHEADER)) { // 讀文件出錯 throw new CException; } // 判斷是否是"BM" if(bmfh.bfType != 0x4d42) { // 不是BMP文件,拋出異常 throw new CException; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = m_nImageAlloc = crtAlloc; nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); m_lpImage = (LPBYTE) new char[m_dwSizeImage]; nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only } catch(CException* pe) { AfxMessageBox("Read error"); pe->Delete(); return FALSE; } return TRUE;}BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */){ // new function reads BMP from disk and creates a DIB section // allows modification of bitmaps from disk // 1. read file header to get size of info hdr + color table // 2. read info hdr (to get image size) and color table // 3. create DIB section based on header parms // 4. read image into memory that CreateDibSection allocates Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; try { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { throw new CException; } 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); // info hdr & color table if(m_lpBMIH->biCompression != BI_RGB) { throw new CException; } 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); // image only } catch(CException* pe) { AfxMessageBox("ReadSection error"); pe->Delete(); return FALSE; } return TRUE;}BOOL CDib::Write(CFile* pFile){ BITMAPFILEHEADER bmfh; bmfh.bfType = 0x4d42; // 'BM' int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; bmfh.bfSize = 0; // bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage; // meaning of bfSize open to interpretation (bytes, words, dwords?) -- we won't use it bmfh.bfReserved1 = bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; try { pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); pFile->Write((LPVOID) m_lpBMIH, nSizeHdr); pFile->Write((LPVOID) m_lpImage, m_dwSizeImage); } catch(CException* pe) { pe->Delete(); AfxMessageBox("write error"); return FALSE; } return TRUE;}void CDib::Serialize(CArchive& ar){ DWORD dwPos; dwPos = ar.GetFile()->GetPosition(); TRACE("CDib::Serialize -- pos = %d\n", dwPos); ar.Flush(); dwPos = ar.GetFile()->GetPosition(); TRACE("CDib::Serialize -- pos = %d\n", dwPos); if(ar.IsStoring()) { Write(ar.GetFile()); } else { Read(ar.GetFile()); }}// helper functionsvoid CDib::ComputePaletteSize(int nBitCount){ if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0)) { switch(nBitCount) { case 1: m_nColorTableEntries = 2; break; case 4: m_nColorTableEntries = 16; break; case 8: m_nColorTableEntries = 256; break; case 16: case 24: case 32: m_nColorTableEntries = 0; break; default: ASSERT(FALSE); } } else { m_nColorTableEntries = m_lpBMIH->biClrUsed; } ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256)); }void CDib::ComputeMetrics(){ if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) { TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n"); throw new CException; } m_dwSizeImage = m_lpBMIH->biSizeImage; if(m_dwSizeImage == 0) { DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32; if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32) { dwBytes++; } dwBytes *= 4; m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression } m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);}void CDib::Empty(){ // this is supposed to clean up whatever is in the DIB DetachMapFile(); if(m_nBmihAlloc == crtAlloc) { delete [] m_lpBMIH; } else if(m_nBmihAlloc == heapAlloc) { ::GlobalUnlock(m_hGlobal); ::GlobalFree(m_hGlobal); } if(m_nImageAlloc == crtAlloc) { delete [] m_lpImage; } if(m_hPalette != NULL) { ::DeleteObject(m_hPalette); } if(m_hBitmap != NULL) { ::DeleteObject(m_hBitmap); } m_nBmihAlloc = m_nImageAlloc = noAlloc; m_hGlobal = NULL; m_lpBMIH = NULL; m_lpImage = NULL; m_lpvColorTable = NULL; m_nColorTableEntries = 0; m_dwSizeImage = 0; m_lpvFile = NULL; m_hMap = NULL; m_hFile = NULL; m_hBitmap = NULL; m_hPalette = NULL;}void CDib::DetachMapFile(){ if(m_hFile == NULL) { return; } ::UnmapViewOfFile(m_lpvFile); ::CloseHandle(m_hMap); ::CloseHandle(m_hFile); m_hFile = NULL;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -