您的位置:首页 > 其它

常用的图像处理小算法

2013-09-25 21:40 405 查看
1.RGB24数据的RGB互换

BOOL BGRFromRGB(BYTE *buf, UINT widthPix, UINT height)

{

if (buf==NULL)

return FALSE;

UINT col, row;

for (row=0;row<height;row++) {

for (col=0;col<widthPix;col++) {

LPBYTE pRed, pGrn, pBlu;

pRed = buf + row * widthPix * 3 + col * 3;

pGrn = buf + row * widthPix * 3 + col * 3 + 1;

pBlu = buf + row * widthPix * 3 + col * 3 + 2;

// 交换红色和蓝色

BYTE tmp;

tmp = *pRed;

*pRed = *pBlu;

*pBlu = tmp;

}

}

return TRUE;

}

2.从一个RGB24数据缓冲得到一个小的矩形RGB24缓冲

void GetPartImage( BYTE* image, int imageWidth, int imageHeight, BYTE* part, int left,int top, int right ,int bottom )

{

int w = right - left;

int h = bottom - top;

UINT nSize=((imageWidth*(24/8)+3)&~3);

for( int i=0; i<h; i++ )

{

for( int j=0; j<w; j++ )

{

part[j*3+i*w*3+0] = image[(left+j)*3+(top+i)*nSize+0];

part[j*3+i*w*3+1] = image[(left+j)*3+(top+i)*nSize+1];

part[j*3+i*w*3+2] = image[(left+j)*3+(top+i)*nSize+2];//imageWidth*3

}

}

}

3.对RGB24重新采样(最近邻算法)

BOOL ResampleBmp(BITMAPINFOHEADER& bih, BYTE* inBuf,int newx,int newy,BYTE* outBuf)

{

if (newx==0 || newy==0) return FALSE;

if (bih.biWidth==newx && bih.biHeight==newy){

if(outBuf)

{

memcpy(outBuf,inBuf,bih.biSizeImage);

}

return TRUE;

}

float xScale, yScale, fX, fY;

xScale = (float)bih.biWidth / (float)newx;

yScale = (float)bih.biHeight / (float)newy;

//DWORD对齐的扫描行的字节宽度

int dwEffWidth1 = ((((bih.biBitCount * bih.biWidth) + 31) / 32) * 4);

bih.biWidth=newx;

bih.biHeight=newy;

int dwEffWidth2 = ((((bih.biBitCount * bih.biWidth) + 31) / 32) * 4);

for(long y=0; y<newy; y++)

{

fY = y * yScale;

for(long x=0; x<newx; x++)

{

fX = x * xScale;

//得到源位图的每个象素点的RGB

BYTE* iSrc = inBuf + (int)fY*dwEffWidth1 + (int)fX*3;

RGBQUAD rgb;

rgb.rgbBlue = *iSrc++;

rgb.rgbGreen= *iSrc++;

rgb.rgbRed = *iSrc;

//设置目标位图的每个象素点的RGB

BYTE* iDst = outBuf + y*dwEffWidth2 + x*3;

*iDst++ = rgb.rgbBlue;

*iDst++ = rgb.rgbGreen;

*iDst = rgb.rgbRed;

}

}

bih.biSizeImage=dwEffWidth2*bih.biHeight;

return TRUE;

}

4.水平或垂直镜像位图

BOOL MirrorDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BOOL bDirection,int nImageBits)

