一個讀位圖並顯示的類,未完

頭文件

#pragma once
#include <vector>
using namespace std;
typedef unsigned char* HMYBITMAP;
const CString FILE_TYPE_ERROR = "It is not bitmap file!";
const CString FILE_READ_ERROR = "Read file Error!";
const CString FILE_OPEN_ERROR = "Open file error!";
const int MAX_SIZE = 50;
const WORD PALVERSION = 0x300;
typedef struct tagBitmapPoint
{
 int PointX;
 int PointY;
 HMYBITMAP pBitmapData;
}BitmapPoint,*LPBitmapPoint;

typedef vector<BitmapPoint> vBitmapPoint;
class CMyBitMap
{
public:
 CMyBitMap(void);
 virtual ~CMyBitMap(void);
 // 讀入位圖文件
 void ReadBitMap(const CString& strFileName,CString& strError);
private:
 // 指向位圖的句柄
 HMYBITMAP hBitmap;
 // 指向位圖文件的頭的指針
 BITMAPINFOHEADER* pBitmapInfoHeader;
 // 文件頭結構
 BITMAPFILEHEADER m_BitmapFileHeader;
 // 當前讀入位圖的調色板
 CPalette* pCPalette;
 // 指向位圖的數據區
 HMYBITMAP hBitmapData;
public:
 // 爲當前位圖創建調色板
 void CreatePalette(void);
 void PaintBitmap(CDC* pDC, int DestinationX, int DestinationY, DWORD Width, DWORD Height, int ResourceX, int ResourceY, UINT StartLine, UINT ScanLines, UINT ColorUse = DIB_RGB_COLORS);
 
 ULONGLONG GetBitmapWidth(void);
 ULONGLONG GetBitmapHeight(void);
 HMYBITMAP GetBitmap(void);
 // 將256色的圖像變爲2值圖像
 BOOL BitMapToBinaryMap(void);
 // 獲得表格圖像偏轉後最上端的點的像素座標
 CPoint GetTopAnglePoint(void); 
private:
 // 保存探測到的黑色點
 vBitmapPoint m_vBitmapPoint;
public:
 void SearchLeft(CPoint point, int& deep);
 void SearchRight(CPoint point, int& deep); 
};

實現文件

#include "StdAfx.h"
#include "./bitmap.h"
#include <math.h>
#include "MyLog.h"

const int MAX_DEEP = 200;

CMyBitMap::CMyBitMap(void)
: pBitmapInfoHeader(NULL)
, pCPalette(NULL)
,hBitmap(NULL)
,hBitmapData(NULL)
, m_vBitmapPoint(0)
{
}

CMyBitMap::~CMyBitMap(void)
{
}

// 讀入位圖文件
void CMyBitMap::ReadBitMap(const CString& strFileName,CString& strError)
{
 CFile file;
 
 if(file.Open(strFileName,CFile::modeReadWrite))
 {
  //讀文件頭,判斷是不是位圖文件
  if(sizeof(BITMAPFILEHEADER) == file.Read(&m_BitmapFileHeader,sizeof(BITMAPFILEHEADER)))
  {
   if(m_BitmapFileHeader.bfType = 19778)
   {
    //爲文件分配內存控件
    ULONGLONG BitmapFileSize = file.GetLength() - sizeof(BITMAPFILEHEADER);
    if(hBitmap != NULL)
    {
     delete []hBitmap;
     hBitmap = NULL;
    }
    if(pCPalette != NULL)
    {
     delete pCPalette;
     pCPalette = NULL;
    }
    hBitmap = (HMYBITMAP) new char[(size_t)BitmapFileSize];
    if(file.Read(hBitmap,BitmapFileSize) == BitmapFileSize)
    {
     pBitmapInfoHeader = (BITMAPINFOHEADER*)hBitmap;
     //創建調色板
     hBitmapData = hBitmap + (m_BitmapFileHeader.bfOffBits - sizeof(BITMAPFILEHEADER));
     CreatePalette();
    }
    else
    {
     strError = FILE_READ_ERROR;
    }
   }
   else
   {
    strError = FILE_TYPE_ERROR;
   }
  }
  else
  {
   strError = FILE_READ_ERROR;
  }
 }
 else
 {
  strError = FILE_OPEN_ERROR;
 }
 file.Close();
}

// 爲當前位圖創建調色板
void CMyBitMap::CreatePalette(void)
{
 pCPalette = new CPalette;
 DOUBLE ColorNum = pow(2,pBitmapInfoHeader->biBitCount);
 DOUBLE PaletteSize = sizeof(LOGPALETTE) + ColorNum * sizeof(PALETTEENTRY);
 //定義邏輯調色板,併爲其分配空間
 PLOGPALETTE lpLogPalette = (PLOGPALETTE)new char[(size_t)PaletteSize];
 //填充邏輯調色板
 lpLogPalette->palVersion = PALVERSION;
 lpLogPalette->palNumEntries = (WORD)ColorNum;
 LPBITMAPINFO pPaletteEntry = (LPBITMAPINFO)hBitmap;
#ifdef NDEBUG
 CMyLog Log;
 CString PalColor;
 char buf[10];
#endif
 for(int i = 0;i<ColorNum;i++)
 {
  lpLogPalette->palPalEntry[i].peRed = pPaletteEntry->bmiColors[i].rgbRed;
  lpLogPalette->palPalEntry[i].peGreen = pPaletteEntry->bmiColors[i].rgbGreen;
  lpLogPalette->palPalEntry[i].peBlue = pPaletteEntry->bmiColors[i].rgbBlue;
  lpLogPalette->palPalEntry[i].peFlags = 0;
  
#ifdef NDEBUG
  PalColor = "The RedColor:BlueColor:GreenColor is:";
  itoa((int)lpLogPalette->palPalEntry[i].peRed,buf,10);
  PalColor += buf;
  PalColor += ":";
  itoa((int)lpLogPalette->palPalEntry[i].peBlue,buf,10);
  PalColor += buf;
  PalColor += ":";
  itoa((int)lpLogPalette->palPalEntry[i].peGreen,buf,10);
  PalColor += buf;
  Log.WriteLog(PalColor);
#endif

 }
 //通過邏輯調色板創建實際的調色板
 pCPalette->CreatePalette(lpLogPalette);
 delete[] (char*)lpLogPalette;
}

