常用用图像处理算法(一)

本文档介绍了一组基础图像处理算法的实现,包括灰度图、彩色图、二值化处理,以及局部纠偏、去污、浓淡调整、黑白边去除、磨白、擦除、二值化、横竖拆页、拼页、旋转、翻转、亮度调整等操作。代码主要在MFC框架下编写,适合初学者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是以前应朋友邀请写的算法,大多数是基础的,只是由于长时间不写,显得生疏,不知道是否有用,贴出来帮给初学者参考。算法是在MFC框架下编写的,我会把主文件和相关文件相继贴出来。

一、基本实现如下功能:

1)        图像灰度图、彩色图和二值化三种格式文件的打开和存储功能;

2)        支持版面局部纠偏功能;

3)        图像去污功能;

4)        支持图像局部浓淡调整功能;

5)        支持去除图像黑白边功能;

6)        支持部分磨白功能;

7)        擦除图像功能;

8)        自动和人工二值化功能;

9)        对图像提供横、竖拆页功能,图像人工、自动拼页功能;

10)    图像进行左、右旋转,翻转及改变图像亮度操作功能;

二、主函数为CArdpsImg类
1)头文件

#pragma once
#include "api/dibapi.h"
#include "api/ImgConv.h"
#include "api/CompConnect.h"


class CArdpsImg  : public CObject
{
 DECLARE_SERIAL(CArdpsImg)

public:
 CArdpsImg(void);
 CArdpsImg &operator =(const CArdpsImg &ArdSrc);
 CArdpsImg(const CArdpsImg &ArdSrc);

 HANDLE  LoadNonDibHandle(BOOL *bBmp, char* szImgFileName);
 bool    ConvertGray(int nMethod, UINT uiRWeight = 114, UINT uiGWeight = 587, UINT uiBWeight = 299 );
 bool    ConvertBinary(int nMethod /* = 0 */, int nTh /* = 0  */);
 bool    SaveNonDIB(HDIB hDib, CString strFileName, ImageType nDestFileExtType );
 bool    GrayEqual();
 bool    GrayStretch(int nMethod, BYTE x1,BYTE y1,BYTE x2,BYTE y2);
 bool    EliminateDirt(int nMethod, const CRect rct);
 bool    EliminateDirt(int nMethod, const int nCircleX, const int nCircleY, const int nRadius);
 void    SetDirtSize(CSize szMax, CSize szMin);
 CRect*   GetDirtPos( int nMethod, int *nCnt);
 bool    AutoEliminateDirt(int nMethod, int nMinArea);
 bool    AutoEliminateDirt(int nMethod, CRect *pRect, int *pFlag, const int nNum);
 bool    RotateImage(int iRotateAngle = 0);
 bool    AutoRotatelImage( RECT rtROI);
 bool    CutFrame();   
 bool    SplitImage(POINT pt1, POINT pt2, CArdpsImg *pNewArd);
 bool    MergeImage(CArdpsImg *pSrcArd, int nMethod = 0);
 bool    MergeImage(CArdpsImg *pSrcArd, int nPos1, int nPos2, int nMethod = 0);
 bool    SaveTiff(char *szImgFileName);
 bool    AjustLightAndContrast(int brightness, int contrast);
 bool    Zoom(double fRatioX, double fRatioY);
 bool    AdjustBinPos( int nMethod = 0);
 bool    ColorEqual();


 bool    SaveGrayDIB(); // for debug

 
 void    Serialize(CArchive& ar);
 bool    IsEmpty();
 bool    Read(CFile *pFile);
 bool    Write(CFile *pFile);
 bool    Create(LPBYTE lpDIB);
 bool    Create(LPBYTE lpDIB,  WORD  wBitCount);  
 bool    UpdateInternal();
 void    Destroy();
 bool    BuildBitmap();
 bool    BuildPalette();
 bool    Display(CDC* pDC, int x, int y, DWORD dwRop=SRCCOPY);
 bool    ConvertFormat(WORD wBitCount);