{

// 指向源图像的指针

LPSTR lpSrc;

// 指向要复制区域的指针

LPSTR lpDst;

// 指向复制图像的指针

LPSTR lpBits;

HLOCAL hBits;

// 循环变量

LONG i;

LONG j;

int nBits;//每像素占的位数

// 图像每行的字节数

LONG lLineBytes;

// 计算图像每行的字节数

lLineBytes = WIDTHBYTES(lWidth *nImageBits);

// 暂时分配内存,以保存一行图像

hBits = LocalAlloc(LHND, lLineBytes);

if (hBits == NULL)

{

// 分配内存失败

return FALSE;

}

// 锁定内存

lpBits = (char * )LocalLock(hBits);

int nStep=nImageBits/8;

long lCenter=lWidth/2*nStep;

// 判断镜像方式

if (bDirection)

{

// 水平镜像

// 针对图像每行进行操作

for(i = 0; i < lHeight; i++)

{

// 针对每行图像左半部分进行操作

for(j = 0; j < lCenter; j+=nStep)

{

for(nBits=0;nBits<nStep;nBits++)

{

lpSrc = (char *)lpDIBBits + lLineBytes * i +lCenter- j+nBits;

lpDst = (char *)lpDIBBits + lLineBytes * i +lCenter+ j+nBits;

*lpBits = *lpDst;

*lpDst = *lpSrc;

*lpSrc = *lpBits;

}

}

}

}

else

{

// 垂直镜像

// 针对上半图像进行操作

for(i = 0; i < lHeight / 2; i++)

{

// 指向倒数第i行象素起点的指针

lpSrc = (char *)lpDIBBits + lLineBytes * i;

// 指向第i行象素起点的指针

lpDst = (char *)lpDIBBits + lLineBytes * (lHeight - i - 1);

// 备份一行,宽度为lWidth

memcpy(lpBits, lpDst, lLineBytes);

// 将倒数第i行象素复制到第i行

memcpy(lpDst, lpSrc, lLineBytes);

// 将第i行象素复制到倒数第i行

memcpy(lpSrc, lpBits, lLineBytes);

}

}

// 释放内存

LocalUnlock(hBits);

LocalFree(hBits);

// 返回

return TRUE;

}

5.保存位图到文件

BOOL SaveBufToBmpFile( BYTE* buf, LPBITMAPINFOHEADER lpBih, LPCSTR strFileName )

{

FILE* bmpFile;

bmpFile = fopen( strFileName, "wb" );

if( bmpFile == NULL )

{

return FALSE;

}

BITMAPFILEHEADER bfh;

memset( &bfh, 0, sizeof( bfh ) );

bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+lpBih->biSizeImage;

bfh.bfType = 0x4d42;

bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

fwrite( &bfh, sizeof(bfh), 1, bmpFile );

fwrite( lpBih, sizeof(BITMAPINFOHEADER), 1, bmpFile );

fwrite( buf, lpBih->biSizeImage, 1, bmpFile );

fclose( bmpFile );

return TRUE;

}

BOOL SaveCBitmapToFile(HBITMAP hBitmap, LPCTSTR strFileName)

{

//设备描述表

HDC hDC;

//当前分辨率下每象素所占字节数

int iBits;

//位图中每象素所占字节数

WORD wBitCount;

//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数

DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;

//位图属性结构

BITMAP Bitmap;

//位图文件头结构

BITMAPFILEHEADER bmfHdr;

//位图信息头结构

BITMAPINFOHEADER bi;

//指向位图信息头结构

LPBITMAPINFOHEADER lpbi;

//定义文件,分配内存句柄,调色板句柄

HANDLE fh, hDib, hPal,hOldPal=NULL;

//计算位图文件每个像素所占字节数

hDC = CreateDC("DISPLAY", NULL, NULL, NULL);

iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);

DeleteDC(hDC);

if (iBits <= 1) wBitCount = 1;

else if (iBits <= 4) wBitCount = 4;

else if (iBits <= 8) wBitCount = 8;

else wBitCount = 24;

GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = Bitmap.bmWidth;

bi.biHeight = Bitmap.bmHeight;

bi.biPlanes = 1;

bi.biBitCount = wBitCount;

bi.biCompression = BI_RGB;

bi.biSizeImage = 0;

bi.biXPelsPerMeter = 0;

bi.biYPelsPerMeter = 0;

bi.biClrImportant = 0;

bi.biClrUsed = 0;

dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

//为位图内容分配内存

hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

*lpbi = bi;

// 处理调色板

hPal = GetStockObject(DEFAULT_PALETTE);

if (hPal)

{

hDC = ::GetDC(NULL);

hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);

RealizePalette(hDC);

}

// 获取该调色板下新的像素值

GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)

+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);

//恢复调色板

if (hOldPal)

{

::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);

RealizePalette(hDC);

::ReleaseDC(NULL, hDC);

}

//创建位图文件

fh = CreateFile(strFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (fh == INVALID_HANDLE_VALUE) return FALSE;

// 设置位图文件头

bmfHdr.bfType = 0x4D42; // "BM"

dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;

bmfHdr.bfSize = dwDIBSize;

bmfHdr.bfReserved1 = 0;

bmfHdr.bfReserved2 = 0;

bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;

// 写入位图文件头

WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

// 写入位图文件其余内容

WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);

//清除

GlobalUnlock(hDib);

GlobalFree(hDib);

CloseHandle(fh);

return TRUE;

}

6.加载RGB24位图