void CMyBitMap::PaintBitmap(CDC* pDC, int DestinationX, int DestinationY, DWORD Width, DWORD Height, int ResourceX, int ResourceY, UINT StartLine, UINT ScanLines, UINT ColorUse)
{
 ::SetStretchBltMode(pDC->m_hDC, COLORONCOLOR);
 //HPALETTE pPal = (HPALETTE)pCPalette->m_hObject;
 //HPALETTE pOldPalette = ::SelectPalette(pDC->m_hDC,pPal,true);
 CPalette* pOldPalette = pDC->SelectPalette(pCPalette,TRUE);
 ::SetDIBitsToDevice(pDC->m_hDC,DestinationX,DestinationY,Width,Height,ResourceX,ResourceY,StartLine,ScanLines,hBitmapData,(BITMAPINFO*)hBitmap,ColorUse);
 pDC->SelectPalette(pOldPalette,TRUE);
}

ULONGLONG CMyBitMap::GetBitmapWidth(void)
{
 ULONGLONG width = pBitmapInfoHeader->biWidth;
 return ((width + 2)/4) * 4;
}

ULONGLONG CMyBitMap::GetBitmapHeight(void)
{
 return pBitmapInfoHeader->biHeight;
}

HMYBITMAP CMyBitMap::GetBitmap(void)
{
 return hBitmap;
}

// 將256色的圖像變爲2值圖像
BOOL CMyBitMap::BitMapToBinaryMap(void)
{
 int BitMapDataSize = m_BitmapFileHeader.bfSize - m_BitmapFileHeader.bfOffBits;
 unsigned char* buf = hBitmapData;
 for(int i = 0;i< BitMapDataSize;i++)
 {
  if(*buf != 0)
  {
   //if(i / pBitmapInfoHeader->biWidth < pBitmapInfoHeader->biHeight / 2)
   {
    *buf = 255;
   }
  }
  buf++;
 }
 GetTopAnglePoint();
 return TRUE;
}

// 獲得表格圖像偏轉後最上端的點的像素座標
CPoint CMyBitMap::GetTopAnglePoint(void)
{
 //用直線掃描圖形,當得到第一個黑色點之後,判斷此點是在圖的左半邊還是圖的右半邊。然後增加步長,暫定爲10行,如果第一個點是表格的角,那麼增加步長10後應該可以掃描到至少兩個分離開的點,這兩個點欲第一個點組成的直線的夾角應該在90度範圍左右。如果滿足這一條件,那麼可以確定的一個點就是表格的角點。
 //當掃描到第一個點後,以此點爲起點,向四周掃描,查看此點是孤立的點還是直線上的點。
 if(hBitmap == NULL)
 {
  return CPoint(0,0);
 }
 unsigned char* pData = hBitmapData;
 int Width = pBitmapInfoHeader->biWidth;
 int Height = pBitmapInfoHeader->biHeight;
 int deep = 0;
 CPoint point;
 for(int i = Height-1; i >= 0;i--)
 {
  pData = hBitmapData + i * Width;
  for(int j = 0;j<Width;j++)
  {
   if(*pData == 0)
   {
    deep = 0;     
    point.x = j;
    point.y = i;
    if(j > Width / 2)
    {     
     SearchLeft(point,deep);
    }
    else
    {
     SearchRight(point,deep);
    }
    if(deep >= MAX_DEEP)
    {
     return CPoint(i,j);
    }
   }
   pData++;
  }
 }
 return CPoint();
}


void CMyBitMap::SearchLeft(CPoint point, int& deep)
{
 if(deep >= MAX_DEEP)
 {
  return;
 } 
 if(point.x > pBitmapInfoHeader->biWidth || point.x < 0 || point.y < 0 || point.y > pBitmapInfoHeader->biHeight)
 {
  return;
 }
 if(*(hBitmapData + pBitmapInfoHeader->biWidth * point.y + point.x) == 0)
 {
  //*(hBitmapData + pBitmapInfoHeader->biWidth * point.y + point.x) = 255;
  deep++;
  SearchLeft(CPoint(point.x -1,point.y),deep);
  SearchLeft(CPoint(point.x -1,point.y -1),deep);
  SearchLeft(CPoint(point.x,point.y -1),deep);
 }
 else
 {
  return;
 } 
}

void CMyBitMap::SearchRight(CPoint point, int& deep)
{
 if(deep >= MAX_DEEP)
 {
  return;
 } 
 if(point.x > pBitmapInfoHeader->biWidth || point.x < 0 || point.y < 0 || point.y > pBitmapInfoHeader->biHeight)
 {
  return;
 }
 if(*(hBitmapData + pBitmapInfoHeader->biWidth * point.y + point.x) == 0)
 {
  //*(hBitmapData + pBitmapInfoHeader->biWidth * point.y + point.x) = 255;
  deep++;
  SearchRight(CPoint(point.x + 1,point.y),deep);
  SearchRight(CPoint(point.x + 1,point.y -1),deep);
  SearchRight(CPoint(point.x,point.y - 1),deep);
 }
 else
 {
  return;
 } 
}

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