这是以前应朋友邀请写的算法,大多数是基础的,只是由于长时间不写,显得生疏,不知道是否有用,贴出来帮给初学者参考。算法是在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