www.pudn.com > backmode824.rar > Dibapi.cpp
#include "WindowsX.h"
#include "stdafx.h"
#include "mmsystem.h"
#include "math.h"
#include "Dibapi.h"
// Compile using winmm.lib
//***********************************************
// 调色板函数群
// **********************************************
//**********************************************
// HPALETTE CreateDIBPalette(LPBYTE lpbi)
//*********************************************
HPALETTE CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal=NULL;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
int i,wNumColors;
if(!lpbi)
return NULL;
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
//
wNumColors=DIBNumColors(lpbi);
if(wNumColors==0)
return NULL;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
if(wNumColors)
{
hLogPal=GlobalAlloc(GHND,sizeof(LOGPALETTE)*
sizeof(PALETTEENTRY)*wNumColors);
if(!hLogPal)
{
//GlobalUnlock(lpbi);
return NULL;
}
lpPal=(LPLOGPALETTE)GlobalLock(hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=wNumColors;
for(i=0;ipalPalEntry[i].peRed=
lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=
lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=
lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
// GlobalUnlock(lpbi);
// lpbmc=(LPBITMAPCOREINFO)GlobalLock(lpbi);
lpPal->palPalEntry[i].peRed=
lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=
lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=
lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
}
}
hPal=CreatePalette(lpPal);
if(!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
// GlobalUnlock(lpbi);
return NULL;
}
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
}
// GlobalUnlock(lpbi);
return hPal;
}
//***********************************************
// HPALETTE GetSystemPalette(void)
// **********************************************
HPALETTE GetSystemPalette(void)
{
HDC hDC;
static HPALETTE hPal=NULL;
HANDLE hLogPal;
LPLOGPALETTE lpLogPal;
int nColors;
hDC=GetDC(NULL);
if(!hDC)
return NULL;
nColors=PalEntriesOnDevice(hDC);
hLogPal=GlobalAlloc(GHND,sizeof(LOGPALETTE)+nColors*
sizeof(PALETTEENTRY));
if(!hLogPal)
return NULL;
lpLogPal=(LPLOGPALETTE)GlobalLock(hLogPal);
lpLogPal->palVersion=PALVERSION;
lpLogPal->palNumEntries=nColors;
GetSystemPaletteEntries(hDC,0,nColors,
(LPPALETTEENTRY)(lpLogPal->palPalEntry));
hPal=CreatePalette(lpLogPal);
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
ReleaseDC(NULL,hDC);
return hPal;
}
//***********************************************
// int PalEntriesOnDevice(HDC hDC)
// **********************************************
int PalEntriesOnDevice(HDC hDC)
{
int nColors;
nColors=(1<<(GetDeviceCaps(hDC,BITSPIXEL)*
GetDeviceCaps(hDC,PLANES)));
if(nColors>256) nColors=256;
if(nColors<0) nColors=0;
return nColors;
}
//***********************************************
// BOOL DisplayPalette(HDC hDC,LPRECT lpRect,HPALETTE hPal)
// **********************************************
BOOL HDisplayPalette(HDC hDC,LPRECT lpRect,HPALETTE hPal)
{
if(!hPal)
return FALSE;
int nEntries;
PALETTEENTRY pe[256];
nEntries=GetPaletteEntries(hPal,0,256,pe);
int nSqr=(int)sqrt((double)nEntries);
int nWidth=(lpRect->right-lpRect->left)/nSqr;
int nHeight=(lpRect->bottom-lpRect->top)/nSqr;
lpRect->right=lpRect->left+nWidth*nSqr;
lpRect->bottom=lpRect->top+nHeight*nSqr;
HPALETTE hOldPalette=(HPALETTE)SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
HBRUSH hBrush,hOldBrush;
int x,y;
for(int i=0;ileft+x*nWidth,
lpRect->top+y*nHeight,
lpRect->left+(x+1)*nWidth,
lpRect->top+(y+1)*nHeight);
SelectObject(hDC,hOldBrush);
DeleteObject(hBrush);
}
SelectPalette(hDC,hPal,FALSE);
return TRUE;
}
//***********************************************
// BOOL MapDIBColorsToPalette(HDIB hDIB,HPALETTE hPalette)
// **********************************************
BOOL MapDIBColorsToPalette(HDIB hDIB,HPALETTE hPalette)
{
if(!hDIB)
return FALSE;
if(!hPalette)
return FALSE;
LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(!lpbi)
return FALSE;
LPRGBQUAD pctThis=(LPRGBQUAD)((LPBYTE)lpbi+lpbi->biSize);
BYTE imap[256];
for(int i=0;i<256;i++)
{
imap[i]=(BYTE)GetNearestPaletteIndex(hPalette,
RGB(pctThis->rgbRed,
pctThis->rgbGreen,
pctThis->rgbBlue));
pctThis++;
}
LPBYTE pBits=(LPBYTE)lpbi+lpbi->biSize+PaletteSize((LPBYTE)lpbi);
int iSize=WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)*lpbi->biHeight;
while(iSize--)
{
*pBits=imap[*pBits];
pBits++;
}
PALETTEENTRY pe[256];
GetPaletteEntries(hPalette,0,256,pe);
pctThis=(LPRGBQUAD)((LPBYTE)lpbi+lpbi->biSize);
for(i=0;i<256;i++)
{
pctThis->rgbRed=pe[i].peRed;
pctThis->rgbGreen=pe[i].peGreen;
pctThis->rgbBlue=pe[i].peBlue;
pctThis++;
}
GlobalUnlock(hDIB);
return TRUE;
}
//***********************************************
// 属性函数群
// **********************************************
//***********************************************
// DWORD BytesPerLine(LPBYTE lpDIB)
// **********************************************
DWORD BytesPerLine(LPBYTE lpDIB)
{
return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth*
((LPBITMAPINFOHEADER)lpDIB)->biPlanes*
((LPBITMAPINFOHEADER)lpDIB)->biBitCount);
}
//***********************************************
// DWORD DIBBlockSize(LPBYTE lpDIB)
// **********************************************
DWORD DIBBlockSize(LPBYTE lpDIB)
{
if(((LPBITMAPINFOHEADER)lpDIB)->biSizeImage==0)
{
((LPBITMAPINFOHEADER)lpDIB)->biSizeImage=
BytesPerLine(lpDIB)*((LPBITMAPINFOHEADER)
lpDIB)->biHeight;
}
return ((LPBITMAPINFOHEADER)lpDIB)->biSize+PaletteSize(
lpDIB)+((LPBITMAPINFOHEADER)lpDIB)->biSizeImage;
}
//***********************************************
// WORD DIBBitCount(LPBYTE lpDIB)
// **********************************************
WORD DIBBitCount(LPBYTE lpDIB)
{
return ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
}
//***********************************************
// DWORD DIBHeight(LPBYTE lpDIB)
// **********************************************
DWORD DIBHeight(LPBYTE lpDIB)
{
return ((LPBITMAPINFOHEADER)lpDIB)->biHeight;
}
//**********************************************
// WORD DIBNumColors(LPBYTE lpDIB)
// **********************************************
WORD DIBNumColors(LPBYTE lpDIB)
{
WORD wBitCount;
if(IS_WIN30_DIB(lpDIB))
{
DWORD dwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
if(dwClrUsed)
{
return (WORD)dwClrUsed;
}
}
if(IS_WIN30_DIB(lpDIB))
wBitCount=((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else
wBitCount=((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
//***********************************************
// LPBYTE FindDIBBits(LPBYTE lpDIB)
// **********************************************
LPBYTE FindDIBBits(LPBYTE lpDIB)
{
DWORD nOffSize;
UINT nNumColors;
nNumColors=DIBNumColors(lpDIB);
nOffSize=((LPBITMAPINFOHEADER)lpDIB)->biSize
+nNumColors*sizeof(RGBQUAD);
return ((LPBYTE)(lpDIB+nOffSize));
}
//***********************************************
// WORD PaletteSize(LPBYTE lpDIB)
// **********************************************
WORD PaletteSize(LPBYTE lpDIB)
{
WORD PalSize;
UINT nNumColors;
if(!(nNumColors=(UINT)(((LPBITMAPINFOHEADER)lpDIB)->biClrUsed)))
{
if(((LPBITMAPINFOHEADER)lpDIB)->biBitCount!=24)
nNumColors=1<<(((LPBITMAPINFOHEADER)lpDIB)->biBitCount);
}
PalSize=nNumColors*sizeof(RGBQUAD);
return PalSize;
}
//***********************************************
// DWORD BytesPerLine(HDIB hDIB)
// **********************************************
DWORD BytesPerLine(HDIB hDIB)
{
DWORD nBPL;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
nBPL=WIDTHBYTES(lpbih->biWidth*
lpbih->biPlanes*lpbih->biBitCount);
GlobalUnlock(hDIB);
return nBPL;
}
//***********************************************
// DWORD DIBBlockSize(HDIB hDIB)
// **********************************************
DWORD DIBBlockSize(HDIB hDIB)
{
DWORD nBBS;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
if(lpbih->biSizeImage==0)
{
lpbih->biSizeImage=
BytesPerLine(hDIB)*lpbih->biHeight;
}
nBBS=lpbih->biSize+PaletteSize(hDIB)*lpbih->biSizeImage;
GlobalUnlock(hDIB);
return nBBS;
}
//***********************************************
// WORD DIBBitCount(HDIB hDIB)
// **********************************************
WORD DIBBitCount(HDIB hDIB)
{
WORD nBBC;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
nBBC=lpbih->biBitCount;
GlobalUnlock(hDIB);
return nBBC;
}
//***********************************************
// DWORD DIBHeight(HDIB hDIB)
// **********************************************
DWORD DIBHeight(HDIB hDIB)
{
DWORD nh;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
nh= lpbih->biHeight;
GlobalUnlock(hDIB);
return nh;
}
//**********************************************
// WORD DIBNumColors(HDIB hDIB)
// **********************************************
WORD DIBNumColors(HDIB hDIB)
{
WORD wBitCount;
DWORD dwClrUsed;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
LPBITMAPCOREHEADER lpbich;
LPBITMAPCOREINFO lpbic;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
if(IS_WIN30_DIB(lpbih))
{
dwClrUsed=lpbih->biClrUsed;
if(dwClrUsed)
{
GlobalUnlock(hDIB);
return (WORD)dwClrUsed;
}
}
if(IS_WIN30_DIB(lpbih))
{
wBitCount=lpbih->biBitCount;
GlobalUnlock(hDIB);
}
else
{
GlobalUnlock(hDIB);
lpbic=(LPBITMAPCOREINFO)GlobalLock(hDIB);
if(lpbic==NULL) return 0;
lpbich=(LPBITMAPCOREHEADER)lpbic;
if(lpbich==NULL) return 0;
wBitCount=lpbich->bcBitCount;
GlobalUnlock(hDIB);
}
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
//***********************************************
// DWORD DIBWidth(HDIB hDIB)
// **********************************************
DWORD DIBWidth(HDIB hDIB)
{
DWORD DibW;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
DibW=lpbih->biWidth;
GlobalUnlock(hDIB);
return DibW;
}
//***********************************************
// LPBYTE FindDIBBits(HDIB hDIB)
// **********************************************
LPBYTE FindDIBBits(HDIB hDIB)
{
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
DWORD nOffSize;
UINT nNumColors;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
nNumColors=DIBNumColors(hDIB);
nOffSize=lpbih->biSize+nNumColors*sizeof(RGBQUAD);
// GlobalUnlock(hDIB);
return ((LPBYTE)(lpbih+nOffSize));
}
//***********************************************
// WORD PaletteSize(HDIB hDIB)
// **********************************************
WORD PaletteSize(HDIB hDIB)
{
WORD PalSize;
UINT nNumColors;
LPBITMAPINFO lpbi;
LPBITMAPINFOHEADER lpbih;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(lpbi==NULL) return 0;
lpbih=(LPBITMAPINFOHEADER)lpbi;
if(lpbih==NULL) return 0;
if(!(nNumColors=(UINT)(lpbih->biClrUsed)))
{
if(lpbih->biBitCount!=24)
nNumColors=1<<(lpbih->biBitCount);
}
GlobalUnlock(hDIB);
PalSize=nNumColors*sizeof(RGBQUAD);
return PalSize;
}
//***********************************************
// 初始化函数群
// **********************************************
//***********************************************
// HDIB CreateDIB(DWORD dwWidth,DWORD dwHeight,WORD wBitCount)
// **********************************************
HDIB CreateDIB(DWORD dwWidth,DWORD dwHeight,WORD wBitCount)
{
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HDIB hDIB;
DWORD dwBytesPerLine;
if(wBitCount<=1)
wBitCount=1;
else if(wBitCount<=4)
wBitCount=4;
else if(wBitCount<=8)
wBitCount=8;
else if(wBitCount<=24)
wBitCount=24;
else
wBitCount=8;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biWidth=dwWidth;
bi.biHeight=dwHeight;
bi.biPlanes=1;
bi.biBitCount=wBitCount;
bi.biCompression=BI_RGB;
bi.biSizeImage=0;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=0;
bi.biClrImportant=0;
dwBytesPerLine=WIDTHBYTES(wBitCount *dwWidth);
dwLen=bi.biSize+PaletteSize((LPBYTE)&bi)+
(dwBytesPerLine*dwHeight);
hDIB=GlobalAlloc(GHND,dwLen);
if(!hDIB)
return NULL;
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi=bi;
GlobalUnlock(hDIB);
return hDIB;
}
//***********************************************
// HDIB CreateDefaultDIB(DWORD dwWidth,DWORD dwHeight)
// **********************************************
HDIB CreateDefaultDIB(DWORD dwWidth,DWORD dwHeight)
{
HDC hDC=GetDC(NULL);
if(!hDC)
return NULL;
int nDeviceBitsPixel=GetDeviceCaps(hDC,BITSPIXEL);
HDIB hDIB=CreateDIB(dwWidth,dwHeight,nDeviceBitsPixel);
LPBITMAPINFO lpbmi=(LPBITMAPINFO)GlobalLock(hDIB);
LPBYTE lpDIBBits=FindDIBBits((LPBYTE)lpbmi);
DWORD dwBitsSize=lpbmi->bmiHeader.biHeight*
BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
for(DWORD l=0;l8)
{
GlobalUnlock(hDIB);
ReleaseDC(NULL,hDC);
return hDIB;
}
int nColors=PalEntriesOnDevice(hDC);
PALETTEENTRY pe[256];
GetSystemPaletteEntries(hDC,0,nColors,pe);
for(int i=0;ibmiColors[i].rgbRed=pe[i].peRed;
lpbmi->bmiColors[i].rgbGreen=pe[i].peGreen;
lpbmi->bmiColors[i].rgbBlue=pe[i].peBlue;
}
GlobalUnlock(hDIB);
ReleaseDC(NULL,hDC);
return hDIB;
}
//***********************************************
// void DestroyDIB(HDIB hDib)
// **********************************************
void DestroyDIB(HDIB hDib)
{
GlobalFree(hDib);
return;
}
//***********************************************
// HANDLE ReadDIBFile(HANDLE hFile)
// **********************************************
HANDLE ReadDIBFile(HANDLE hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitSize;
UINT nNumColors;
HANDLE hDIB;
HANDLE hDIBtmp;
LPBITMAPINFOHEADER lpbi;
DWORD offBits;
DWORD dwRead;
dwBitSize=GetFileSize(hFile,NULL);
hDIB=GlobalAlloc(GMEM_MOVEABLE,
(DWORD)(sizeof(BITMAPINFOHEADER)+
256*sizeof(RGBQUAD)));
if(!hDIB)
{
return(NULL);
}
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(!lpbi)
{
GlobalFree(hDIB);
return(NULL);
}
if(!ReadFile(hFile,
(LPBYTE)&bmfHeader,
sizeof(BITMAPFILEHEADER),
&dwRead,
NULL))
goto ErrExit;
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
goto ErrExit;
if(!ReadFile(hFile,
(LPBYTE)lpbi,
sizeof(BITMAPINFOHEADER),
&dwRead,
NULL))
goto ErrExit;
if(sizeof(BITMAPINFOHEADER)!=dwRead)
goto ErrExit;
if(lpbi->biSize==sizeof(BITMAPCOREHEADER))
goto ErrExit;
if(!(nNumColors=(UINT)lpbi->biClrUsed))
{
if(lpbi->biBitCount!=24)
nNumColors=1<biBitCount;
}
if(lpbi->biClrUsed==0)
lpbi->biClrUsed=nNumColors;
if(lpbi->biSizeImage==0)
{
lpbi->biSizeImage=(((lpbi->biWidth*
(DWORD)lpbi->biBitCount+31)&~31)>>3)*lpbi->biHeight;
}
GlobalUnlock(hDIB);
hDIBtmp=GlobalReAlloc(hDIB,lpbi->biSize+nNumColors*
sizeof(RGBQUAD)+lpbi->biSizeImage,0);
if(!hDIBtmp)
goto ErrExitUnLock;
else
hDIB=hDIBtmp;
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
ReadFile(hFile,
(LPBYTE)lpbi+lpbi->biSize,
nNumColors*sizeof(RGBQUAD),
&dwRead,
NULL);
offBits=lpbi->biSize+nNumColors*sizeof(RGBQUAD);
if(bmfHeader.bfOffBits!=0L)
SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
if(ReadFile(hFile,(LPBYTE)lpbi+offBits,lpbi->biSizeImage,&dwRead,NULL))
goto OKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitUnLock:
GlobalFree(hDIB);
return NULL;
OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
//***********************************************
// HANDLE LoadDIB(LPSTR lpPathName)
// **********************************************
HANDLE LoadDIB(LPCTSTR lpFileName)
{
HANDLE hDIB;
HANDLE hFile;
SetCursor(LoadCursor(NULL,IDC_WAIT));
if((hFile=CreateFile(lpFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN,
NULL)) !=INVALID_HANDLE_VALUE)
{
hDIB=ReadDIBFile(hFile);
CloseHandle(hFile);
SetCursor(LoadCursor(NULL,IDC_ARROW));
return hDIB;
}
else
{
SetCursor(LoadCursor(NULL,IDC_ARROW));
return NULL;
}
}
//***********************************************
// BOOL SaveDIB(HANDLE hDib,LPCTSTR lpFileName)
// **********************************************
BOOL SaveDIB(HANDLE hDib,LPCTSTR lpFileName)
{
BITMAPFILEHEADER bmfHeader;
LPBITMAPINFOHEADER lpBI;
HANDLE fh;
DWORD dwDIBSize;
DWORD dwWritten;
if(!hDib)
return FALSE;
fh=CreateFile(lpFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(fh==INVALID_HANDLE_VALUE)
return FALSE;
lpBI=(LPBITMAPINFOHEADER)GlobalLock(hDib);
if(!lpBI)
{
CloseHandle(fh);
return FALSE;
}
if(lpBI->biSize!=sizeof(BITMAPINFOHEADER))
{
GlobalUnlock(hDib);
CloseHandle(fh);
return FALSE;
}
bmfHeader.bfType=DIB_HEADER_MARKER; //"BM"
dwDIBSize=*(LPWORD)lpBI+
DIBNumColors((LPBYTE)lpBI)*sizeof(RGBQUAD);
if((lpBI->biCompression==BI_RLE8)||
(lpBI->biCompression==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage;
else
{
DWORD dwBMBitsSize;
dwBMBitsSize=WIDTHBYTES((lpBI->biWidth)*
((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBMBitsSize;
lpBI->biSizeImage=dwBMBitsSize;
}
bmfHeader.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHeader.bfReserved1=0;
bmfHeader.bfReserved2=0;
bmfHeader.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+
lpBI->biSize+DIBNumColors((LPBYTE)lpBI)*sizeof(RGBQUAD);
WriteFile(fh,(LPBYTE)&bmfHeader,
sizeof(BITMAPFILEHEADER),&dwWritten,NULL);
WriteFile(fh,(LPBYTE)lpBI,dwDIBSize,&dwWritten,NULL);
GlobalUnlock(hDib);
CloseHandle(fh);
if(dwWritten==0)
return FALSE;
else
return TRUE;
}
//***********************************************
// 显示函数
// **********************************************
//*************************************************************
// BOOL PaintDIB(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,
// LPRECT lpDIBRect,HPALETTE hPal, DWORD dwRop)
// *************************************************************
BOOL PaintDIB(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,
LPRECT lpDIBRect,HPALETTE hPal, DWORD dwRop)
{
LPBYTE lpDIBHdr;
LPBYTE lpDIBBits;
BOOL bSuccess=FALSE;
HPALETTE hOldPal=NULL;
if(!hDIB)
return FALSE;
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
lpDIBBits=lpDIBHdr+sizeof(BITMAPINFOHEADER)+
DIBNumColors(lpDIBHdr)*sizeof(RGBQUAD);
if(!hPal)
hPal=CreateDIBPalette(lpDIBHdr);
if(hPal)
{
hOldPal=SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
}
SetStretchBltMode(hDC,COLORONCOLOR);
bSuccess=StretchDIBits(hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight
-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
RECTWIDTH(lpDIBRect),
RECTHEIGHT(lpDIBRect),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
// GlobalUnlock(hDIB);
if(hOldPal)
SelectPalette(hDC,hOldPal,FALSE);
GlobalUnlock(hDIB);
return bSuccess;
}
//*************************************************************
// BOOL PaintBitmap(HDC hDC,LPRECT lpDCRect,HBITMAP hDDB,
// LPRECT lpDDBRect,HPALETTE hPal, DWORD dwRop)
// *************************************************************
BOOL PaintBitmap(HDC hDC,LPRECT lpDCRect,HBITMAP hDDB,
LPRECT lpDDBRect,HPALETTE hPal, DWORD dwRop)
{
HDC hMemDC;
HBITMAP hOldBitmap;
HPALETTE hOldPal1=NULL;
HPALETTE hOldPal2=NULL;
BOOL bSuccess=FALSE;
hMemDC=CreateCompatibleDC(hDC);
if(!hMemDC)
return FALSE;
if(hPal)
{
hOldPal1=SelectPalette(hMemDC,hPal,TRUE);
hOldPal2=SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
}
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hDDB);
SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDDBRect))&&
(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDDBRect)))
bSuccess=BitBlt(hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
hMemDC,
lpDDBRect->left,
lpDDBRect->top,
dwRop);
else
bSuccess=StretchBlt(hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
hMemDC,
lpDDBRect->left,
lpDDBRect->top,
RECTWIDTH(lpDDBRect),
RECTHEIGHT(lpDDBRect),
dwRop);
SelectObject(hMemDC,hOldBitmap);
if(hOldPal1)
SelectPalette(hDC,hOldPal1,FALSE);
if(hOldPal2)
SelectPalette(hDC,hOldPal2,FALSE);
DeleteDC(hMemDC);
return bSuccess;
}
//***********************************************
// 操作函数
// **********************************************
//***********************************************
// HBITMAP DIBTODIBSECTION(LPBYTE lpDIB)
// **********************************************
HBITMAP DIBToDIBSection(LPBYTE lpDIB)
{
LPBYTE lpSourceBits;
HDC hDC=NULL;
HDC hSourceDC;
HBITMAP hSourceBitmap;
HBITMAP hOldSourceBitmap;
DWORD dwSourceBitsSize;
LPBITMAPINFO lpSrcDIB=(LPBITMAPINFO)lpDIB;
if(!lpSrcDIB)
return NULL;
hDC=GetDC(NULL);
hSourceBitmap=CreateDIBSection(hDC,lpSrcDIB,
DIB_RGB_COLORS,(VOID **)&lpSourceBits,NULL,0);
hSourceDC=CreateCompatibleDC(hDC);
dwSourceBitsSize=lpSrcDIB->bmiHeader.biHeight*
BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
memcpy(lpSourceBits,FindDIBBits((LPBYTE)lpSrcDIB),
dwSourceBitsSize);
hOldSourceBitmap=(HBITMAP)SelectObject(hSourceDC,hSourceBitmap);
if(lpSrcDIB->bmiHeader.biBitCount<=8)
SetDIBColorTable(hSourceDC,
0,
1<bmiHeader.biBitCount,
lpSrcDIB->bmiColors);
SelectObject(hSourceDC,hOldSourceBitmap);
DeleteDC(hSourceDC);
ReleaseDC(NULL,hDC);
GdiFlush();
return hSourceBitmap;
}
//***********************************************
// HDIB DIBSectionToDIB(HBITMAP hBitmap)
// **********************************************
HDIB DIBSectionToDIB(HBITMAP hBitmap)
{
HDC hDC=NULL,hSourceDC;
HBITMAP hOldSourceBitmap;
HANDLE hNewDIB;
LPBITMAPINFO lpbmi=NULL;
DWORD dwSize;
DIBSECTION ds;
DWORD dwColorNum;
GetObject(hBitmap,sizeof(DIBSECTION),&ds);
dwColorNum=ds.dsBmih.biClrUsed;
if((dwColorNum==0)&&(ds.dsBmih.biBitCount<=8))
dwColorNum=1<bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth=ds.dsBm.bmWidth;
lpbmi->bmiHeader.biHeight=ds.dsBm.bmHeight;
lpbmi->bmiHeader.biPlanes=1;
lpbmi->bmiHeader.biBitCount=ds.dsBmih.biBitCount;
lpbmi->bmiHeader.biCompression=ds.dsBmih.biCompression;
lpbmi->bmiHeader.biSizeImage=ds.dsBmih.biSizeImage;
lpbmi->bmiHeader.biXPelsPerMeter=ds.dsBmih.biXPelsPerMeter;
lpbmi->bmiHeader.biYPelsPerMeter=ds.dsBmih.biYPelsPerMeter;
lpbmi->bmiHeader.biClrUsed=ds.dsBmih.biClrUsed;
lpbmi->bmiHeader.biClrImportant=ds.dsBmih.biClrImportant;
hDC=GetDC(NULL);
if(!GetDIBits(hDC,
hBitmap,
0L,
(DWORD)ds.dsBm.bmHeight,
(LPBYTE)lpbmi+(WORD)lpbmi->bmiHeader.biSize
+(dwColorNum*sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbmi,
(DWORD)DIB_RGB_COLORS) )
{
GlobalUnlock(hNewDIB);
ReleaseDC(NULL,hDC);
return NULL;
}
hSourceDC=CreateCompatibleDC(hDC);
hOldSourceBitmap=(HBITMAP)SelectObject(hSourceDC,hBitmap);
if(lpbmi->bmiHeader.biBitCount<=8)
GetDIBColorTable(hSourceDC,0,1<bmiHeader.biBitCount,
lpbmi->bmiColors);
SelectObject(hSourceDC,hOldSourceBitmap);
DeleteDC(hSourceDC);
ReleaseDC(NULL,hDC);
GlobalUnlock(hNewDIB);
return hNewDIB;
}
//***********************************************
// BOOL CopyColorTabel(LPBITMAPINFO lpTarget,LPBITMAPINFO lpSource,
// HPALETTE hPalSrc);
// **********************************************
BOOL CopyColorTable(LPBITMAPINFO lpTarget,LPBITMAPINFO lpSource,
HPALETTE hPalSrc)
{
switch(lpTarget->bmiHeader.biBitCount)
{
case 8:
if(hPalSrc)
{
PALETTEENTRY pe[256];
UINT i;
GetPaletteEntries(hPalSrc,0,256,pe);
for(i=0;i<256;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbReserved=0;
}
}
else
{
if(lpSource->bmiHeader.biBitCount==8)
{
memcpy(lpTarget->bmiColors,lpSource->bmiColors,
256*sizeof(RGBQUAD));
}
else
{
HPALETTE hPal;
HDC hDC=GetDC(NULL);
PALETTEENTRY pe[256];
UINT i;
hPal=CreateOctreePalette((LPBYTE)lpSource,236,8);
if(!hPal)
hPal=CreateHalftonePalette(hDC);
ReleaseDC(NULL,hDC);
GetPaletteEntries(hPal,0,256,pe);
DeleteObject(hPal);
for(i=0;i<256;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbReserved=pe[i].peFlags;
}
}
}
break;
case 4:
if(hPalSrc)
{
PALETTEENTRY pe[16];
UINT i;
GetPaletteEntries(hPalSrc,0,16,pe);
for(i=0;i<16;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbReserved=0;
}
}
else
{
if(lpSource->bmiHeader.biBitCount==8)
{
memcpy(lpTarget->bmiColors,lpSource->bmiColors,
16*sizeof(RGBQUAD));
}
else
{
HPALETTE hPal;
PALETTEENTRY pe[256];
UINT i;
hPal=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetPaletteEntries(hPal,0,16,pe);
DeleteObject(hPal);
for(i=0;i<16;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbReserved=pe[i].peFlags;
}
}
}
break;
case 1:
lpTarget->bmiColors[0].rgbRed=0;
lpTarget->bmiColors[0].rgbGreen=0;
lpTarget->bmiColors[0].rgbBlue=0;
lpTarget->bmiColors[0].rgbReserved=0;
lpTarget->bmiColors[1].rgbRed=255;
lpTarget->bmiColors[1].rgbGreen=255;
lpTarget->bmiColors[1].rgbBlue=255;
lpTarget->bmiColors[1].rgbReserved=0;
break;
case 32:
case 24:
case 16:
default:
break;
}
return TRUE;
}
//***********************************************
// HDIB ConvertDIBFormat(LPBYTE lpDIB,UINT nWidth,UINT nHeight,
// UINT nbpp,BOOL bStrech,HPALETTE hPalSrc)
// **********************************************
HDIB ConvertDIBFormat(LPBYTE lpDIB,UINT nWidth,UINT nHeight,
UINT nbpp,BOOL bStretch,HPALETTE hPalSrc)
{
LPBITMAPINFO lpSrcDIB=(LPBITMAPINFO)lpDIB;
LPBITMAPINFO lpbmi=NULL;
LPBYTE lpSourceBits,lpTargetBits,lpResult;
HDC hDC=NULL,hSourceDC,hTargetDC;
HBITMAP hSourceBitmap,hTargetBitmap,hOldTargetBitmap,
hOldSourceBitmap;
DWORD dwSourceBitsSize,dwTargetBitsSize,dwTargetHeaderSize,
dwColorNum;
HDIB hDib;
if(nbpp<=8)
dwColorNum=1<bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth=nWidth;
lpbmi->bmiHeader.biHeight=nHeight;
lpbmi->bmiHeader.biPlanes=1;
lpbmi->bmiHeader.biBitCount=nbpp;
lpbmi->bmiHeader.biCompression=BI_RGB;
lpbmi->bmiHeader.biSizeImage=0;
lpbmi->bmiHeader.biXPelsPerMeter=0;
lpbmi->bmiHeader.biYPelsPerMeter=0;
lpbmi->bmiHeader.biClrUsed=0;
lpbmi->bmiHeader.biClrImportant=0;
if(!CopyColorTable(lpbmi,(LPBITMAPINFO)lpSrcDIB,hPalSrc))
{
free(lpbmi);
return NULL;
}
hDC=GetDC(NULL);
hTargetBitmap=CreateDIBSection(hDC,lpbmi,DIB_RGB_COLORS,
(VOID **)&lpTargetBits,NULL,0);
hSourceBitmap=CreateDIBSection(hDC,lpSrcDIB,DIB_RGB_COLORS,
(VOID **)&lpSourceBits,NULL,0);
hSourceDC=CreateCompatibleDC(hDC);
hTargetDC=CreateCompatibleDC(hDC);
dwSourceBitsSize=lpSrcDIB->bmiHeader.biHeight*
BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
dwTargetBitsSize=lpbmi->bmiHeader.biHeight*
BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
memcpy(lpSourceBits,FindDIBBits((LPBYTE)lpSrcDIB),dwSourceBitsSize);
lpbmi->bmiHeader.biSizeImage=dwTargetBitsSize;
hOldSourceBitmap=(HBITMAP)SelectObject(hSourceDC,hSourceBitmap);
hOldTargetBitmap=(HBITMAP)SelectObject(hTargetDC,hTargetBitmap);
if(lpSrcDIB->bmiHeader.biBitCount<=8)
SetDIBColorTable(hSourceDC,0,
1<bmiHeader.biBitCount,
lpSrcDIB->bmiColors);
if(lpbmi->bmiHeader.biBitCount<=8)
SetDIBColorTable(hTargetDC,0,
1<bmiHeader.biBitCount,
lpbmi->bmiColors);
if((lpSrcDIB->bmiHeader.biWidth==lpbmi->bmiHeader.biWidth)&&
(lpSrcDIB->bmiHeader.biHeight==lpbmi->bmiHeader.biHeight))
BitBlt(hTargetDC,0,0,
lpbmi->bmiHeader.biWidth,
lpbmi->bmiHeader.biHeight,
hSourceDC,0,0,SRCCOPY);
else
{
if(bStretch)
{
SetStretchBltMode(hTargetDC,COLORONCOLOR);
StretchBlt(hTargetDC,0,0,
lpbmi->bmiHeader.biWidth,
lpbmi->bmiHeader.biHeight,
hSourceDC,0,0,
lpSrcDIB->bmiHeader.biWidth,
lpSrcDIB->bmiHeader.biHeight,
SRCCOPY);
}
else
{
BitBlt(hTargetDC,0,0,
lpbmi->bmiHeader.biWidth,
lpbmi->bmiHeader.biHeight,
hSourceDC,0,0,SRCCOPY);
}
}
SelectObject(hSourceDC,hOldSourceBitmap);
SelectObject(hTargetDC,hOldSourceBitmap);
DeleteDC(hSourceDC);
DeleteDC(hTargetDC);
ReleaseDC(NULL,hDC);
GdiFlush();
hDib=GlobalAlloc(GHND,dwTargetBitsSize+dwTargetHeaderSize);
lpResult=(LPBYTE)GlobalLock(hDib);
memcpy(lpResult,lpbmi,dwTargetHeaderSize);
memcpy(FindDIBBits((LPBYTE)lpResult),lpTargetBits,dwTargetBitsSize);
DeleteObject(hTargetBitmap);
DeleteObject(hSourceBitmap);
free(lpbmi);
GlobalUnlock(hDib);
return hDib;
}
//***********************************************
// HDIB BitmaptoDIB(HBITMAP hBitmap,HPALETTE hPal)
//
// **********************************************
HDIB BitmapToDIB(HBITMAP hBitmap,HPALETTE hPal)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDIB,h;
HDC hDC;
WORD biBits;
if(!hBitmap)
return NULL;
if(!GetObject(hBitmap,sizeof(bm),(LPBYTE)&bm))
return NULL;
if(hPal==NULL)
hPal=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
biBits=bm.bmPlanes*bm.bmBitsPixel;
if(biBits<=1)
biBits=1;
else if(biBits<=4)
biBits=4;
else if(biBits<=8)
biBits=8;
else
biBits=24;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biWidth=bm.bmWidth;
bi.biHeight=bm.bmHeight;
bi.biPlanes=1;
bi.biBitCount=biBits;
bi.biCompression=BI_RGB;
bi.biSizeImage=0;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=0;
bi.biClrImportant=0;
dwLen=bi.biSize+PaletteSize((LPBYTE)&bi);
hDC=GetDC(NULL);
hPal=SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
hDIB=GlobalAlloc(GMEM_MOVEABLE,dwLen);
if(!hDIB)
{
SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
ReleaseDC(NULL,hDC);
return NULL;
}
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi=bi;
GetDIBits(hDC,hBitmap,0,(UINT)bi.biHeight,NULL,
(LPBITMAPINFO)lpbi,DIB_RGB_COLORS);
bi=*lpbi;
GlobalUnlock(hDIB);
if(bi.biSizeImage==0)
bi.biSizeImage=WIDTHBYTES((DWORD)bm.bmWidth*biBits)*
bm.bmHeight;
DWORD dwOldLen=dwLen;
dwLen=bi.biSize+PaletteSize((LPBYTE)&bi)+bi.biSizeImage;
h=GlobalReAlloc(hDIB,dwLen,0);
if(h)
hDIB=h;
else
{
GlobalFree(hDIB);
hDIB=NULL;
SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
ReleaseDC(NULL,hDC);
return NULL;
}
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(GetDIBits(hDC,hBitmap,0,(UINT)bm.bmHeight,
(LPBYTE)lpbi+(WORD)lpbi->biSize+PaletteSize((LPBYTE)lpbi),
(LPBITMAPINFO)lpbi,
DIB_RGB_COLORS)==0)
{
GlobalUnlock(hDIB);
hDIB=NULL;
SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
ReleaseDC(NULL,hDC);
return NULL;
}
bi=*lpbi;
GlobalUnlock(hDIB);
SelectPalette(hDC,hPal,TRUE);
RealizePalette(hDC);
ReleaseDC(NULL,hDC);
return hDIB;
}
//***********************************************
//HDIB BitmapToDIB(HBITMAP hBitmap,
// HPALETTE hPalette,WORD wBitCount)
// **********************************************
HDIB BitmapToDIB(HBITMAP hBitmap,HPALETTE hPalette,WORD wBitCount)
{
HDIB hNewDib;
LPBYTE lpbi;
if(!hBitmap)
return NULL;
BITMAP bm;
GetObject(hBitmap,sizeof(bm),(LPBYTE)&bm);
int biBits=bm.bmPlanes*bm.bmBitsPixel;
if(biBits<=1)
biBits=1;
else if(biBits<=4)
biBits=4;
else if(biBits<=8)
biBits=8;
else
biBits=24;
HDIB hDib=BitmapToDIB(hBitmap,hPalette);
if(!hDib)
return NULL;
if(wBitCount==biBits)
hNewDib=hDib;
else
{
lpbi=(LPBYTE)GlobalLock(hDib);
hNewDib=ConvertDIBFormat(
lpbi,
(UINT)(((LPBITMAPINFOHEADER)lpbi)->biWidth),
(UINT)(((LPBITMAPINFOHEADER)lpbi)->biHeight),
wBitCount,
FALSE,
hPalette);
GlobalUnlock(hDib);
GlobalFree(hDib);
}
return hNewDib;
}
//***********************************************
//HBITMAP DIBToBitmap(HDIB hDIB,HPALETTE hPal)
//
// **********************************************
HBITMAP DIBToBitmap(HDIB hDIB,HPALETTE hPal)
{
LPBYTE lpDIBHdr,lpDIBBits;
HBITMAP hBitmap;
HDC hDC;
HPALETTE hOldPal=NULL;
if(!hDIB)
return NULL;
lpDIBHdr=(LPBYTE)GlobalLock(hDIB);
lpDIBBits=FindDIBBits(lpDIBHdr);
hDC=GetDC(NULL);
if(!hDC)
{
GlobalUnlock(hDIB);
return NULL;
}
if(hPal)
{
hOldPal=SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
}
hBitmap=CreateDIBitmap(hDC,
(LPBITMAPINFOHEADER)lpDIBHdr,
CBM_INIT,
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS);
if(hOldPal)
SelectPalette(hDC,hOldPal,FALSE);
ReleaseDC(NULL,hDC);
GlobalUnlock(hDIB);
return hBitmap;
}
//***********************************************
// 捕获函数群
// **********************************************
//**********************************************
// HBITMAP CopyScreenToBitmap(LPRECT lpRect)
//*********************************************
HBITMAP CopyScreenToBitmap(LPRECT lpRect)
{
HDC hScrDC,hMemDC;
HBITMAP hBitmap,hOldBitmap;
int nx,ny,nx2,ny2;
int nWidth,nHeight;
int xScrn,yScrn;
if(IsRectEmpty(lpRect))
return NULL;
hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
hMemDC=CreateCompatibleDC(hScrDC);
nx=lpRect->left;
ny=lpRect->top;
nx2=lpRect->right;
ny2=lpRect->bottom;
xScrn=GetDeviceCaps(hScrDC,HORZRES);
yScrn=GetDeviceCaps(hScrDC,VERTRES);
if(nx<0)
nx=0;
if(ny<0)
ny=0;
if(nx2>xScrn)
nx2=xScrn;
if(ny2>yScrn)
ny2=yScrn;
nWidth=nx2-nx;
nHeight=ny2-ny;
hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nx,ny,SRCCOPY);
hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return hBitmap;
}
//**********************************************
// HBITMAP CopyWindowToBitmap(HWND hWnd,WORD fPrintArea)
//*********************************************
HBITMAP CopyWindowToBitmap(HWND hWnd,WORD fPrintArea)
{
HBITMAP hBitmap=NULL;
if(!hWnd)
return NULL;
switch(fPrintArea)
{
case PW_WINDOW:
{
RECT rectWnd;
GetWindowRect(hWnd,&rectWnd);
hBitmap=CopyScreenToBitmap(&rectWnd);
break;
}
case PW_CLIENT:
{
RECT rectClient;
POINT pt1,pt2;
GetClientRect(hWnd,&rectClient);
pt1.x=rectClient.left;
pt1.y=rectClient.top;
pt2.x=rectClient.right;
pt2.y=rectClient.bottom;
ClientToScreen(hWnd,&pt1);
ClientToScreen(hWnd,&pt2);
rectClient.left=pt1.x;
rectClient.top=pt1.y;
rectClient.right=pt2.x;
rectClient.bottom=pt2.y;
hBitmap=CopyScreenToBitmap(&rectClient);
break;
}
default:
return NULL;
}
return hBitmap;
}
//**********************************************
// HBITMAP CopyClientRectToBitmap(HWND hWnd,LPRECT lpRect)
//*********************************************
HBITMAP CopyClientRectToBitmap(HWND hWnd,LPRECT lpRect)
{
HBITMAP hBitmap=NULL;
if(!hWnd)
return NULL;
POINT pt1,pt2;
pt1.x=lpRect->left;
pt1.y=lpRect->top;
pt2.x=lpRect->right;
pt2.y=lpRect->bottom;
ClientToScreen(hWnd,&pt1);
ClientToScreen(hWnd,&pt2);
lpRect->left=pt1.x;
lpRect->top=pt1.y;
lpRect->right=pt2.x;
lpRect->bottom=pt2.y;
hBitmap=CopyScreenToBitmap(lpRect);
pt1.x=lpRect->left;
pt1.y=lpRect->top;
pt2.x=lpRect->right;
pt2.y=lpRect->bottom;
ScreenToClient(hWnd,&pt1);
ScreenToClient(hWnd,&pt2);
lpRect->left=pt1.x;
lpRect->top=pt1.y;
lpRect->right=pt2.x;
lpRect->bottom=pt2.y;
return hBitmap;
}
//**********************************************
// HDIB CopyScreenTODIB(LPRECT lpRect)
//*********************************************
HDIB CopyScreenToDIB(LPRECT lpRect)
{
HBITMAP hBitmap;
HPALETTE hPalette=NULL;
HDIB hDIB=NULL;
hBitmap=CopyScreenToBitmap(lpRect);
if(!hBitmap)
return NULL;
hPalette=GetSystemPalette();
hDIB=BitmapToDIB(hBitmap,hPalette);
DeleteObject(hPalette);
DeleteObject(hBitmap);
return hDIB;
}
//**********************************************
// HDIB CopyWindowToDIB(HWND hWnd,WORD fPrintArea)
//*********************************************
HDIB CopyWindowToDIB(HWND hWnd,WORD fPrintArea)
{
HBITMAP hBitmap=NULL;
HPALETTE hPalette=NULL;
HDIB hDIB=NULL;
if(!hWnd)
return NULL;
hBitmap=CopyWindowToBitmap(hWnd,fPrintArea);
hPalette=GetSystemPalette();
hDIB=BitmapToDIB(hBitmap,hPalette);
DeleteObject(hPalette);
DeleteObject(hBitmap);
return hDIB;
}
//**********************************************
// HDIB CopyClientRectToDIB(HWND hWnd,LPRECT lpRect)
//*********************************************
HDIB CopyClientRectToDIB(HWND hWnd,LPRECT lpRect)
{
HBITMAP hBitmap=NULL;
HPALETTE hPalette=NULL;
HDIB hDIB=NULL;
if(!hWnd)
return NULL;
hBitmap=CopyClientRectToBitmap(hWnd,lpRect);
hPalette=GetSystemPalette();
hDIB=BitmapToDIB(hBitmap,hPalette);
DeleteObject(hPalette);
DeleteObject(hBitmap);
return hDIB;
}
//***********************************************
// 定时函数
// **********************************************
//***********************************************
// void Delay (DWORD dwDelayTime)
// **********************************************
void Delay (DWORD dwDelayTime)
{
DWORD dwTimeBegin,dwTimeEnd;
dwTimeBegin=timeGetTime();
do
{
dwTimeEnd=timeGetTime();
}while((dwTimeEnd-dwTimeBegin)rm) *r=rm;
if(*g>gm) *g=gm;
if(*b>bm) *b=bm;
if((*r==rm)&&(*g==gm)&&(*b=bm))
return TRUE;
else
return FALSE;
}
//***********************************************
// HANDLE CopyHandle(HANDLE h)
// **********************************************
HANDLE CopyHandle(HANDLE h)
{
if(h==NULL)
return NULL;
DWORD dwLen=::GlobalSize((HGLOBAL)h);
HANDLE hCopy=::GlobalAlloc(GHND,dwLen);
if(hCopy==NULL)
return NULL;
void *lpCopy=::GlobalLock((HGLOBAL)hCopy);
void *lp =::GlobalLock((HGLOBAL)h);
::CopyMemory(lpCopy,lp,dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
return hCopy;
}
//***********************************************
// 颜色处理函数
// **********************************************
//***********************************************
// HPALETTE ConvertToGrayScale(HDIB hnib,int nMethod,
// double fRedWeight, double fGreenWeight,double fBlueWeight)
// **********************************************
HPALETTE ConvertToGrayScale(HDIB hDib,int nMethod,
double fRedWeight, double fGreenWeight,double fBlueWeight)
{
if (hDib == NULL)
return NULL;
BITMAPINFO* lpbi = (BITMAPINFO *)GlobalLock(hDib);
if(!lpbi)
return NULL;
WaitCursorBegin();
// get color number
WORD wNumColors =DIBNumColors((LPBYTE)lpbi);
if (wNumColors == 0) // There is no palette
GlobalUnlock (hDib);
// reduce colors to 256
HDIB hNewDib=ColorQuantizeDIB(hDib,8,256);
LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
if (!lpDIB)
{
WaitCursorEnd();
return NULL;
}
DWORD dwSize =DIBBlockSize(lpDIB);
hDib = GlobalReAlloc(hDib, dwSize, 0);
lpbi= (BITMAPINFO *)GlobalLock(hDib);
CopyMemory((LPBYTE)lpbi,(LPBYTE)lpDIB,dwSize);
GlobalUnlock (hNewDib);
GlobalFree (hNewDib);
wNumColors = DIBNumColors((LPBYTE)lpbi);
BYTE GrayValue = 0;
WORD i;
switch (nMethod)
{
case MAXIMUM_GRAY:
for (i=0; ibmiColors[i].rgbRed,
lpbi->bmiColors[i].rgbGreen),
lpbi->bmiColors[i].rgbBlue);
lpbi->bmiColors[i].rgbRed =
lpbi->bmiColors[i].rgbGreen =
lpbi->bmiColors[i].rgbBlue = GrayValue;
}
break;
case MEAN_GRAY:
for (i=0; ibmiColors[i].rgbRed +
lpbi->bmiColors[i].rgbGreen +
lpbi->bmiColors[i].rgbBlue)/3);
lpbi->bmiColors[i].rgbRed =
lpbi->bmiColors[i].rgbGreen =
lpbi->bmiColors[i].rgbBlue = GrayValue;
}
break;
case WEIGHT_GRAY:
for (i=0; ibmiColors[i].rgbRed*fRedWeight+
lpbi->bmiColors[i].rgbGreen*fGreenWeight+
lpbi->bmiColors[i].rgbBlue*fBlueWeight));
lpbi->bmiColors[i].rgbRed=
lpbi->bmiColors[i].rgbGreen =
lpbi->bmiColors[i].rgbBlue=GrayValue;
}
break;
}
HPALETTE hNewDIB;
hNewDIB=CreateDIBPalette((LPBYTE)lpbi);
GlobalUnlock(hDib);
WaitCursorEnd();
return hNewDIB;
}
//**************************************************************
//* CreateOctreePalette ()
//* Parameters:
//* HDIB hDIB - Handle to source DIB
//* UINT nMaxColors - destination color number
//* UINT nColorBits - destination color bits
//* Return Value:
//* HPALETTE - Handle to the result palette
//* Description:
//* This function use Octree color quantization algorithm to get
//* optimal m kinds of color to represent total n kinds of color
//* in a DIB, and use the m kinds of color to build a palette.
//* With the palette, we can display the DIE on reasonable accuracy.
//*****************************************************************
HPALETTE CreateOctreePalette(HDIB hDIB,UINT nMaxColors,
UINT nColorBits)
{
HANDLE hImage;
LPBITMAPINFO lpbi;
if(!hDIB)
return NULL;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
hImage = DIBToDIBSection((LPBYTE)lpbi);
GlobalUnlock(hDIB);
if (!hImage)
return NULL;
return BuildOctreePalette(hImage, nMaxColors, nColorBits);
}
//**************************************************************
//* CreateOctreePalette ()
//* Parameters:
//* LPBYTE lpbIB - Pointer to DID data buffer
//* UINT nMaxColors - destination color number
//* UINT nColorBits - destination color bits
//* Return Value:
//* HPALETTE - Handle to the result palette
//* Description:
//* This function use Octree color quantization algorithm to get
//* optimal m kinds of color to represent total n kinds of color
//* in a DIB, and use the m kinds of color to build a palette.
//* With the palette, we can display the DIE on reasonable accuracy.
//*****************************************************************
HPALETTE CreateOctreePalette(LPBYTE lpDIB,UINT nMaxColors,
UINT nColorBits)
{
HANDLE hImage;
hImage = DIBToDIBSection(lpDIB);
if (! hImage)
return NULL;
return BuildOctreePalette(hImage,nMaxColors, nColorBits);
}
//***********************************************
// HPALETTE BuildOctreePalette(HANDLE hImage, UINT nMaxColors,
// UINT nColorBits)
// **********************************************
// local function to build optimal palette from DlBSection
HPALETTE BuildOctreePalette(HANDLE hImage, UINT nMaxColors,
UINT nColorBits)
{
DIBSECTION ds;
int i, j, nPad;
BYTE* pbBits;
WORD* pwBits;
DWORD* pdwBits;
DWORD rmask,gmask,bmask;
int rright, gright, bright;
int rleft, gleft, bleft;
BYTE r, g, b;
WORD wColor;
DWORD dwColor, dwSize;
LOGPALETTE* plp;
HPALETTE hPalette;
NODE* pTree;
UINT nLeafCount, nIndex;
NODE* pReducibleNodes[9];
HDC hdc;
BYTE* pBuffer;
BITMAPINFO bmi;
//Initialize octree variables
pTree = NULL;
nLeafCount = 0;
if (nColorBits > 8) // Just in case
return NULL;
for (i=0; i<=(int) nColorBits; i++)
pReducibleNodes[i] = NULL;
// Scan the DIB and build the octree
GetObject(hImage, sizeof (ds), &ds);
nPad = ds.dsBm.bmWidthBytes-(((ds.dsBmih.biWidth *
ds.dsBmih.biBitCount)+7)/8);
switch (ds.dsBmih.biBitCount)
{
case 1:// 1-bit DIB
case 4:// 4-bit DIB
case 8:// 8-bit DIB
// The strategy here is to use ::GetDlBits to convert the
// image into a 24-bit DIR one scan line at a time. A pleasant
// side effect of using ::GetDlBits in this manner is that RLE-
// encoded 4-bit and 8-bit DIBs will be uncompressed.
hdc = GetDC (NULL);
pBuffer = new BYTE[ds.dsBmih.biWidth * 3];
ZeroMemory(&bmi, sizeof (bmi));
bmi .bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi .bmiHeader.biWidth = ds.dsBmih.biWidth;
bmi .bmiHeader.biHeight = ds.dsBmih.biHeight;
bmi .bmiHeader.biPlanes = 1;
bmi. bmiHeader.biBitCount = 24;
bmi. bmiHeader.biCompression = BI_RGB;
for (i=0; i nMaxColors)
ReduceTree(nColorBits, &nLeafCount,
pReducibleNodes);
}
}
delete pBuffer;
ReleaseDC (NULL, hdc);
break;
case 16: // One case for 16-bit DIBs
if (ds.dsBmih.biCompression == BI_BITFIELDS)
{
rmask = ds.dsBitfields[0];
gmask = ds.dsBitfields[1];
bmask = ds.dsBitfields[2];
}
else
{
rmask = 0x7C00;
gmask = 0x03E0;
bmask = 0x001F;
}
rright = GetRightShiftCount (rmask);
gright = GetRightShiftCount (gmask);
bright = GetRightShiftCount (bmask);
rleft = GetLeftShiftCount (rmask);
gleft = GetLeftShiftCount (gmask);
bleft = GetLeftShiftCount (bmask);
pwBits = (WORD*) ds.dsBm.bmBits;
for (i=0; i>bright)<>gright)<>rright)<nMaxColors)
ReduceTree (nColorBits, &nLeafCount,
pReducibleNodes);
}
pwBits=(WORD*)(((BYTE*)pwBits)+nPad);
}
break;
case 24: // Another for 24-bit DIBS
pbBits=(BYTE*)ds.dsBm.bmBits;
for (i=0; i nMaxColors)
ReduceTree(nColorBits,&nLeafCount,
pReducibleNodes);
}
pbBits+=nPad;
}
break;
case 32: // And another for 32-bit DIEs
if(ds.dsBmih.biCompression == BI_BITFIELDS)
{
rmask = ds.dsBitfields[0];
gmask = ds.dsBitfields[1];
bmask = ds.dsBitfields[2];
}
else
{
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
}
rright = GetRightShiftCount (rmask);
gright = GetRightShiftCount (gmask);
bright = GetRightShiftCount (bmask);
pdwBits =(DWORD*) ds.dsBm.bmBits;
for (i=0; i>bright);
g=(BYTE)((dwColor & gmask)>>gright);
r=(BYTE)((dwColor & rmask)>>rright);
AddColor(&pTree,r,g,b,nColorBits,0,&nLeafCount,
pReducibleNodes);
while(nLeafCount > nMaxColors)
ReduceTree(nColorBits, &nLeafCount,
pReducibleNodes);
}
pdwBits=(DWORD*)(((BYTE*) pdwBits) + nPad);
}
break;
default: // nIB must be 16, 24, or 32bit!
return NULL;
break;
}
if(nLeafCount > nMaxColors)
{ // Sanity check
DeleteTree (&pTree);
return NULL;
}
// Create a logical palette front the colors in the octree
dwSize=sizeof(LOGPALETTE) +
((nLeafCount-1)*sizeof(PALETTEENTRY));
if((plp= (LOGPALETTE*) HeapAlloc(GetProcessHeap(),0,
dwSize))== NULL)
{
DeleteTree (&pTree);
return NULL;
}
plp->palVersion = 0x300;
plp->palNumEntries = (WORD) nLeafCount;
nIndex=0;
GetPaletteColors(pTree,plp->palPalEntry,&nIndex);
hPalette=CreatePalette (plp);
HeapFree(GetProcessHeap(),0,plp);
DeleteTree(&pTree);
return hPalette;
}
//***********************************************
// void AddColor(NODE** ppNode,BYTE r,BYTE g,BYTE b,UINT nColorBits,
// UINT nLevel,UINT* pLeafCount,NODE** pReducibleNodes)
// **********************************************
// local function to add a color to octree
void AddColor(NODE** ppNode,BYTE r,BYTE g,BYTE b,UINT nColorBits,
UINT nLevel,UINT* pLeafCount,NODE** pReducibleNodes)
{
int nIndex,shift;
static BYTE mask[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
// If the node doesn't exist, create it
if (*ppNode==NULL)
*ppNode=CreateNode(nLevel,nColorBits,pLeafCount,
pReducibleNodes);
// Update color information if it's a leaf node
if ((*ppNode)->bIsLeaf)
{
(*ppNode) ->nPixelCount++;
(*ppNode) ->nRedSum+= r;
(*ppNode)->nGreenSum+= g;
(*ppNode)->nBlueSum+= b;
}
// Recurse a level deeper if the node is not a leaf
else
{
shift =7 - nLevel;
nIndex=(((r&mask[nLevel])>>shift)<<2)|
(((g&mask[nLevel])>>shift)<<1)|
((b&mask[nLevel])>>shift);
AddColor(&((*ppNode)->pChild[nIndex]),r,g,b,nColorBits,
nLevel+1,pLeafCount,pReducibleNodes);
}
}
//***********************************************
// NODE* CreateNode(UINT nLevel,UINT nColorBits,UINT* pLeafCount,
// NODE** pReducibleNodes)
// **********************************************
// local function to create a new node in octree
NODE* CreateNode(UINT nLevel,UINT nColorBits,UINT* pLeafCount,
NODE** pReducibleNodes)
{
NODE* pNode;
if((pNode = (NODE*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,sizeof (NODE))) == NULL)
return NULL;
pNode->bIsLeaf=(nLevel== nColorBits)?TRUE:FALSE;
if (pNode->bIsLeaf)
(*pLeafCount) ++;
else
{ // Add the node to the reducible list for this level
pNode->pNext= pReducibleNodes[nLevel];
pReducibleNodes[nLevel] = pNode;
}
return pNode;
}
//***********************************************
// void ReduceTree(UINT nColorBits,UINT* pLeafCount,
// NODE** pReducibleNodes)
// **********************************************
// local function to reduce the nodes of octree
void ReduceTree(UINT nColorBits,UINT* pLeafCount,
NODE** pReducibleNodes)
{
int i;
NODE* pNode;
UINT nRedSum, nGreenSum, nBlueSum, nChildren;
// Find the deepest level containing at least ,one reducible node
for(i=nColorBits - 1;(i>0) &&(pReducibleNodes[i]==NULL);i--);
// Reduce the node most recently added to the list at level i
pNode = pReducibleNodes[i];
pReducibleNodes[i]= pNode->pNext;
nRedSum = nGreenSum = nBlueSum = nChildren = 0;
for (i=0; i<8; i++)
{
if (pNode->pChild[i]!= NULL)
{
nRedSum += pNode->pChild[i]->nRedSum;
nGreenSum += pNode->pChild[i]->nGreenSum;
nBlueSum += pNode->pChild[i]->nBlueSum;
pNode->nPixelCount += pNode->pChild[i]->nPixelCount;
HeapFree(GetProcessHeap(),0,pNode->pChild[i]);
pNode->pChild[i] = NULL;
nChildren++;
}
}
pNode->bIsLeaf=TRUE;
pNode->nRedSum = nRedSum;
pNode->nGreenSum = nGreenSum;
pNode->nBlueSum = nBlueSum;
*pLeafCount -= (nChildren - 1);
}
//***********************************************
// void DeleteTree (NODE** ppNode)
//
// **********************************************
// local function to delete a node of octree
void DeleteTree (NODE** ppNode)
{
int i;
for (i=0; i<8; i++)
{
if((*ppNode)->pChild[i]!=NULL)
DeleteTree(&((*ppNode)->pChild[i]));
}
HeapFree(GetProcessHeap (), 0, *ppNode);
*ppNode = NULL;
return;
}
//***********************************************
// void GetPaletteColors (NODE* pTree,PALETTEENTRY* pPalEntries,
// UINT* pIndex)
// **********************************************
// local function to get color entry from a palette
void GetPaletteColors (NODE* pTree,PALETTEENTRY* pPalEntries,
UINT* pIndex)
{
int i;
if (pTree->bIsLeaf)
{
pPalEntries[*pIndex].peRed =
(BYTE)((pTree->nRedSum)/(pTree->nPixelCount));
pPalEntries[*pIndex].peGreen=
(BYTE)((pTree->nGreenSum)/(pTree->nPixelCount));
pPalEntries[*pIndex].peBlue =
(BYTE)((pTree->nBlueSum)/(pTree->nPixelCount));
(*pIndex) ++;
}
else
{
for (i=0; i<8; i++)
{
if (pTree->pChild[i] != NULL)
GetPaletteColors(pTree->pChild[i], pPalEntries, pIndex);
}
}
}
//***********************************************
// int GetRightShiftCount (DWORD dwVal)
//
// **********************************************
//local function to get pixel count
int GetRightShiftCount (DWORD dwVal)
{
int i;
for (i=0; i>=1;
}
return -1;
}
//***********************************************
// int GetLeftShiftCount (DWORD dwVal)
//
// **********************************************
//local function to get pixel count
int GetLeftShiftCount (DWORD dwVal)
{
int nCount, i;
nCount = 0;
for (i=0; i>=1;
}
return(8-nCount);
}
//***********************************************
// HDIB ColorQuantizeDIB(HDIB hDIB,UINT nColorBits,UINT nMaxColors)
//
// **********************************************
HDIB ColorQuantizeDIB(HDIB hDIB,UINT nColorBits,UINT nMaxColors)
{
HPALETTE hPal=NULL;
WaitCursorBegin();
LPBYTE lpDIB=(LPBYTE)GlobalLock(hDIB);
hPal=CreateOctreePalette(lpDIB,nMaxColors,nColorBits);
GlobalUnlock(hDIB);
LPBITMAPINFO lpbi;
lpbi=(LPBITMAPINFO)GlobalLock(hDIB);
if(!lpbi)
return NULL;
HDIB hNewDIB=ConvertDIBFormat((LPBYTE)lpbi,lpbi->bmiHeader.biWidth,
lpbi->bmiHeader.biHeight,nColorBits,FALSE,hPal);
GlobalUnlock(hDIB);
WaitCursorEnd();
return hNewDIB;
}
//颜色空间相互转换函数
void HSItoRGB(double h,double s,double i,
BYTE *r,BYTE *g,BYTE *b)
{
double V1 =s*cos(h);
double V2 =s*sin(h);
int iR=(int)(0.816496*V2+0.57735*i);
int iG=(int)(0.7071 *V1-0.40824*V2+0.57735*i);
int iB=(int)(-0.7071 *V1-0.40824*V2+0.57735*i);
*r= BOUND(iR, 0, 255);
*g= BOUND(iG, 0, 255);
*b= BOUND(iB, 0, 255);
return;
}
void RGBtoHSI(BYTE r,BYTE g,BYTE b,
double *h,double *s,double *i)
{
double V1 = 0.7071*((double)g-(double)b);
double V2 = 0.816496*(double)r-0.40824*((double)g+(double)b);
*h=atan2(V1, V2);
*s=sqrt(V1*V1+V2*V2);
*i=0.57735*((double)r+(double)g+(double)b);
}
//local function used in RLStoRGB
double Value(double n1, double n2, double hue)
{
if (hue > 360.0)
hue -= 360.0;
else if (hue < 0.0)
hue += 360.0;
if (hue < 60.0)
return (n1+(n2-n1)*hue/60.0);
else if (hue < 180.0)
return n2;
else if (hue < 240.0)
return (n1+(n2-n1)*(240.0-hue)/60.0);
else
return n1;
}
void HLStoRGB(double h,double l,double s,
BYTE *r,BYTE *g, BYTE *b)
{
double m1, m2;
double R,G,B;
if (l <= 0.5)
m2 = l*(1.0+s);
else
m2 = l+s-l*s;
m1 =2.0*l-m2;
if (s == 0)
{
if (h == UNDEFINED)
R = G = B = 1;
else // error!!
R= G = B = 0.0;
}
else
{
R = Value(m1, m2, h+120.0);
G = Value(m1, m2, h);
B = Value(m1, m2, h-120.0);
}
int iR = (int) (R*255.0);
int iG = (int) (G*255.0);
int iB = (int) (B*255.0);
*r= (BYTE)BOUND(iR, 0, 255);
*g= (BYTE)BOUND(iG, 0, 255);
*b= (BYTE)BOUND(iB, 0, 255);
return;
}
void RGBtoHLS(BYTE r,BYTE g,BYTE b,
double *h,double *l,double *s)
{
double mx,mn,delta;
double R, G, B;
R = (double)r/255.0;
G = (double)g/255.0;
B = (double)b/255.0;
mx = max(R, max(G, B));
mn = min(R, min(G, B));
*l = (mx+mn)/2.0;
if (mx == mn)
{
*s = 0.0;
*h= UNDEFINED; // undefined!
}
else
{
delta = mx-mn;
if (*l < 0.5)
*s = delta/(mx+mn);
else
*s = delta/(2.0-mx-mn);
if (R == mx)
*h = (G-B)/delta;
else if (G == mx)
*h = 2.0+(B-R)/delta;
else if (B == mx)
*h = 4.0+(R-G)/delta;
*h *= 60.0;
if (*h < 0.0)
*h += 360.0;
else if (*h > 360.0)
*h -= 360.0;
}
return;
}
void RGBtoHSV(BYTE r,BYTE g,BYTE b,
double *h,double *s,double *v)
{
double mx,mn,d;
double R, G, B;
R = (double)r/255.0;
G = (double)g/255.0;
B = (double)b/255.0;
mx = max(R, max(G, B));
mn = min(R, min(G, B));
*v=mx;d=mx-mn;
if(mx) *s=d/mx;
else *s=0.0;
if(fabs(d)>0.0001)
{
if(mx==R) *h=(G-B)/d;
if(mx==G) *h=2.0+(B-R)/d;
if(mx==B) *h=4.0+(R-G)/d;
}
else *h=0.0;
*h=(*h)/6.0;
if((*h)<0.0) *h=(*h)+1.0;
return;
}
void RGBtoHS(BYTE r,BYTE g,BYTE b,
double *h,double *s)
{
double mx,mn,d;
double R, G, B;
R = (double)r/255.0;
G = (double)g/255.0;
B = (double)b/255.0;
mx = max(R, max(G, B));
mn = min(R, min(G, B));
//*v=mx;
d=mx-mn;
if(mx) *s=d/mx;
else *s=0.0;
if(fabs(d)>0.0001)
{
if(mx==R) *h=(G-B)/d;
if(mx==G) *h=2.0+(B-R)/d;
if(mx==B) *h=4.0+(R-G)/d;
}
else *h=0.0;
*h=(*h)/6.0;
if((*h)<0.0) *h=(*h)+1.0;
return;
}
void CMYKtoRGB(BYTE c,BYTE m,BYTE y,BYTE k,
BYTE *r,BYTE *g,BYTE *b)
{
c +=k;
m +=k;
y +=k;
*r=255-c;
*g=255-m;
*b=255-y;
return;
}
void RGBtoCMYK(BYTE r,BYTE g,BYTE b,
BYTE *c,BYTE *m,BYTE *y,BYTE *k)
{
*c=255-r;
*m=255-g;
*y=255-b;
*k=min(*c,min(*m,*y));
*c-=*k;
*m-=*k;
*y-=*k;
return;
}
BOOL RGBToShort2HS(LPBITMAPINFOHEADER lpbi,LPBYTE lpdib,
short *lpDataH,short *lpDataS)
{
BYTE r, g, b;
double s, h,v;
int nx,ny,index;
if((lpbi == NULL)|(lpdib == NULL)) return FALSE;
// get color number
int nDelta=WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)
-lpbi->biWidth*lpbi->biBitCount/8;
WORD wNumColors = DIBNumColors((LPBYTE)lpbi);
if (wNumColors) // There is palette
{
RGBQUAD *lpRGB=(RGBQUAD *)((LPSTR)lpbi+lpbi->biSize);
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
index=(BYTE)(*(lpdib));
r=lpRGB[index].rgbRed ;
g=lpRGB[index].rgbGreen;
b=lpRGB[index].rgbBlue;
RGBtoHSV(r,g,b,&h,&s,&v);
*lpDataH=(short)(h*100);
*lpDataS=(short)(s*100);
lpdib++;lpDataH++;lpDataS++;
}
lpdib += nDelta;
}
}
else // No palette
{
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
b = (BYTE)*(lpdib);
g = (BYTE)*(lpdib+1);
r = (BYTE)*(lpdib+2);
RGBtoHSV(r,g,b,&h,&s,&v);
*lpDataH=(short)(h*1000);
// *lpDataS=(short)(s*100);
lpdib=lpdib+3;
lpDataH++;
// lpDataS++;
}
lpdib += nDelta;
}
}
return TRUE;
}
BOOL AdjustDIBColor(HDIB hDib, int nColorModel,int v1,
int v2, int v3)
{
BYTE r, g, b, c, m, y, k;
int dr, dg, db, dc, dm, dy;
double dh, ds, dv, dl, h, s, v, l;
if (hDib == NULL)
return FALSE;
BITMAPINFO *bmi = (BITMAPINFO *)GlobalLock(hDib);
if (!bmi)
return FALSE;
WaitCursorBegin ();
switch (nColorModel)
{
case RGB_COLOR:
dr = v1;
dg = v2;
db = v3;
break;
case CMYK_COLOR:
dc = v1;
dm = v2;
dy = v3;
break;
case HSI_COLOR:
if (v1 < 0)
v1 += 360;
dh = v1;
ds = v2;
dv = v3;
break;
case HLS_COLOR:
if (v1 < 0)
v1 += 360;
dh = v1;
dl = v2/100.0;
ds = v3/100.0;
break;
}
// get color number
WORD wNumColors = DIBNumColors((LPBYTE)bmi);
if (wNumColors) // There is palette
{
WORD i;
switch (nColorModel)
{
case RGB_COLOR:
for (i=0; ibmiColors[i].rgbRed =
BOUND(bmi->bmiColors[i].rgbRed+dr,0,255);
bmi->bmiColors[i].rgbGreen=
BOUND(bmi->bmiColors[i].rgbGreen+dg,0,255);
bmi->bmiColors[i].rgbBlue =
BOUND(bmi->bmiColors[i].rgbBlue+db,0,255);
}
break;
case CMYK_COLOR:
for (i=0; ibmiColors[i].rgbRed;
g = bmi->bmiColors[i].rgbGreen;
b = bmi->bmiColors[i].rgbBlue;
RGBtoCMYK(r,g,b,&c,&m,&y,&k);
c += dc;
m += dm;
y += dy;
CMYKtoRGB(c,m,y,k,&r,&g,&b);
bmi->bmiColors[i].rgbRed = r;
bmi->bmiColors[i].rgbGreen= g;
bmi->bmiColors[i].rgbBlue = b;
}
break;
case HSI_COLOR:
for (i=0; ibmiColors[i].rgbRed;
g = bmi->bmiColors[i].rgbGreen;
b = bmi->bmiColors[i].rgbBlue;
RGBtoHSI(r,g,b,&h,&s,&v);
h += dh;
s += ds;
v += dv;
HSItoRGB(h,s,v,&r,&g,&b);
bmi->bmiColors[i].rgbRed = r;
bmi->bmiColors[i].rgbGreen= g;
bmi->bmiColors[i].rgbBlue = b;
}
break;
case HLS_COLOR:
for (i=0; ibmiColors[i].rgbRed;
g = bmi->bmiColors[i].rgbGreen;
b = bmi->bmiColors[i].rgbBlue;
RGBtoHLS(r,g,b,&h,&l,&s);
if (h != UNDEFINED)
h = BOUND(h+dh, 0.0, 360.0);
l = BOUND(l+dl, 0.0, 1.0);
s = BOUND(s+ds, 0.0, 1.0);
HLStoRGB(h,l,s,&r,&g,&b);
bmi->bmiColors[i].rgbRed = r;
bmi->bmiColors[i].rgbGreen= g;
bmi->bmiColors[i].rgbBlue = b;
}
break;
} //switch end
} //if end
else // No palette
{
// bits position
LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)bmi;
LPBYTE lpBits=(LPBYTE)lpbi+lpbi->biSize;
int nDelta=WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)
-lpbi->biWidth*lpbi->biBitCount/ 8;
int nx,ny;
switch (nColorModel)
{
case RGB_COLOR:
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
*lpBits++ = BOUND(b+db, 0, 255);
*lpBits++ = BOUND(g+dg, 0, 255);
*lpBits++ = BOUND(r+dr, 0, 255);
}
lpBits += nDelta;
}
break;
case CMYK_COLOR:
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
RGBtoCMYK(r,g,b,&c,&m,&y,&k);
c += dc;
m += dm;
y += dy;
CMYKtoRGB(c,m,y,k,&r,&g,&b);
*lpBits++ =b;
*lpBits++ =g;
*lpBits++ =r;
}
lpBits += nDelta;
}
break;
case HSI_COLOR:
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
RGBtoHSI(r,g,b,&h,&s,&v);
h += dh;
s += ds;
v += dv;
HSItoRGB(h,s,v,&r,&g,&b);
*lpBits++ = b;
*lpBits++ = g;
*lpBits++ = r;
}
lpBits += nDelta;
}
break;
case HLS_COLOR:
for (ny=0; nybiHeight; ny++)
{
for (nx=0; nxbiWidth; nx++)
{
b = (BYTE)*(lpBits);
g = (BYTE)*(lpBits+1);
r = (BYTE)*(lpBits+2);
RGBtoHLS(r,g,b,&h,&l,&s);
if (h != UNDEFINED)
h = BOUND(h+dh, 0.0, 360.0);
l = BOUND(l+dl, 0.0, 1.0);
s = BOUND(s+ds, 0.0, 1.0);
HLStoRGB(h,l,s,&r,&g,&b);
*lpBits++ = b;
*lpBits++ = g;
*lpBits++ = r;
}
lpBits += nDelta;
}
break;
} //switch end
} //else end
GlobalUnlock (hDib);
WaitCursorEnd();
return TRUE;
}
//亮度调整
void ChangeBrightness(int nDelta,BYTE *r,BYTE *g,BYTE *b)
{
int R=*r+nDelta;
int G=*g+nDelta;
int B=*b+nDelta;
*r=(BYTE)BOUND(R,0,255);
*g=(BYTE)BOUND(G,0,255);
*b=(BYTE)BOUND(B,0,255);
return;
}
BOOL AdjustDIBBrightness(HDIB hDib,int v)
{
if(hDib==NULL)
return FALSE;
BITMAPINFO *bmi=(BITMAPINFO *)GlobalLock(hDib);
if(!bmi)
return FALSE;
WaitCursorBegin();
WORD wNumColors=DIBNumColors((LPBYTE)bmi);
if(wNumColors)
{
for(WORD i=0;ibmiColors[i].rgbRed),
&(bmi->bmiColors[i].rgbGreen),
&(bmi->bmiColors[i].rgbBlue));
}
}
else //No Palette
{
LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)bmi;
LPBYTE lpBits=(LPBYTE)lpbi+lpbi->biSize;
int nDelta=WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)
-lpbi->biWidth*lpbi->biBitCount/8;
BYTE r,g,b;
for(int ny=0;nybiHeight;ny++)
{
for(int nx=0;nxbiWidth;nx++)
{
b=(BYTE)*(lpBits);
g=(BYTE)*(lpBits+1);
r=(BYTE)*(lpBits+2);
ChangeBrightness(v,&r,&g,&b);
*lpBits++=b;
*lpBits++=g;
*lpBits++=r;
}
lpBits+=nDelta;
}
}
GlobalUnlock(hDib);
WaitCursorEnd();
return TRUE;
}
//对比度调整
void IncreaseContrast(BYTE *pByte,const int Low,
const int High, const float Grad)
{
if(*pByte<=Low)
*pByte=0;
else if((Low<(*pByte))&&(*pByte=0)
{
int Low=0+nDelta;
int Hight=255-nDelta;
float Grad=((float)(Hight-Low))/255;
IncreaseContrast(r,Low,Hight,Grad);
IncreaseContrast(g,Low,Hight,Grad);
IncreaseContrast(b,Low,Hight,Grad);
}
else
{
float Grad=255/(255+(float)nDelta+(float)nDelta);
DecreaseContrast(r,nDelta,Grad);
DecreaseContrast(g,nDelta,Grad);
DecreaseContrast(b,nDelta,Grad);
}
return;
}
BOOL AdjustDIBContrast(HDIB hDib,int v)
{
if(hDib==NULL)
return FALSE;
BITMAPINFO *bmi=(BITMAPINFO *)GlobalLock(hDib);
if(!bmi)
return FALSE;
WORD wNumColors=DIBNumColors((LPBYTE)bmi);
if(wNumColors)
{
for(WORD i=0;ibmiColors[i].rgbRed),
&(bmi->bmiColors[i].rgbGreen),
&(bmi->bmiColors[i].rgbBlue));
}
}
else//No Palette
{
LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)bmi;
LPBYTE lpBits=(LPBYTE)lpbi+lpbi->biSize;
int nDelta=WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)
-lpbi->biWidth*lpbi->biBitCount/8;
BYTE r,g,b;
for(int ny=0;nybiHeight;ny++)
{
for(int nx=0;nxbiWidth;nx++)
{
b=(BYTE)*(lpBits);
g=(BYTE)*(lpBits+1);
r=(BYTE)*(lpBits+2);
ChangeContrast(v,&r,&g,&b);
*lpBits++=b;
*lpBits++=g;
*lpBits++=r;
}
lpBits+=nDelta;
}
}
GlobalUnlock(hDib);
WaitCursorEnd();
return TRUE;
}
//***********************************************
// 图象处理函数
// **********************************************
//***********************************************************************
//* Parameters:
//* HDIB hDib - objective DIB handle
//* KERNEL *lpKernel - pointer of kernel used to convolute with DIB
//* int Strength - operation strength set to the convolute
//* int nKernelNum - kernel number used to convolute
//* Return Value:
//* BOOL - True is success, else False
//* Description:
//* This is the generic convolute function to DIB
//*************************************************************************
BOOL ConvoluteDIB24(HDIB hDib,KERNEL *lpKernel,int Strength,
int nKernelNum)
{
WaitCursorBegin ();
HDIB hNewDib=NULL;
// we only convolute 24bpp DIB, so first convert DIB to 24bpp
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 24)
{
//hNewDib = ConvertDlBFormat(hDib, 24, NULL);
return FALSE;
}
else
hNewDib = CopyHandle(hDib);
if (! hNewDib)
{
WaitCursorEnd();
return FALSE;
}
// new DIB attributes
WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
WORD wDIBHeight =(WORD)DIBHeight(hNewDib);
WORD wBytesPerLine =(WORD)BytesPerLine(hNewDib);
DWORD dwImageSize = wBytesPerLine * wDIBHeight;
// Allocate and lock memory for filtered image data
HGLOBAL hFilteredBits = GlobalAlloc(GHND,dwImageSize);
if (!hFilteredBits)
{
WaitCursorEnd();
return FALSE;
}
LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits);
// get bits address in DIB
LPBYTE lpDIB = (LPBYTE) GlobalLock (hNewDib);
LPBYTE lpDIBits = FindDIBBits(lpDIB);
// convolute...
for (int i=1;i red)
red = r;
if (g > green)
green = g;
if (b > blue)
blue = b;
//red += r; green += g; blue += b;
}
// original RGB value in center pixel (j, i)
LONG lOffset= PIXEL_OFFSET24(i,j,wBytesPerLine);
BYTE OldB = *(lpDIBits + lOffset++);
BYTE OldG = *(lpDIBits + lOffset++);
BYTE OldR = *(lpDIBits + lOffset);
// When we get here, red, green and blue have the new RGB value.
if (Strength != 10)
{
// Interpolate pixel data
red=OldR+(((red-OldR)*Strength)/10);
green =OldG+(((green-OldG)*Strength)/10);
blue = OldB+(((blue-OldB)*Strength)/10);
}
lOffset= PIXEL_OFFSET24(i,j, wBytesPerLine);
*(lpDestImage+lOffset++)= BOUND(blue, 0, 255);
*(lpDestImage+lOffset++)= BOUND(green, 0, 255);
*(lpDestImage+lOffset) = BOUND(red, 0, 255);
}
// a filtered image is available in lpDestlmage
// copy it to DIB bits
memcpy (lpDIBits, lpDestImage, dwImageSize);
// cleanup temp buffers
GlobalUnlock (hFilteredBits);
GlobalFree (hFilteredBits);
GlobalUnlock (hNewDib);
// rebuild hDib
HDIB hTmp = NULL;
if (wBitCount != 24)
{
return FALSE;
//hTmp = ConvertDlBFormat(hNewDib, wBitCount, NULL);
}
else
hTmp = CopyHandle(hNewDib);
GlobalFree (hNewDib);
DWORD dwSize = GlobalSize(hTmp);
memcpy((LPBYTE)GlobalLock(hDib),
(LPBYTE)GlobalLock(hTmp),dwSize);
GlobalUnlock (hTmp);
GlobalFree (hTmp);
GlobalUnlock (hDib);
WaitCursorEnd();
return TRUE;
}
// local function: perform convolution to DIB with a kernel
void DoConvoluteDlB24(int *red,int *green,int *blue,int i,
int j,WORD wBytesPerLine,
LPBYTE lpDIBits, KERNEL *lpKernel)
{
BYTE b[9], g[9],r[9];
LONG lOffset;
int k1,k2;
k1=i-1;k2=j-1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[0]=*(lpDIBits + lOffset++);
g[0]=*(lpDIBits + lOffset++);
r[0]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[1]=*(lpDIBits + lOffset++);
g[1]=*(lpDIBits + lOffset++);
r[1]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[2]=*(lpDIBits + lOffset++);
g[2]=*(lpDIBits + lOffset++);
r[2]=*(lpDIBits + lOffset);
k1=i;k2=j-1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[3]=*(lpDIBits + lOffset++);
g[3]=*(lpDIBits + lOffset++);
r[3]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[4]=*(lpDIBits + lOffset++);
g[4]=*(lpDIBits + lOffset++);
r[4]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[5]=*(lpDIBits + lOffset++);
g[5]=*(lpDIBits + lOffset++);
r[5]=*(lpDIBits + lOffset);
k1=i+1;k2=j-1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[6]=*(lpDIBits + lOffset++);
g[6]=*(lpDIBits + lOffset++);
r[6]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[7]=*(lpDIBits + lOffset++);
g[7]=*(lpDIBits + lOffset++);
r[7]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET24(k1,k2, wBytesPerLine);
b[8]=*(lpDIBits + lOffset++);
g[8]=*(lpDIBits + lOffset++);
r[8]=*(lpDIBits + lOffset);
*red=*green =*blue = 0;
for (int k=0; k<8; ++k)
{
*red +=lpKernel->Element[k]*r[k];
*green+=lpKernel->Element[k]*g[k];
*blue +=lpKernel->Element[k]*b[k];
}
if (lpKernel->Divisor!= 1)
{
*red /=lpKernel->Divisor;
*green/=lpKernel->Divisor;
*blue /=lpKernel->Divisor;
}
//getoff opposite
*red = abs(*red);
*green = abs(*green);
*blue = abs(*blue);
return;
}
//***********************************************************************
//* Parameters:
//* HDIB hDib - objective DIB handle
//* KERNEL *lpKernel - pointer of kernel used to convolute with DIB
//* int Strength - operation strength set to the convolute
//* int nKernelNum - kernel number used to convolute
//* Return Value:
//* BOOL - True is success, else False
//* Description:
//* This is the generic convolute function to DIB
//*************************************************************************
BOOL ConvoluteDIB08(HDIB hDib,KERNEL *lpKernel,int Strength,
int nKernelNum)
{
WaitCursorBegin ();
HDIB hNewDib=NULL;
// we only convolute 24bpp DIB, so first convert DIB to 24bpp
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 8)
{
//hNewDib = ConvertDlBFormat(hDib, 24, NULL);
return FALSE;
}
else
hNewDib = CopyHandle(hDib);
if (! hNewDib)
{
WaitCursorEnd();
return FALSE;
}
// new DIB attributes
WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
WORD wDIBHeight =(WORD)DIBHeight(hNewDib);
WORD wBytesPerLine =(WORD)BytesPerLine(hNewDib);
DWORD dwImageSize = wBytesPerLine * wDIBHeight;
// Allocate and lock memory for filtered image data
HGLOBAL hFilteredBits = GlobalAlloc(GHND,dwImageSize);
if (!hFilteredBits)
{
WaitCursorEnd();
return FALSE;
}
LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits);
// get bits address in DIB
LPBYTE lpDIB = (LPBYTE) GlobalLock (hNewDib);
LPBYTE lpDIBits = FindDIBBits(lpDIB);
// convolute...
for (int i=1;i gray)
gray = g1;
//red += r; green += g; blue += b;
}
// original RGB value in center pixel (j, i)
LONG lOffset= PIXEL_OFFSET08(i,j,wBytesPerLine);
BYTE OldGray = *(lpDIBits + lOffset);
// When we get here, red, green and blue have the new RGB value.
if (Strength != 10)
{
// Interpolate pixel data
gray=OldGray+(((gray-OldGray)*Strength)/10);
}
lOffset= PIXEL_OFFSET08(i,j, wBytesPerLine);
*(lpDestImage+lOffset)= BOUND(gray, 0, 255);
}
// a filtered image is available in lpDestlmage
// copy it to DIB bits
memcpy (lpDIBits, lpDestImage, dwImageSize);
// cleanup temp buffers
GlobalUnlock (hFilteredBits);
GlobalFree (hFilteredBits);
GlobalUnlock (hNewDib);
// rebuild hDib
HDIB hTmp = NULL;
if (wBitCount != 8)
{
return FALSE;
//hTmp = ConvertDlBFormat(hNewDib, wBitCount, NULL);
}
else
hTmp = CopyHandle(hNewDib);
GlobalFree (hNewDib);
DWORD dwSize = GlobalSize(hTmp);
memcpy((LPBYTE)GlobalLock(hDib),
(LPBYTE)GlobalLock(hTmp),dwSize);
GlobalUnlock (hTmp);
GlobalFree (hTmp);
GlobalUnlock (hDib);
WaitCursorEnd();
return TRUE;
}
// local function: perform convolution to DIB with a kernel
void DoConvoluteDlB08(int *gray,int i,int j,WORD wBytesPerLine,
LPBYTE lpDIBits, KERNEL *lpKernel)
{
BYTE g[9];
LONG lOffset;
int k1,k2;
k1=i-1;k2=j-1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[0]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[1]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[2]=*(lpDIBits + lOffset);
k1=i;k2=j-1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[3]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[4]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[5]=*(lpDIBits + lOffset);
k1=i+1;k2=j-1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[6]=*(lpDIBits + lOffset);
k2=j;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[7]=*(lpDIBits + lOffset);
k2=j+1;
lOffset= PIXEL_OFFSET08(k1,k2, wBytesPerLine);
g[8]=*(lpDIBits + lOffset);
*gray = 0;
for (int k=0; k<8; ++k)
*gray+=lpKernel->Element[k]*g[k];
if (lpKernel->Divisor!= 1)
*gray/=lpKernel->Divisor;
//getoff opposite
*gray = abs(*gray);
return;
}
//高通滤波器
BOOL HighPassDIB(HDIB hDib,int Strength,int nAlgorithm)
{
BOOL bSuccess=FALSE;
LPBITMAPINFO lpbm;
lpbm=(LPBITMAPINFO)GlobalLock(hDib);
KERNEL HIGHPASS1={ {-1,-1,-1,-1, 9,-1,-1,-1,-1},1};
KERNEL HIGHPASS2={ { 0,-1, 0,-1, 5,-1, 0,-1, 0},1};
KERNEL HIGHPASS3={ { 1,-2, 1,-2, 5,-2, 1,-2,-1},1};
if(!lpbm)
return FALSE;
int KernelNum=0;
KernelNum=1;
if(lpbm->bmiHeader.biBitCount==8)
{
switch(nAlgorithm)
{
case FILTER1:
bSuccess=ConvoluteDIB08(hDib,&HIGHPASS1,Strength,KernelNum);
break;
case FILTER2:
bSuccess=ConvoluteDIB08(hDib,&HIGHPASS2,Strength,KernelNum);
break;
case FILTER3:
bSuccess=ConvoluteDIB08(hDib,&HIGHPASS3,Strength,KernelNum);
break;
default:
break;
}
}
else
if(lpbm->bmiHeader.biBitCount==24)
{
switch(nAlgorithm)
{
case FILTER1:
bSuccess=ConvoluteDIB24(hDib,&HIGHPASS1,Strength,KernelNum);
break;
case FILTER2:
bSuccess=ConvoluteDIB24(hDib,&HIGHPASS2,Strength,KernelNum);
break;
case FILTER3:
bSuccess=ConvoluteDIB24(hDib,&HIGHPASS3,Strength,KernelNum);
break;
default:
break;
}
}
GlobalUnlock(hDib);
return bSuccess;
}
//低通滤波器
BOOL LowPassDIB(HDIB hDib,int Strength,int nAlgorithm)
{
BOOL bSuccess=FALSE;
LPBITMAPINFO lpbm;
lpbm=(LPBITMAPINFO)GlobalLock(hDib);
KERNEL LOWPASS1={ { 1,1,1,1,1,1,1,1,1 }, 9};
KERNEL LOWPASS2={ { 1,1,1,1,2,1,1,1,1},10 };
KERNEL LOWPASS3={ { 1,2,1,2,4,2,1,2,1},16 };
if(!lpbm)
return FALSE;
int KernelNum=0;
KernelNum=1;
if(lpbm->bmiHeader.biBitCount==8)
{
switch(nAlgorithm)
{
case FILTER1:
bSuccess=ConvoluteDIB08(hDib,&LOWPASS1,Strength,KernelNum);
break;
case FILTER2:
bSuccess=ConvoluteDIB08(hDib,&LOWPASS2,Strength,KernelNum);
break;
case FILTER3:
bSuccess=ConvoluteDIB08(hDib,&LOWPASS3,Strength,KernelNum);
break;
default:
break;
}
}
else
if(lpbm->bmiHeader.biBitCount==24)
{
switch(nAlgorithm)
{
case FILTER1:
bSuccess=ConvoluteDIB24(hDib,&LOWPASS1,Strength,KernelNum);
break;
case FILTER2:
bSuccess=ConvoluteDIB24(hDib,&LOWPASS2,Strength,KernelNum);
break;
case FILTER3:
bSuccess=ConvoluteDIB24(hDib,&LOWPASS3,Strength,KernelNum);
break;
default:
break;
}
}
GlobalUnlock(FALSE);
return bSuccess;
}
//中值滤波
//*********************************************************************
//* This is the media filtering function to DIB
//**********************************************************************
BOOL MedianFilterDIB24(HDIB hDib)
{
WaitCursorBegin ();
HDIB hNewDib = NULL;
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 24)
{
//hNewDib = ConvertDlBFormat(hDib, 24~ NULL);
WaitCursorEnd();
return FALSE;
}
else
hNewDib = CopyHandle(hDib);
if (!hNewDib)
{
WaitCursorEnd();
return FALSE;
}
// new DIB attributes
WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
WORD wDIBHeight = (WORD)DIBHeight (hNewDib);
WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
DWORD dwImageSize = wBytesPerLine*wDIBHeight;
// Allocate and lock memory for filtered image data
HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
if (!hFilteredBits)
{
WaitCursorEnd();
return FALSE;
}
LPBYTE lpDestImage =(LPBYTE)GlobalLock(hFilteredBits);
// get bits address in DIB
LPBYTE lpDIB=(LPBYTE)GlobalLock(hNewDib);
LPBYTE lpDIBits=FindDIBBits(lpDIB);
// convolute..
for (int i=1; i *(BYTE *)e2)
return 1;
return 0;
}
BOOL MedianPassDIB(HDIB hDib)
{
BOOL bSuccess=FALSE;
if(!hDib)
return FALSE;
LPBITMAPINFO lpbm=(LPBITMAPINFO)GlobalLock(hDib);
if(!lpbm)
return FALSE;
if(lpbm->bmiHeader.biBitCount==8)
bSuccess=MedianFilterDIB08(hDib);
else
if(lpbm->bmiHeader.biBitCount==24)
bSuccess=MedianFilterDIB24(hDib);
GlobalUnlock(hDib);
return bSuccess;
}
//二值化函数
BOOL BinaryDIB08(HDIB hDib)
{
WaitCursorBegin ();
HDIB hNewDib = NULL;
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 8)
{
//hNewDib = ConvertDlBFormat(hDib, 24~ NULL);
WaitCursorEnd();
return FALSE;
}
else
hNewDib = CopyHandle(hDib);
if (!hNewDib)
{
WaitCursorEnd();
return FALSE;
}
// new DIB attributes
WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
WORD wDIBHeight = (WORD)DIBHeight (hNewDib);
WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
DWORD dwImageSize = wBytesPerLine*wDIBHeight;
// Allocate and lock memory for filtered image data
HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
if (!hFilteredBits)
{
WaitCursorEnd();
return FALSE;
}
LPBYTE lpDestImage =(LPBYTE)GlobalLock(hFilteredBits);
// get bits address in DIB
LPBYTE lpDIB=(LPBYTE)GlobalLock(hNewDib);
LPBYTE lpDIBits=FindDIBBits(lpDIB);
int GrayTable[25];
int i,j;
for(i=0;i<25;i++)
GrayTable[i]=0;
unsigned short gray;
LONG lOffset;
// convolute..
for (i=1; iGrayTable[i])&&(GrayTable[i]!=0)) min=i;
for (i=1; imin)
*(lpDestImage+lOffset)=255;
else
*(lpDestImage+lOffset)=0;
}
memcpy(lpDIBits, lpDestImage, dwImageSize);
// cleanup temp buffers
GlobalUnlock (hFilteredBits);
GlobalFree (hFilteredBits);
GlobalUnlock (hNewDib);
// rebuild hDib
HDIB hTmp = NULL;
hTmp = CopyHandle(hNewDib);
GlobalFree (hNewDib);
DWORD dwSize = GlobalSize(hTmp);
memcpy ((LPBYTE)GlobalLock(hDib),
(LPBYTE)GlobalLock(hTmp), dwSize);
GlobalUnlock (hTmp);
GlobalFree (hTmp);
GlobalUnlock (hDib);
WaitCursorEnd();
return TRUE;
}
//数据读取函数
BOOL ReadDIB08(LPCTSTR lpDataFile,HDIB hDib)
{
HANDLE fh;
DWORD dwWritten;
fh=CreateFile(lpDataFile,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(fh==INVALID_HANDLE_VALUE)
return FALSE;
WaitCursorBegin ();
WORD wBitCount = DIBBitCount(hDib);
if (wBitCount != 8)
{
WaitCursorEnd();
return FALSE;
}
LPBYTE lpDIB=(LPBYTE)GlobalLock(hDib);
WORD wDIBHeight = (WORD)DIBHeight (hDib);
WORD wBytesPerLine = (WORD)BytesPerLine(hDib);
DWORD dwImageSize = wBytesPerLine*wDIBHeight;
LPBYTE lpDIBits=FindDIBBits(lpDIB);
WriteFile(fh,(LPBYTE)lpDIBits,dwImageSize,&dwWritten,NULL);
GlobalUnlock(hDib);
CloseHandle(fh);
WaitCursorEnd();
if(dwWritten==0)
return FALSE;
else
return TRUE;
}