上篇幾個函數

聲明:以下函數均不爲自己所寫,所以僅供觀看,不過確實能用,而且沒有錯誤

轉換函數是本人原創,裏面調用了這裏的函數

 

//return value:
// 0 OK
// 1 failed
BOOL CDib::OpenFile(const CString &szFileName)
{
 CFile f;
 if (!f.Open(szFileName,CFile::modeRead))
 {
#ifdef _DEBUG
  AfxMessageBox("Can't open file:/n"+szFileName,MB_OK);
#endif 
  return 1;
 }

 //讀入位圖信息
 void *hbi=ReadBitmapHead(&f);
 if (!hbi)
     return 1;

 //讀入位圖數據
    BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hbi;
 int dwsize=lpbi->biSizeImage;
    int dwlen=lpbi->biSize+PaletteSize(*lpbi)+lpbi->biSizeImage;
 void *h=realloc(hbi,dwlen);
 if (!h)
 {
    free(hbi);
    return 1;
 }
 hbi=h;
 lpbi=(BITMAPINFOHEADER *)hbi;
// dwsize=lpbi->biSizeImage;
//    dwlen=lpbi->biSize+PaletteSize(*lpbi)+lpbi->biSizeImage;
UINT temp = PaletteSize(*lpbi);
 f.Read((void *)((BYTE*)lpbi+lpbi->biSize+temp),dwsize);

 hdib=hbi;
    hbm=BitmapFromDib((void *)hdib);
 if (!hbm)
 {
  free(hdib);
  hdib=NULL;
  return 1;
 }

 strFileName = szFileName;
 return 0;
}


HBITMAP CDib::BitmapFromDib (void *dib)
{
  LPBITMAPINFOHEADER  lpbi;
  HDC                 hdc;
  HBITMAP             hbm;


  if(!hdib)
     return(NULL);

  lpbi = (LPBITMAPINFOHEADER)hdib;

  WORD  wPaletteSize;
  hdc = GetDC(NULL);
  wPaletteSize = PaletteSize(*lpbi);
  hbm = CreateDIBitmap(hdc,
                        (LPBITMAPINFOHEADER)lpbi,
                        (DWORD)CBM_INIT,
                        (BYTE*)lpbi + lpbi->biSize + wPaletteSize,
                        (LPBITMAPINFO)lpbi,
                         DIB_RGB_COLORS );
  if (!hbm)  // Couldn't CreateDIBitmap
  {
     AfxMessageBox("Can't create bitmap,Function BitmapFromDib failed");
     return(NULL);
  }
  ReleaseDC(NULL,hdc);

  return(hbm);
}


