dibapi.cpp
来自「一个非常全的vc编程的原程序代码是关于图像处理的!」· C++ 代码 · 共 2,454 行 · 第 1/5 页
CPP
2,454 行
return FALSE;
}
//填写Bitmap文件头的内容
bmfHeader.bfType = DIB_HEADER_MARKER;//'BM'
dwDibsize = *(LPDWORD)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 = dwDibsize;
}
bmfHeader.bfSize = dwDibsize+sizeof(BITMAPFILEHEADER);
bmfHeader.bfReserved1 = bmfHeader.bfReserved2=0;
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+lpbi->biSize+DIBNumColors((LPBYTE)lpbi)*sizeof(RGBQUAD);
//将文件头的内容和图像信息写回文件中
WriteFile( hFile,
(LPBYTE)&bmfHeader,
sizeof(BITMAPFILEHEADER),
&dwWritten,
NULL);
WriteFile( hFile,
(LPBYTE)lpbi,
dwDibsize,
&dwWritten,
NULL);
GlobalUnlock(hDib);
CloseHandle(hFile);
if(dwWritten == 0)
return FALSE;
else
return TRUE;
}
/**************************************************
free memory associated with a DIB
parameter: HDIB
return: void
**************************************************/
void DestroyDIB(HDIB hDib)
{
GlobalFree(hDib);
}
/********************************************************
show a DDB with specified area.
parameter: HDC,
LPRECT(show),
HANDLE(to DIB),
LPRECT(DIB),
DWORD(mode)
return: BOOL
********************************************************/
BOOL PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDdb, LPRECT lpDdbRect, HPALETTE hPalette, DWORD dwRop)
{
HDC hMemDC;
HBITMAP hOldBitmap;
HPALETTE hOldPal1 = NULL;
HPALETTE hOldPal2 = NULL;
BOOL bSuccess = FALSE;
hMemDC = CreateCompatibleDC(hDC);
if(!hMemDC)
return FALSE;
if(hPalette)
{
hOldPal1 = SelectPalette(hMemDC,hPalette,TRUE);
hOldPal2 = SelectPalette(hMemDC,hPalette,TRUE);
RealizePalette(hDC);
}
hOldBitmap = (HBITMAP)SelectObject(hDC, hDdb);
SetStretchBltMode(hDC, COLORONCOLOR);
if((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDdbRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDdbRect)))
bSuccess = BitBlt( hDC,
lpDCRect->left,
lpDCRect->top,
lpDCRect->right-lpDCRect->left,
lpDCRect->bottom-lpDCRect->top,
hMemDC,
lpDdbRect->left,
lpDdbRect->top,
dwRop);
else
bSuccess = StretchBlt( hDC,
lpDCRect->left,
lpDCRect->top,
lpDCRect->right-lpDCRect->left,
lpDCRect->bottom-lpDCRect->top,hMemDC,lpDdbRect->left,
lpDdbRect->top,
lpDdbRect->right-lpDdbRect->left,
lpDdbRect->bottom-lpDdbRect->top,
dwRop);
SelectObject(hMemDC, hOldBitmap);
if(hOldPal1)
SelectPalette(hMemDC, hOldPal1, FALSE);
if(hOldPal2)
SelectPalette(hMemDC, hOldPal2, FALSE);
DeleteDC(hDC);
return bSuccess;
}
/*****************************************************
create a palette from DIB file.
parameter: LPBYTE(to DIB)
return: HPALETTE
call: WORD DIBNumColors(LPBYTE)
*****************************************************/
HPALETTE CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal; //到逻辑调色板的指针
HANDLE hLogPal; //到逻辑调色板的句柄
HPALETTE hPal = NULL; //要返回的调色板句柄
LPBITMAPINFO lpbmi; //到BITMAPINFO结构的指针
BOOL bWinStyleDib; //是否为Windows下的位图格式
int i, wNumColors;
//检查到位图的指针是否合法
if(!lpbi)
return NULL;
//得到指向BITMAPINFO结构的指针
lpbmi = (LPBITMAPINFO)lpbi;
//得到位图中的颜色数
wNumColors = DIBNumColors(lpbi);
//是否为Windows下的位图格式?
bWinStyleDib = IS_WIN30_DIB(lpbi);
//颜色数不为0表示需要调色板支持
if(wNumColors)
{
//为逻辑调色板分配内存空间
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(!hLogPal)
return NULL;
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
//填写逻辑调色板的内容
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = wNumColors;
for( i = 0 ;i < wNumColors; i++)
{
if(bWinStyleDib)
{
lpPal->palPalEntry[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
{
//在此不考虑非Window标准格式的位图
}
}
hPal = CreatePalette(lpPal);
if(!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
}
return hPal;
}
/*****************************************************
create a palette from DIB file.
parameter: HDIB
return: HPALETTE
call: WORD DIBNumColors(LPBYTE)
*****************************************************/
HPALETTE CreateDIBPalette(HDIB hDib)
{
LPBYTE lpbi;
lpbi = (LPBYTE)GlobalLock(hDib);
HPALETTE hPal;
hPal = CreateDIBPalette(lpbi);
GlobalUnlock(hDib);
return hPal;
}
/********************************************************
show a DIB with specified area.
parameter: HDC hdc --显示设备上下文
LPRECT lpDCRect --显示设备的区域
HANDLE hDib --位图句柄
LPRECT lpDibRect --位图区域
HPALETTE hPalette --调色板
DWORD dwRop --显示方式
return: BOOL
********************************************************/
BOOL PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDib, LPRECT lpDibRect, HPALETTE hPalette, DWORD dwRop)
{
LPBYTE lpDib; //指向BITMAPINFOHEADER的指针
LPBYTE lpDibbits; //指向图象数据的指针
BOOL bSuccess = FALSE;
HPALETTE hOldPal = NULL;//原有调色板句柄
//检查位图句柄是否合法
if(!hDib)
return FALSE;
//得到指向BITMAPINFOHEADER的指针和指向图象数据的指针
lpDib = (LPBYTE)GlobalLock(hDib);
lpDibbits = lpDib+sizeof(BITMAPINFOHEADER)+DIBNumColors(lpDib)*sizeof(RGBQUAD);
//如果没有提供调色板,则从位图细心中创建一个调色板
if(!hPalette)
hPalette = CreateDIBPalette(lpDib);
//在绘图上下文中采用新的调色板
if(hPalette)
{
hOldPal = SelectPalette(hDC, hPalette, TRUE);
RealizePalette(hDC);
}
//调用函数设置绘图方式并绘图
SetStretchBltMode(hDC, COLORONCOLOR);
bSuccess = StretchDIBits( hDC,
lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDCRect->left,
((LPBITMAPINFOHEADER)lpDib)->biHeight-lpDibRect->top-RECTHEIGHT(lpDibRect),
RECTWIDTH(lpDibRect),
RECTHEIGHT(lpDibRect),
lpDibbits,
(LPBITMAPINFO)lpDib,
DIB_RGB_COLORS,
SRCCOPY);
//清除工作
GlobalUnlock(hDib);
if(hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
return bSuccess;
}
/********************************************************
show a DIB fully.
parameter: CDC*,
LPCSTR(to file)
return: BOOL
********************************************************/
BOOL DisplayDIB(CDC* pDC, LPCSTR lpszBitmap)
{
LPBITMAPINFO lpDib;
LPSTR lpBits;
CPalette *pPal, *pOldPal;
lpDib = (LPBITMAPINFO)LoadDIBFromResource(lpszBitmap);
if(lpDib == NULL)
return FALSE;
lpBits = (LPSTR)lpDib+sizeof(BITMAPINFOHEADER)+DIBNumColors((LPSTR)lpDib)*sizeof(RGBQUAD);
pPal = (CPalette*)CreateDIBPalette((LPBYTE)lpDib);
pOldPal = pDC->SelectPalette(pPal,TRUE);
pDC->RealizePalette();
SetDIBitsToDevice( pDC->GetSafeHdc(),
0,
0,
(int)lpDib->bmiHeader.biWidth,
(int)lpDib->bmiHeader.biHeight,
0,
0,
0,
(UINT)lpDib->bmiHeader.biHeight,
lpBits,
lpDib,
DIB_RGB_COLORS);
pDC->SelectPalette(pOldPal, FALSE);
return TRUE;
}
/**************************************************
Create DIBSection from DIB.
parameter: LPBYTE(lpDIB)
return: HBITMAP
**************************************************/
HBITMAP DIBToDIBSection(LPBYTE lpDib)
{
LPBYTE lpSourceBits;
HDC hDC = NULL, hSourceDC;
HBITMAP hSourceBitmap, 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<<lpSrcDib->bmiHeader.biBitCount,
lpSrcDib->bmiColors);
SelectObject(hSourceDC, hOldSourceBitmap);
DeleteDC(hSourceDC);
ReleaseDC(NULL,hDC);
GdiFlush();
return hSourceBitmap;
}
/**************************************************
Create DIBSection from DIB.
parameter: HDIB
return: HBITMAP
**************************************************/
HBITMAP DIBToDIBSection(HDIB hDib)
{
LPBYTE lpDib;
HBITMAP hBitmap;
lpDib = (LPBYTE)GlobalLock(hDib);
hBitmap = DIBToDIBSection(lpDib);
GlobalUnlock(hDib);
return hBitmap;
}
/**************************************************
create DIB to DIBSection
parameter: HBITMAP
return: HDIB
**************************************************/
HDIB DIBSectionToDIB(HBITMAP hBitmap)
{
HDC hDC = NULL, hSourceDC;
HBITMAP hOldSourceBitmap;
HDIB 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<<ds.dsBmih.biBitCount;
dwSize = sizeof(BITMAPINFOHEADER)+(dwColorNum*sizeof(RGBQUAD))+ds.dsBmih.biSizeImage;
hNewDib = GlobalAlloc(GHND, dwSize);
if(!hNewDib)
return NULL;
lpbmi = (LPBITMAPINFO)GlobalLock(hNewDib);
if(!lpbmi)
return NULL;
lpbmi->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<<lpbmi->bmiHeader.biBitCount,
lpbmi->bmiColors);
SelectObject(hSourceDC, hOldSourceBitmap);
DeleteDC(hSourceDC);
ReleaseDC(NULL, hDC);
GlobalUnlock(hNewDib);
return hNewDib;
}
/***********************************************************
Copy the color table from one CF_DIB to another.
parameter: LPBITMAPINFO(target),
LPBITMAPINFO(source),
HPALETTE
return: BOOL
***********************************************************/
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
{
MessageBox(NULL, "error no match color table", "error", MB_OK);
return FALSE;
}
}
break;
}
case 4:
{
if(hPalSrc)
{
PALETTEENTRY pe[16];
UINT i;
GetPaletteEntries(hPalSrc, 0, 256, 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 == 4)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?