BYTE* LoadBmpFromFile(LPCTSTR strFileName,BITMAPINFOHEADER& bih)

{

/*

CFile file;

if(!file.Open(strFileName,CFile::shareDenyRead ))

{

DWORD dwError=GetLastError();

return NULL;

}

BITMAPFILEHEADER bmfheader;

if(file.Read((LPSTR)&bmfheader,sizeof(bmfheader))!=sizeof(bmfheader))

return NULL;

if (bmfheader.bfType!=((WORD)('M'<<8)|'B')) return FALSE;

DWORD nLen=file.GetLength()- sizeof(BITMAPFILEHEADER);

HGLOBAL hDib=::GlobalAlloc(GMEM_FIXED,nLen);

if (hDib==NULL) return NULL;

if (file.ReadHuge((LPSTR)hDib, nLen)!=nLen)

{

::GlobalFree(hDib);

return NULL;

}

BITMAPINFOHEADER *BmIHeader=(LPBITMAPINFOHEADER)hDib;

LPBITMAPINFO BmInfo=(LPBITMAPINFO)hDib;

int nColors=BmIHeader->biClrUsed?BmIHeader->biClrUsed:1<<BmIHeader->biBitCount;

LPVOID lpDibBits;

if(BmInfo->bmiHeader.biBitCount>8)

lpDibBits=(LPVOID)((LPDWORD)(BmInfo->bmiColors+ BmInfo->bmiHeader.biClrUsed)+

((BmInfo->bmiHeader.biCompression==BI_BITFIELDS)?3:0));

else

lpDibBits=(LPVOID)(BmInfo->bmiColors+nColors);

memcpy(&bih,BmIHeader,sizeof(BITMAPINFOHEADER));

// bih.biSizeImage=WIDTHBYTES(bih.biWidth*bih.biBitCount)*bih.biHeight;

bih.biSizeImage=((bih.biWidth*(bih.biBitCount/8)+3)&~3)*bih.biHeight;

// bih.biSizeImage=bih.biWidth*bih.biHeight*3;

BYTE* pDataBuf=new BYTE[bih.biSizeImage];

memcpy(pDataBuf,lpDibBits,bih.biSizeImage);

::GlobalFree(hDib);

file.Close();

return pDataBuf;

*/

HANDLE bmpFile;

bmpFile = CreateFile( strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

if( bmpFile==INVALID_HANDLE_VALUE )

return NULL;

DWORD dwRead;

BITMAPFILEHEADER bfh;

ReadFile( bmpFile, &bfh, sizeof(BITMAPFILEHEADER), &dwRead, NULL );

if( bfh.bfType != 0x4d42 )

{

CloseHandle(bmpFile);

return NULL;

}

ReadFile( bmpFile, &bih, sizeof(BITMAPINFOHEADER), &dwRead, NULL );

if( bih.biBitCount != 24 )

{

CloseHandle( bmpFile );

return NULL;

}

UINT bmpSize = ((bih.biWidth*(bih.biBitCount/8)+3)&~3)*bih.biHeight;

BYTE* imageBuf = new BYTE[bmpSize];

ReadFile( bmpFile, imageBuf, bmpSize, &dwRead, NULL );

bih.biSizeImage=bmpSize;

CloseHandle(bmpFile);

return imageBuf;

}

BOOL LoadBmpFromFile(LPCTSTR strFileName, CBitmap &bmp)

{

CFile file;

if(!file.Open(strFileName,CFile::shareDenyRead ))

{

DWORD dwError=GetLastError();

return FALSE;

}

BITMAPFILEHEADER bmfheader;

if(file.Read((LPSTR)&bmfheader,sizeof(bmfheader))!=sizeof(bmfheader))

return FALSE;

if (bmfheader.bfType!=((WORD)('M'<<8)|'B')) return FALSE;

DWORD nLen=file.GetLength()- sizeof(BITMAPFILEHEADER);

HGLOBAL hDib=::GlobalAlloc(GMEM_FIXED,nLen);

if (hDib==NULL) return FALSE;

if (file.ReadHuge((LPSTR)hDib, nLen)!=nLen)

{

::GlobalFree(hDib);

return FALSE;

}

BITMAPINFOHEADER *BmIHeader=(LPBITMAPINFOHEADER)hDib;

LPBITMAPINFO BmInfo=(LPBITMAPINFO)hDib;

int nColors=BmIHeader->biClrUsed?BmIHeader->biClrUsed:1<<BmIHeader->biBitCount;

LPVOID lpDibBits;

if(BmInfo->bmiHeader.biBitCount>8)

lpDibBits=(LPVOID)((LPDWORD)(BmInfo->bmiColors+ BmInfo->bmiHeader.biClrUsed)+

((BmInfo->bmiHeader.biCompression==BI_BITFIELDS)?3:0));

else

lpDibBits=(LPVOID)(BmInfo->bmiColors+nColors);

CClientDC dc(NULL);

HBITMAP hBmp =::CreateDIBitmap(dc.m_hDC,

BmIHeader,

CBM_INIT,

lpDibBits,

BmInfo,

DIB_RGB_COLORS);

bmp.Attach( hBmp );

::GlobalFree(hDib);

file.Close();

return TRUE;

}

7.从位图数据得到CBitmap

BOOL GetCBitmap(BITMAPINFOHEADER* pBih, BYTE* pDataBuf,CBitmap &bmp)

{

BITMAPINFO bi;

memset( &bi, 0, sizeof(bi) );

memcpy( &(bi.bmiHeader), pBih, sizeof(BITMAPINFOHEADER) );

CClientDC dc(NULL);

HBITMAP hBmp =::CreateDIBitmap(dc.m_hDC,

pBih,

CBM_INIT,

pDataBuf,

&bi,

DIB_RGB_COLORS);

bmp.Attach( hBmp );

return TRUE;

}

8.从CImageList得到提取一个HBITMAP

HBITMAP GetBitmapFromImageList(CImageList& imageList,int nWidth,int nHeight,int nIndex)

{

//从ImageList得出相应的bmp

HDC hDC=::GetDC(NULL);

CDC dc;

dc.CreateCompatibleDC(NULL);

HBITMAP hBmp=CreateCompatibleBitmap(hDC,nWidth,nHeight);

HBITMAP obmp = (HBITMAP) SelectObject(dc.m_hDC, hBmp);

imageList.Draw(&dc,nIndex,CPoint(0,0),ILD_NORMAL);

hBmp=(HBITMAP) SelectObject(dc.m_hDC, obmp);

dc.DeleteDC();

return hBmp;

}

9.从HBitmap得到对应的位图数据

BYTE* GetBmpInfoFromHBitmap(HBITMAP hBitmap,BITMAPINFOHEADER& bih)

{

//设备描述表

HDC hDC;

//当前分辨率下每象素所占字节数

int iBits;

//位图中每象素所占字节数

WORD wBitCount;

//定义调色板大小, 位图中像素字节大小

DWORD dwPaletteSize=0, dwBmBitsSize=0;

//位图属性结构

BITMAP Bitmap;

//位图信息头结构

BITMAPINFOHEADER bi;

//指向位图信息头结构

LPBITMAPINFOHEADER lpbi;

//定义文件,分配内存句柄,调色板句柄

HANDLE hDib, hPal,hOldPal=NULL;

//计算位图文件每个像素所占字节数

hDC = CreateDC("DISPLAY", NULL, NULL, NULL);

iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);

DeleteDC(hDC);

if (iBits <= 1) wBitCount = 1;

else if (iBits <= 4) wBitCount = 4;

else if (iBits <= 8) wBitCount = 8;

else wBitCount = 24;

GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = Bitmap.bmWidth;

bi.biHeight = Bitmap.bmHeight;

bi.biPlanes = 1;

bi.biBitCount = wBitCount;

bi.biCompression = BI_RGB;

bi.biSizeImage = 0;

bi.biXPelsPerMeter = 0;

bi.biYPelsPerMeter = 0;

bi.biClrImportant = 0;

bi.biClrUsed = 0;

dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

bi.biSizeImage=dwBmBitsSize;

//为位图内容分配内存

hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

*lpbi = bi;

// 处理调色板

hPal = GetStockObject(DEFAULT_PALETTE);

if (hPal)

{

hDC = ::GetDC(NULL);

hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);

RealizePalette(hDC);

}

// 获取该调色板下新的像素值

GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)

+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);

memcpy(&bih,&bi,sizeof(BITMAPINFOHEADER));

BYTE* pDataBuf=new BYTE[dwBmBitsSize];

memcpy(pDataBuf,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,dwBmBitsSize);

//恢复调色板

if (hOldPal)

{

::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);

RealizePalette(hDC);

::ReleaseDC(NULL, hDC);

}

//清除资源

GlobalUnlock(hDib);

GlobalFree(hDib);

return pDataBuf;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: