发新话题
打印

[转载]我感觉最好的一段DIB代码

[转载]我感觉最好的一段DIB代码

信息来源:邪恶八进制信息安全团队(www.eviloctal.com

BOOL CBmpDlg::LoadBitmapFile(CString strFileName,CBitmap& bmp)
{
  CFile file;
  if( !file.Open(strFileName, CFile::modeRead) )
    return FALSE;

  BITMAPFILEHEADER bmfHeader;
  long nFileLen;
  CString str;

  nFileLen = file.GetLength();
  str.Format("%d",nFileLen);
  MessageBox(str);

  if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
    return FALSE;
  str.Format("%d",bmfHeader.bfType );
  MessageBox(str);
  if (bmfHeader.bfType != ((WORD)(&#39;M&#39; <<8) | &#39;B&#39;))
    return FALSE;

  HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
  if (hDIB == 0)
    return FALSE;

  if (file.ReadHuge((LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER)) !=
    nFileLen - sizeof(BITMAPFILEHEADER) )
  {
    ::GlobalFree(hDIB);
    return FALSE;
  }

  BITMAPINFO &bmInfo = *(LPBITMAPINFO) ::GlobalLock(hDIB) ;
  BITMAPINFOHEADER *pInfoHead = (BITMAPINFOHEADER  *)hDIB;

  int nHeaderSize=sizeof(BITMAPINFOHEADER);  
  BYTE *pBmpPixelBuffer=(BYTE *)&bmInfo+bmfHeader.bfOffBits - sizeof(BITMAPFILEHEADER);

  CDC dc;
  dc.CreateDC("DISPLAY",NULL,NULL,NULL);
  HBITMAP hBitmap;
  hBitmap=CreateDIBitmap(dc.m_hDC,(BITMAPINFOHEADER *)&bmInfo,CBM_INIT,(VOID *)pBmpPixelBuffer,&bmInfo,DIB_RGB_COLORS);
  bmp.Attach (hBitmap);
  
  ::GlobalUnlock (hDIB);
  ::GlobalFree(hDIB);
  return TRUE;
}
BOOL CBmpDlg::SaveBitmapFile(CString strFileName,CBitmap& bmp)
{
  BITMAP bm;
  bmp.GetBitmap (&bm);
  
  int nWidth = bm.bmWidth;
  int nHeight = bm.bmHeight;
  
  int nLineBits = bm.bmWidthBytes;
  if ((nLineBits % 8) != 0)
    nLineBits += 8 - nLineBits%8;

  int nBitCounts = nLineBits * bm.bmHeight ;

  int nBits = bm.bmBitsPixel;
  int nBitmapInfoSize = 0;

  if (nBits <= 8)
  {
    int nColors = 1 << nBits;
    int nPalUnitSize = sizeof(RGBQUAD);
    nBitmapInfoSize = sizeof(BITMAPINFOHEADER) + nPalUnitSize * nColors;  
  }
  else
    nBitmapInfoSize = sizeof(BITMAPINFOHEADER);

  BITMAPINFO*  pbmpinfo = NULL;

  pbmpinfo =(BITMAPINFO *)(new BYTE[nBitmapInfoSize]);
  ZeroMemory((void *)pbmpinfo,nBitmapInfoSize);
  
  BITMAPINFOHEADER* pInfoHead = (BITMAPINFOHEADER *)pbmpinfo;
  ZeroMemory((void *)pInfoHead,sizeof(BITMAPINFOHEADER));

  pInfoHead->biSize = sizeof(BITMAPINFOHEADER);
  pInfoHead->biBitCount = nBits;
  pInfoHead->biPlanes = 1;
  pInfoHead->biSizeImage = nBitCounts;
  pInfoHead->biCompression = BI_RGB;
  pInfoHead->biWidth = nWidth;
  pInfoHead->biHeight = nHeight;

  CDC dc;
  dc.CreateDC("DISPLAY",NULL,NULL,NULL);

  int nLx = dc.GetDeviceCaps (LOGPIXELSX);
  int nLy = dc.GetDeviceCaps (LOGPIXELSY);

  double dbInchPerMeter = 39.375;

  int nPMx = (int)((double)nLx * dbInchPerMeter);
  int nPMy = (int)((double)nLy * dbInchPerMeter);

  pInfoHead->biXPelsPerMeter = nPMx;//3780;
  pInfoHead->biYPelsPerMeter = nPMy;//3780;
  
  if (nBits <= 8)
  {
    int nColors = 1 << nBits;
    GetDIBColorTable(dc.m_hDC,0,nColors,pbmpinfo->bmiColors);
  }

  BYTE* pBits = NULL;
  
  HGLOBAL hGlobal = ::GlobalAlloc(GMEM_FIXED, nBitCounts);
  pBits = (BYTE *)::GlobalLock(hGlobal);
  ZeroMemory((void *)pBits,nBitCounts);
  
  GetDIBits(dc.m_hDC,(HBITMAP)bmp,0,nHeight,pBits,pbmpinfo,DIB_RGB_COLORS);

  BITMAPFILEHEADER  bmfHeader;
  int nFileHeadSize = sizeof(BITMAPFILEHEADER);
  
  ZeroMemory((void *)&bmfHeader,sizeof(BITMAPFILEHEADER));
  bmfHeader.bfType = 19778;//&#39;BM&#39;   ((WORD) (&#39;M&#39; << 8) | &#39;B&#39;);
  bmfHeader.bfSize = nFileHeadSize + nBitmapInfoSize + nBitCounts;
  bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + nBitmapInfoSize;

  CFile file;
  if(!file.Open (strFileName,CFile::modeCreate | CFile::modeWrite))
  {
    AfxMessageBox("Write File Error!");
    return FALSE;
  }

  file.Write (&bmfHeader,sizeof(BITMAPFILEHEADER));
  file.Write (pbmpinfo,nBitmapInfoSize);

  file.WriteHuge (pBits, nBitCounts);
  file.Close ();

  ::GlobalUnlock (hGlobal);
  ::GlobalFree (hGlobal);
  delete[] pbmpinfo;

  return TRUE;
}
void CBmpDlg::DrawBmp (CBitmap& bmp)
{
  CDC* pDC = GetDC();
  CDC memDC;
  memDC.CreateCompatibleDC (NULL);
  CBitmap* pOldBmp = memDC.SelectObject (&bmp);

  BITMAP bm;
  bmp.GetBitmap (&bm);
  int nWidth = bm.bmWidth;
  int nHeight = bm.bmHeight;

  pDC->BitBlt (0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);
  
  memDC.SelectObject (pOldBmp);
}
void CBmpDlg::OnButtonBitmap()
{
  // TODO: Add your control notification handler code here
  CFileDialog dlg(true,"*.bmp",NULL,NULL,"*.bmp|*.bmp|*.*|*.*||");
  if (dlg.DoModal()==IDOK)
  {
    if (m_pBmp != NULL)
    {
      m_pBmp->DeleteObject();
      delete m_pBmp;
      m_pBmp = NULL;
    }
   
    m_pBmp = new CBitmap;

    if (LoadBitmapFile(dlg.GetPathName(),*m_pBmp))
    {
      DrawBmp(*m_pBmp);
    }
  }  
}

void CBmpDlg::OnButtonSave()
{
  // TODO: Add your control notification handler code here
  if (m_pBmp == NULL)
    return;

  CFileDialog dlg(false,"*.bmp",NULL,NULL,"*.bmp|*.bmp||");
  if (dlg.DoModal()==IDOK)
  {
    SaveBitmapFile(dlg.GetPathName(),*m_pBmp);  
  }
}

BOOL CBmpDlg::DestroyWindow()
{
  // TODO: Add your specialized code here and/or call the base class
  if (m_pBmp != NULL)
  {
    m_pBmp->DeleteObject();
    delete m_pBmp;
    m_pBmp = NULL;
  }

  return CDialog::DestroyWindow();
}
QQ:838468959

TOP

我错了,本代码有待完善。!
QQ:838468959

TOP

发新话题