void *CDib::ReadBitmapHead(CFile *f)
{
 //文件頭
 BITMAPFILEHEADER bf;
 f->Read(&bf,sizeof(BITMAPFILEHEADER));
    if (!IsDIB(bf.bfType))
 {
  AfxMessageBox("File type is not Bitmap, Please select Bitmap",MB_OK);
  return(NULL);
 }

 //信息頭
 BITMAPINFOHEADER bi;
 f->Read(&bi,sizeof(BITMAPINFOHEADER));
 int size=bi.biSize;
//    switch(size)
// {
// case sizeof(BITMAPINFOHEADER):
//  break;
// case sizeof(BITMAPV4HEADER):
//  break;
//    case sizeof(BITMAPCOREHEADER):
//        BITMAPCOREHEADER *bc=(BITMAPCOREHEADER *)&bi;
//        bi.biSize=40;
//  bi.biWidth=bc->bcWidth;
//  bi.biHeight=bc->bcHeight;
//        bi.biBitCount=bc->bcBitCount;
//  bi.biPlanes=bc->bcPlanes;
//  bi.biClrUsed=0;
//  bi.biClrImportant=0;
//        bi.biCompression=0;
//  f->Seek(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),CFile::current);
//  break;
// }

 //位圖數據的字節數,計算圖像每行象素所佔的字節數目,設置成4的整數倍
    bi.biSizeImage=WIDTHBYTES(bi.biWidth*bi.biBitCount)*bi.biHeight;

 //顏色數,對於16、24、32位位圖,顏色數爲0
 int nnumcolors=DibNumColors(bi);
 if (bi.biClrUsed==0)
    bi.biClrUsed=nnumcolors;

 //位圖信息=信息頭的大小+調色板的大小
 void *hbi=malloc( size+ PaletteSize(bi) ); 
    if (!hbi)
 {
  AfxMessageBox("Can't allocate memory",MB_OK);
  return(NULL);
 }

 //信息頭
    LPBITMAPINFOHEADER lpbi=(BITMAPINFOHEADER *)hbi;
 *lpbi=bi;

 //調色板或顏色掩碼
 RGBQUAD *pRgb=(RGBQUAD*)malloc(256*sizeof(RGBQUAD));
 pRgb=(RGBQUAD *)((BYTE*)lpbi+sizeof(BITMAPINFOHEADER));
//    if  (size==sizeof(BITMAPV4HEADER))
// {
//  f->Seek(sizeof(BITMAPV4HEADER)-sizeof(BITMAPINFOHEADER),CFile::current);
//        pRgb=(RGBQUAD *)((BYTE*)pRgb+sizeof(BITMAPV4HEADER)-sizeof(BITMAPINFOHEADER));
//    }
// else 
 if (bi.biCompression==BI_BITFIELDS && bi.biBitCount>8)
 {
       f->Read( pRgb,3*sizeof(DWORD));
    pRgb=(RGBQUAD *)((BYTE*)pRgb+3*sizeof(DWORD));
 }

    if (nnumcolors)//讀取調色板信息
 {
//  if (size==sizeof(BITMAPCOREHEADER))
//  {
//            f->Read((void *)((BYTE*)pRgb),nnumcolors*sizeof(RGBTRIPLE));
//    RGBQUAD rgb;
//           for(int i=nnumcolors-1;i >= 0;i--)
//   {
//    rgb.rgbRed=((RGBTRIPLE *)pRgb)[i].rgbtRed;
//    rgb.rgbGreen=((RGBTRIPLE *)pRgb)[i].rgbtGreen;
//    rgb.rgbBlue=((RGBTRIPLE *)pRgb)[i].rgbtBlue;
//                rgb.rgbReserved=(BYTE)0;
//    pRgb[i]=rgb;
//   }
//  }
//  else
  {
   f->Read((void *)((BYTE*)pRgb),nnumcolors*sizeof(RGBQUAD));
  }
 }
 
 strFileName = f->GetFilePath();
    return(hbi);
}


UINT  CDib::DibNumColors(void *dib)
{
 BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)dib;
 switch (lpbi->biBitCount)
 {
 case 1:
  return(2);
 case 4:
  return(16);
 case 8:
  return(256);
    default:
  return(lpbi->biClrUsed);
 }
}

UINT CDib::DibNumColors(BITMAPINFOHEADER bi)
{
 switch (bi.biBitCount)
 {
 case 1:
  return(2);
 case 4:
  return(16);
 case 8:
  return(256);
    default:
  return(bi.biClrUsed);
 }

}

int CDib::BitsPerPixel()
{
 return ((BITMAPINFOHEADER*)hdib)->biBitCount;
}

UINT CDib::BitsPerPixel(BITMAPINFOHEADER bi)
{
 return bi.biBitCount;
}

UINT CDib::BitsPerPixel(void *dib)
{
 BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)dib;
 return lpbi->biBitCount;
}

//調色板數據或顏色掩碼佔用空間大小
//biBitCount=16、32時,
// 當 biCompression成員的值是BI_RGB,它沒有調色板。
// 如果biCompression成員的值是BI_BITFIELDS,原來調色板的位置被三個DWORD變量佔據,稱爲紅、綠、藍掩碼。
UINT CDib::PaletteSize()
{
    if (hdib)
 {
       BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
    if (lpbi->biSize==sizeof(BITMAPINFOHEADER)&&
             (lpbi->biBitCount>8)&&(lpbi->biCompression==BI_BITFIELDS))
    {
     return(3*sizeof(DWORD));
    }
    else
    {
     return(DibNumColors(*lpbi)*sizeof(RGBQUAD));
    }
 }
 else
 {
  return(-1);
 }

}