 WORD  GetBitCount();
 LONG   GetWidth();
 LONG   GetHeight();   
 LONG   GetWidthBytes();
 WORD  GetPaletteSize();
 HANDLE  GetHandle();
 WORD  GetColorNumber();
 LPBYTE  GetBitsPtr();
 bool    Attach(HDIB hDib);
 ImageType GetFileExtType(CString strExt);
 CPalette*  GetPalette(); 
private:
 bool  InitDIBFileHead(LPBITMAPINFOHEADER lpBI, BITMAPFILEHEADER *lpbmfHdr); 
 bool  IntensityMean(const BYTE *pbGray, const int nImgWid, const int nImgHei, int &nIntenMean );
 bool  ThreshImage(const BYTE *pbImg, BYTE *pbBinary, const int nImgWid, const int nImgHei, const int nTh);
 void  OtsuTh( DWORD nW, DWORD nH, BYTE *lpBits, int  &Th);
 void  ExtractComponent(Line * Li, BYTE *pMotion, UINT grayBytesPerLine, BYTE bCur ) ;
 inline void  add(int a,int b,char **flag,int *&stack,int **InStack, int &top,int &topin,int c,int d,component *ctail, BYTE *pMotion, UINT grayBytesPerLine,  BYTE bCur  );
 void  AnalysisComponent( Line * Li,  BYTE *pbBinary, UINT unBinaryBytesPerLine, UINT minArea, const BYTE bValue);
 bool  AnalysisDirtPos(Line *Li, CSize maxSize, CSize minSize, int nHeight, int *nCnt);
 bool  ConvertBinary2Gray(const unsigned char * pbBinary, const int nWidth, const int nHeight, unsigned char *pbGray);
 void  SetBinary(CRect rect, BYTE *pbImg, UINT unBinaryBytesPerLine, const BYTE bValue);
 int   OutputNormalImageUnderAngle(BYTE *DesImg, const BYTE *SrcImage, int nWidth, int nHeight, double dk);
 bool  FindTopEdge(BYTE *pbOutImage, BYTE *image, RECT rtROI, int nWidth);
 double DetectSkewAngle(BYTE *pbImage, RECT rtROI, int nWidth);
 RECT GetEdgeImageBoundary(BYTE *pbImage, int nWidth, int nHeight);
 RECT  GetBinImageBoundary(BYTE *pbImage, int nWidth, int nHeight);
 int   FindEdgeImage(BYTE *pbOutImage, BYTE *image, RECT rtROI, int nWidth);
 RECT SetRectValue(int left, int right, int top, int bottom);
 bool  VerticalSplit(int nX, CArdpsImg *newArt);
 bool  HorizntalSplit(int nY, CArdpsImg *newArt);
 int   CompVPrjValeSum(int *pnRamBuff, const BYTE *pInImg, int nImgWidth, int nImgHeight, int nRotAngle);
 void  SmoothingArray(int *pOut, int nR, const int *pIn, int nStart, int nEnd) ;
 int   DeleteVtlSmallLine(BYTE* pImg, BYTE* pBuf, int nWidth, int nHeight, int nTh);
 HDIB  ReadBinTiff(char* szImgFileName);
 void  Img32to24(BYTE *pbImg32, BYTE *pbImg24, int nWidth, int nHeight);
 void  ReversBits(BYTE *pbIn, int nWidth, int nHeight, DWORD nBitCnt);
 void  ReversColors(BYTE*pbIn, BYTE *pbOut, int nWidth, int nHeight);
 void  ReversColors(BYTE*pbIn, int nWidth, int nHeight);
 void  MoveBin(BYTE *pbIn, int nWidth, int nHeight, RECT rtOld, RECT rtNew,   int nMethod = 0);
  

  
public:
 HDIB  m_hDib;  //DIB handle of CDib object
 HBITMAP  m_hBitmap; // handle of DIBSection
 CPalette*  m_pPalette; //related to DIB's palette CPalette object
 CBitmap* m_pBitmap; //related to DDB's CBitmap object
 HDIB  m_hNewDib;

