一个读位图并显示的类,未完

头文件

#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;
 } 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值