//調色板數據或顏色掩碼佔用空間大小
//biBitCount=16、32時,
// 當 biCompression成員的值是BI_RGB,它沒有調色板。
// 如果biCompression成員的值是BI_BITFIELDS,原來調色板的位置被三個DWORD變量佔據,稱爲紅、綠、藍掩碼。
UINT CDib::PaletteSize(BITMAPINFOHEADER bi)
{

 if (bi.biSize==sizeof(BITMAPINFOHEADER)&&
             (bi.biBitCount>8)&&(bi.biCompression==BI_BITFIELDS))
    {
    return(3*sizeof(DWORD));
    }
    else
    {
    return(DibNumColors(bi)*sizeof(RGBQUAD));
    }

}

BITMAPINFOHEADER CDib::GetBitmapInfo()
{
 BITMAPINFOHEADER bi;

 memcpy((void *)&bi,(void *)hdib,sizeof(BITMAPINFOHEADER));

 return(bi);
}

BOOL CDib::DrawBitmap(CDC *pDC,int xOffset,int yOffset)
{
     BITMAPINFO *lpbf;
     BITMAPINFOHEADER *lpbi;
  if (hdib)
  {
      lpbf=(BITMAPINFO *)hdib;
   lpbi=(BITMAPINFOHEADER *)hdib;
         ::SetDIBitsToDevice(pDC->m_hDC,
                     xOffset,yOffset,
                  lpbi->biWidth,ABS(int(lpbi->biHeight)),
         0,0,
                           0,ABS(int(lpbi->biHeight)),
                  (void *)((BYTE*)lpbi+lpbi->biSize+PaletteSize(*lpbi)),
                  lpbf,
                  DIB_RGB_COLORS);

//   CDC memDc;
//      memDc.CreateCompatibleDC(pDC);
//      memDc.SelectObject(hbm);
//      pDC->BitBlt(0,0,lpbi->biWidth,lpbi->biHeight,&memDc,0,0,SRCCOPY);

  }

  return(TRUE);
}

UINT CDib::Width()
{
 if (hdib)
 {
        BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
  return lpbi->biWidth;
 }
 else
 {
  return(0);
 }
}

int CDib::Height()
{
    if (hdib)
 {
        BITMAPINFOHEADER *lpbi=(BITMAPINFOHEADER *)hdib;
  return lpbi->biHeight;
 }
 else
 {
  return(0);
 }
}

void *CDib::GetBits()
{
    if (hdib)
 {
  return((void *)((BYTE*)hdib+sizeof(BITMAPINFOHEADER)));
 }
 else
 {
  return(NULL);
 }
}

BOOL CDib::SaveFile(LPCSTR szFileName)
{
    CFile f;

 if(!f.Open(szFileName,CFile::modeCreate|CFile::shareDenyWrite|CFile::modeWrite))
 {
  AfxMessageBox("無法打開文件");
  return(FALSE);
 }

    BITMAPFILEHEADER bf;
    bf.bfType=0x4d42;
 bf.bfSize=sizeof(BITMAPFILEHEADER)+_msize(hdib);
    bf.bfReserved1=0;
 bf.bfReserved2=0;
 bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+PaletteSize();

    f.Write((void *)&bf,sizeof(BITMAPFILEHEADER));
 f.Write(hdib,_msize(hdib));

 f.Close();

 strFileName = szFileName;
 return(TRUE);
}

CDib& CDib::operator=(CDib &dib)
{
 int size;

 FreeDib();
 size=_msize(dib.hdib);
 hdib=malloc(size);
 memcpy(hdib,dib.hdib,size);

 hbm=BitmapFromDib(hdib);

 return(*this);
}

BOOL CDib::SetBitmapinfoAndBits(BITMAPINFOHEADER bi, void *bits)
{
    int size;
 void *newdib;
 BITMAPINFOHEADER *lpbi;

 size=_msize(bits);
    newdib=malloc(sizeof(BITMAPINFOHEADER)+size);
    if (!newdib)
 {
  AfxMessageBox("can't allocate memory");
  return(FALSE);
 }
 FreeDib();
 hdib=newdib;

 lpbi=(BITMAPINFOHEADER *)newdib;
 *lpbi=bi;

 newdib=(void *)((BYTE*)newdib+sizeof(BITMAPINFOHEADER));
 memcpy(newdib,bits,size);

    if (!BitmapFromDib(hdib))
 {
  AfxMessageBox("can't create a new bitmap");
  return(FALSE);
 }
 return(TRUE);

}

 

 


void CDib::FreeDib()
{
    if (hdib)
 {
  free(hdib);
  hdib = NULL;
 }
 if (hbm)
  DeleteObject(hbm);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章