 // private member data
private:
 // for drawing in DIB
 CDC *  m_pMemDC;
 CBitmap* m_pBitmapTmp;
 CPalette* m_pPaletteTmp;
 CSize  m_DirtSize;
 CSize  m_minDirtSize;
 CRect  *m_dirRect;

public:
 virtual ~CArdpsImg(void);
};

 

2)源文件

#include "StdAfx.h"
#include "ArdpsImg.h"
#include "api/ImgConv.h"
#include "api/CompConnect.h"
#include "api/tiff/tiffio.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <windowsx.h>  // especially for GlobalAllocPtr

 

const UINT  uiRWeight   = 114;
const UINT  uiGWeight  = 587;
const UINT  uiBWeight   = 299; 
#define PI 3.14159
//角度到弧度转化的宏
#define RADIAN(angle) ((angle)*PI/180.0)

#define EDGE_STEP 4

DWORD buf[256];
double bufi[256], varience[256];
// 5. the cos value(*65536 or * (2**16)) with angle from 0 to 180 and the step is 1
const int g_nCos[180] = {   
 65536, 65526, 65496, 65446, 65376, 65286, 65176, 65047, 64898, 64729, 
 64540, 64331, 64103, 63856, 63589, 63302, 62997, 62672, 62328, 61965, 
 61583, 61183, 60763, 60326, 59870, 59395, 58903, 58393, 57864, 57319, 
 56755, 56175, 55577, 54963, 54331, 53683, 53019, 52339, 51643, 50931, 
 50203, 49460, 48702, 47930, 47142, 46340, 45525, 44695, 43852, 42995, 
 42125, 41243, 40347, 39440, 38521, 37589, 36647, 35693, 34728, 33753, 
 32768, 31772, 30767, 29752, 28729, 27696, 26655, 25606, 24550, 23486, 
 22414, 21336, 20251, 19160, 18064, 16961, 15854, 14742, 13625, 12504, 
 11380, 10252, 9120, 7986, 6850, 5711, 4571, 3429, 2287, 1143, 
 0, -1143, -2287, -3429, -4571, -5711, -6850, -7986, -9120, -10252, 
 -11380, -12504, -13625, -14742, -15854, -16961, -18064, -19160, -20251, -21336, 
 -22414, -23486, -24550, -25606, -26655, -27696, -28729, -29752, -30767, -31772, 
 -32768, -33753, -34728, -35693, -36647, -37589, -38521, -39440, -40347, -41243, 
 -42125, -42995, -43852, -44695, -45525, -46340, -47142, -47930, -48702, -49460, 
 -50203, -50931, -51643, -52339, -53019, -53683, -54331, -54963, -55577, -56175, 
 -56755, -57319, -57864, -58393, -58903, -59395, -59870, -60326, -60763, -61183, 
 -61583, -61965, -62328, -62672, -62997, -63302, -63589, -63856, -64103, -64331, 
 -64540, -64729, -64898, -65047, -65176, -65286, -65376, -65446, -65496, -65526
};

// 6. the sin value(*65536 or * (2**16)) with angle from 0 to 180 and the step is 1
const int g_nSin[180] = {
 0, 1143, 2287, 3429, 4571, 5711, 6850, 7986, 9120, 10252, 
 11380, 12504, 13625, 14742, 15854, 16961, 18064, 19160, 20251, 21336, 
 22414, 23486, 24550, 25606, 26655, 27696, 28729, 29752, 30767, 31772, 
 32768, 33753, 34728, 35693, 36647, 37589, 38521, 39440, 40347, 41243, 
 42125, 42995, 43852, 44695, 45525, 46340, 47142, 47930, 48702, 49460, 
 50203, 50931, 51643, 52339, 53019, 53683, 54331, 54963, 55577, 56175, 
 56755, 57319, 57864, 58393, 58903, 59395, 59870, 60326, 60763, 61183, 
 61583, 61965, 62328, 62672, 62997, 63302, 63589, 63856, 64103, 64331, 
 64540, 64729, 64898, 65047, 65176, 65286, 65376, 65446, 65496, 65526, 
 65536, 65526, 65496, 65446, 65376, 65286, 65176, 65047, 64898, 64729, 
 64540, 64331, 64103, 63856, 63589, 63302, 62997, 62672, 62328, 61965, 
 61583, 61183, 60763, 60326, 59870, 59395, 58903, 58393, 57864, 57319, 
 56755, 56175, 55577, 54963, 54331, 53683, 53019, 52339, 51643, 50931, 
 50203, 49460, 48702, 47930, 47142, 46340, 45525, 44695, 43852, 42995, 
 42125, 41243, 40347, 39440, 38521, 37589, 36647, 35693, 34728, 33753, 
 32768, 31772, 30767, 29752, 28729, 27696, 26655, 25606, 24550, 23486, 
 22414, 21336, 20251, 19160, 18064, 16961, 15854, 14742, 13625, 12504, 
 11380, 10252, 9120, 7986, 6850, 5711, 4571, 3429, 2287, 1143
};

typedef bool (*PFN_ImageConvert)(const unsigned char * pSrcData, int nSrcDataLen, ImageType itSrcImageType,
         unsigned char * * ppDestData, int * pnDestDataLen, ImageType itDestImageType);
typedef bool (*PFN_ImageDelete)(unsigned char * * ppImageData);

IMPLEMENT_SERIAL(CArdpsImg, CObject, 0)

CArdpsImg::CArdpsImg(void)
{
 m_hDib  = NULL;   //CDib对象所表示的DIB句柄
 m_hBitmap   = NULL;   //DIB对应的DIBSECTION的句柄
 m_pPalette  = NULL;   //和DIB相关的CPalette调色板对象
 m_pBitmap   = NULL;   //和DIB相关的CBitmap DDB对象
 m_hNewDib = NULL;
 m_DirtSize.cx = 5;
 m_DirtSize.cy = 5;
 m_minDirtSize.cx = 2;
 m_minDirtSize.cy = 2;
 m_dirRect = NULL;
}

CArdpsImg::CArdpsImg(const CArdpsImg &ArdSrc)
{
 if (this != &ArdSrc)
 {
  Destroy();
  if (m_pBitmap != NULL)
  {
   delete m_pBitmap;
   m_pBitmap = NULL;
  }
  if (m_pPalette != NULL)
  {
   delete m_pPalette;
   m_pPalette = NULL;
  }
  if( m_dirRect )
  {
   delete []m_dirRect;
   m_dirRect = NULL;
  }
  if ( m_pMemDC )
  {
   delete m_pMemDC;
   m_pMemDC = NULL;
  }

  this->m_hDib = ArdSrc.m_hDib;
  this->m_hNewDib = ArdSrc.m_hNewDib;
  this->m_pBitmap = ArdSrc.m_pBitmap;
  this->m_pPalette = ArdSrc.m_pPalette;
  this->m_dirRect = ArdSrc.m_dirRect;
  this->m_pMemDC = ArdSrc.m_pMemDC;
  this->m_pPaletteTmp = ArdSrc.m_pPaletteTmp;
  this->m_pBitmapTmp = ArdSrc.m_pBitmapTmp;
  this->m_DirtSize = ArdSrc.m_DirtSize;
  this->m_minDirtSize = ArdSrc.m_minDirtSize;
  this->m_dirRect = ArdSrc.m_dirRect;
 }
}

CArdpsImg::~CArdpsImg(void)
{
 Destroy();
 if (m_pBitmap != NULL)
 {
  delete m_pBitmap;
  m_pBitmap = NULL;
 }
 if (m_pPalette != NULL)
 {
  delete m_pPalette;
  m_pPalette = NULL;
 }
 if( m_dirRect )
 {
  delete []m_dirRect;
  m_dirRect = NULL;
 }
}

CArdpsImg & CArdpsImg::operator =(const CArdpsImg &ArdSrc)
{
 if (this != &ArdSrc)
 {
  Destroy();
  if (m_pBitmap != NULL)
  {
   delete m_pBitmap;
   m_pBitmap = NULL;
  }
  if (m_pPalette != NULL)
  {
   delete m_pPalette;
   m_pPalette = NULL;
  }
  if( m_dirRect )
  {
   delete []m_dirRect;
   m_dirRect = NULL;
  }
  if ( m_pMemDC )
  {
   delete m_pMemDC;
   m_pMemDC = NULL;
  }

  this->m_hDib = ArdSrc.m_hDib;
  this->m_hNewDib = ArdSrc.m_hNewDib;
  this->m_pBitmap = ArdSrc.m_pBitmap;
  this->m_pPalette = ArdSrc.m_pPalette;
  this->m_dirRect = ArdSrc.m_dirRect;
  this->m_pMemDC = ArdSrc.m_pMemDC;
  this->m_pPaletteTmp = ArdSrc.m_pPaletteTmp;
  this->m_pBitmapTmp = ArdSrc.m_pBitmapTmp;
  this->m_DirtSize = ArdSrc.m_DirtSize;
  this->m_minDirtSize = ArdSrc.m_minDirtSize;
  this->m_dirRect = ArdSrc.m_dirRect;
 }
 return *this;
}
void CArdpsImg::Serialize(CArchive& ar)
{
 CObject::Serialize(ar);
 ar.Flush();
 if (ar.IsStoring())
 {
  Write(ar.GetFile());
 }
 else
 {
  Read(ar.GetFile());
 }
}
bool CArdpsImg::Read(CFile *pFile)
{
 WaitCursorBegin();

 LPBITMAPINFOHEADER lpbi;
 DWORD dwSize;
 TRY
 {
  // read DIB file header
  BITMAPFILEHEADER bmfHdr;
  pFile->Read(&bmfHdr, sizeof(BITMAPFILEHEADER));
  // is DIB file?

  if (bmfHdr.bfType != DIB_HEADER_MARKER/*"BM"*/)
  {
   WaitCursorEnd();
   return false;
  }
  DWORD dwLength = pFile->GetLength();
  if (bmfHdr.bfSize != dwLength)
   bmfHdr.bfSize = dwLength;

  // read DIB buffer
  dwSize = bmfHdr.bfSize - sizeof(BITMAPFILEHEADER);
  lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, dwSize);
  DWORD dwCount = pFile->Read(lpbi, dwSize);
  // read ok?
  if (dwCount != dwSize)
  {
   GlobalFreePtr(lpbi);
   WaitCursorEnd();
   return false;
  }

  // Check to see that it's a Windows DIB -- an OS/2 DIB would cause
  // strange problems with the rest of the DIB API since the fields
  // in the header are different and the color table entries are
  // smaller.
  //
  // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL.
  if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  {
   GlobalFreePtr(lpbi);
   WaitCursorEnd();
   return false;
  }

  // fill color num item
  int nNumColors = (UINT)lpbi->biClrUsed;
  if (nNumColors == 0)
  {
   // no color table for 24-bit, default size otherwise
   if (lpbi->biBitCount != 24)
    nNumColors = 1 << lpbi->biBitCount; // standard size table
  }

  // fill in some default values if they are zero
  if (lpbi->biClrUsed == 0)
   lpbi->biClrUsed = nNumColors;
  if (lpbi->biSizeImage == 0)
   lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight;
 }
 CATCH (CException, e)
 {
  GlobalFreePtr(lpbi);
  WaitCursorEnd();
  return false;
 }
 END_CATCH

  // create CDib with DIB buffer
  bool bSuccess = Create((LPBYTE)lpbi);
 GlobalFreePtr(lpbi);
 WaitCursorEnd();

 return bSuccess;
}
///
//从DIB数据块创建默认CDib对象
///
bool CArdpsImg::Create(LPBYTE lpDIB)
{
 if (lpDIB == NULL)
  return false;

 DWORD dwSize = DIBlockSize(lpDIB);

 HDIB hDib  = GlobalAlloc(GHND, dwSize);
 // Check that DIB handle is valid
 if (! hDib)
  return false;

 LPBYTE lpbi  = (LPBYTE)GlobalLock(hDib);
 if (! lpbi)
  return false;

 CopyMemory(lpbi, lpDIB, dwSize);
 GlobalUnlock(hDib);

 Destroy();
 m_hDib = hDib;
 LPBYTE ptmp = (LPBYTE) GlobalLock(m_hDib);

 return UpdateInternal();
}
//*******************************************************************
// 功能:调用DIBToDIBSection函数,创建并更新DIB的DIBSECTION和DDB
//*******************************************************************
bool CArdpsImg::BuildBitmap()
{
 if (m_pBitmap != NULL)
 {
  delete m_pBitmap;
  m_pBitmap = NULL;
  m_hBitmap = NULL;
 }
 m_hBitmap = DIBToDIBSection(m_hDib);
 if (m_hBitmap == NULL)
  return false;
 m_pBitmap = new CBitmap;
 m_pBitmap->Attach(m_hBitmap);

 return true;
}
//*******************************************************************
//该函数调用CreateDIBPalette函数,创建并更新DIB调色板
//*******************************************************************
bool CArdpsImg::BuildPalette()
{
 if (m_pPalette != NULL)
 {
  delete m_pPalette;
  m_pPalette = NULL;
 }
 HPALETTE hPalette = CreateDIBPalette(m_hDib);
 if (hPalette == NULL)
  return false;
 m_pPalette = new CPalette;
 m_pPalette->Attach(hPalette);

 return true;
}

//*******************************************************************
//UpdateInternal function 更新CDib对象所对应的调色板、DIBSECTION、DDB对象
//调用BuildPlaette 和BuildBitmap函数,重建CDib对象的,m_pPalette、m_hBitmap
//和m_pBitmap 成员数据
bool CArdpsImg::UpdateInternal()
{
 BuildPalette();
 return BuildBitmap();
}

void CArdpsImg::Destroy()
{
 if (m_hDib != NULL)
 {
  DestroyDIB(m_hDib);
  m_hDib = NULL;
 }
 if( m_hNewDib != NULL )
 {
  DestroyDIB(m_hNewDib);
  m_hNewDib  = NULL;
 }
}


///
//从DIB数据块创建CDib对象
///
bool CArdpsImg::Create(LPBYTE lpDIB,  WORD  wBitCount)  // bits/pixel
{
 if (lpDIB == NULL)
  return false;
 if (! Create(lpDIB))
  return false;

 WORD wBits = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
 if (wBitCount == wBits)
  return true;

 HDIB hNewDib = ConvertDIBFormat(m_hDib, wBitCount, NULL);
 if (! hNewDib)
  return false;

 Destroy();
 m_hDib = hNewDib;
 return UpdateInternal();
}
CPalette* CArdpsImg::GetPalette()
{
 return m_pPalette;
}
bool CArdpsImg::Write(CFile *pFile)
{
 WaitCursorBegin();

 BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file
 LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure
 DWORD               dwDIBSize;

 // Get a pointer to the DIB memory, the first of which contains
 // a BITMAPINFO structure
 lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
 if (!lpBI)
 {
  GlobalUnlock(m_hDib);
  WaitCursorEnd();
  return false;
 }

 // Check to see if we're dealing with an OS/2 DIB.  If so, don't
 // save it because our functions aren't written to deal with these
 // DIBs.
 if (lpBI->biSize != sizeof(BITMAPINFOHEADER))
 {
  GlobalUnlock(m_hDib);
  WaitCursorEnd();
  return false;
 }

 // Fill in the fields of the file header

 // Fill in file type (first 2 bytes must be "BM" for a bitmap)

 bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM"

 // Calculating the size of the DIB is a bit tricky (if we want to
 // do it right).  The easiest way to do this is to call GlobalSize()
 // on our global handle, but since the size of our global memory may have
 // been padded a few bytes, we may end up writing out a few too
 // many bytes to the file (which may cause problems with some apps,
 // like HC 3.0).
 //
 // So, instead let's calculate the size manually.
 //
 // To do this, find size of header plus size of color table.  Since the
 // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
 // the size of the structure, let's use this.

 // Partial Calculation

 dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);  

 // Now calculate the size of the image

 // It's an RLE bitmap, we can't calculate size, so trust the biSizeImage
 // field

 if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  dwDIBSize += lpBI->biSizeImage;
 else
 {
  DWORD dwBmBitsSize;  // Size of Bitmap Bits only

  // It's not RLE, so size is Width (DWORD aligned) * Height

  dwBmBitsSize = MYWIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *
   lpBI->biHeight;

  dwDIBSize += dwBmBitsSize;

  // Now, since we have calculated the correct size, why don't we
  // fill in the biSizeImage field (this will fix any .BMP files which 
  // have this field incorrect).

  lpBI->biSizeImage = dwBmBitsSize;
 }


 // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)

 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
 bmfHdr.bfReserved1 = 0;
 bmfHdr.bfReserved2 = 0;

 // Now, calculate the offset the actual bitmap bits will be in
 // the file -- It's the Bitmap file header plus the DIB header,
 // plus the size of the color table.

 bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize +
  PaletteSize((LPBYTE)lpBI);

 TRY
 {
  // Write the file header
  pFile->Write(&bmfHdr, sizeof(BITMAPFILEHEADER));
  // write DIB buffer
  pFile->Write(lpBI, dwDIBSize);
 }
 CATCH (CException, e)
 {
  GlobalUnlock(m_hDib);
  WaitCursorEnd();
  return false;
 }
 END_CATCH

  GlobalUnlock(m_hDib);
 WaitCursorEnd();

 return true;
}


bool CArdpsImg::IsEmpty()
{
 if (m_hDib == NULL)
  return true;

 if (! GlobalLock(m_hDib))
  return true;

 GlobalUnlock(m_hDib);
 return false;
}

bool CArdpsImg::Display(CDC * pDC, int x, int y, DWORD dwRop)
{
 CDC MemDC;
 MemDC.CreateCompatibleDC(pDC);

 CBitmap* pOldBmp = MemDC.SelectObject(m_pBitmap);

 CPalette* pOldPal = pDC->SelectPalette(m_pPalette, true);
 pDC->RealizePalette();

 bool bSuccess = pDC->BitBlt(x, y,
  GetWidth(), GetHeight(),
  &MemDC,
  0, 0,
  dwRop);

 MemDC.SelectObject(pOldBmp);
 pDC->SelectPalette(pOldPal, true);

 return bSuccess;
}

WORD CArdpsImg::GetBitCount()
{
 LPBITMAPINFOHEADER lpBI = (LPBITMAPINFOHEADER)GlobalLock(m_hDib);
 if (!lpBI)
 {
  GlobalUnlock(m_hDib);
  return 0;
 }

 WORD wBitCount = lpBI->biBitCount;
 GlobalUnlock(m_hDib);

 return wBitCount;
}

LONG CArdpsImg::GetWidth()
{
 // get DIB buffer pointer
 LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
 if (! lpDIB)
 {
  GlobalUnlock(m_hDib);
  return 0;
 }

 LONG lWidth = (LONG)DIBWidth(lpDIB);
 GlobalUnlock(m_hDib);

 return lWidth;
}

LONG CArdpsImg::GetHeight()
{
 // get DIB buffer pointer
 LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
 if (! lpDIB)
 {
  GlobalUnlock(m_hDib);
  return 0;
 }

 LONG lHeight = (LONG)DIBHeight(lpDIB);
 GlobalUnlock(m_hDib);

 return lHeight;
}

LONG CArdpsImg::GetWidthBytes()
{
 return MYWIDTHBYTES((GetWidth())*((DWORD)GetBitCount()));
 //return WIDTHBYTES((GetWidth())*((int)GetBitCount()));
}
LPBYTE CArdpsImg::GetBitsPtr()
{
 LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
 if (! lpDIB)
 {
  GlobalUnlock(m_hDib);
  return NULL;
 }

 LPBYTE lpData = FindDIBBits(lpDIB);
 GlobalUnlock(m_hDib);

 return lpData;
}

HANDLE

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值