何东健-彩色位图转黑白位图代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
何东健主编《数字图像处理》程序
////////////////////////////////////////////////////////////////////////
//BOOL MakeGray256(BYTE mGrayType, CDibObject *pDibObject)
//----------------------------------------------------------------------
//基本功能:本函数将传入的CDibObject对象中的图像从彩色转换为灰度图像。
// 如果进行此调整之前没有指定一个CDibObject对象指针,则必须在
// 调整时加以指定。
//----------------------------------------------------------------------
//参数说明:BYTE mGrayType 0:Y=0.3R+0.59G+0.11B
// 1: Y=R
// 2: Y=G
// 3: Y=B
// CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返回:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CPointPro::MakeGray256(BYTE mGrayType,
CDibObject *pDibObject )
{
//CDibObject对象指针
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//若未指定CDibObject 对象指针返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//低于8位的图像不进行处理
if( m_pDibObject->GetNumBits() < 8 ) return( FALSE );
//获取原图像字节宽度和转换后的8位256色灰度图像的字节宽度
int nOldWidthBytes, nNewWidthBytes;
char *pBuffer = (char *) m_pDibObject->GetDIBPointer( &nOldWidthBytes, 8, &nN ewWidthBytes );
if( pBuffer == NULL ) return( FALSE );
//定义变量
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
RGBQUAD *pOldRGBPalette, *pNewRGBPalette;
unsigned char *pOldBits, *pNewBits, *pTemp, *pNewTemp;
int nNumColors, nNumNewColors;
//获取文件头指针
pOldBFH = (BI TMAPFILEHEADER *) pBuffer;
//获取信息头指针
pOldBIH = (BI TMAPINFOHEADER *) &pBuffer[sizeof(BI TMAPFILEHEADER)];
//获取调色板指针
pOldRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//新图像颜色数
nNumNewColors = 256;
//获取原图像数据指针
pOldBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//为新图像分配内存
HGLOBAL hGlobal;
//新图像总字节数
DWORD dwSize;
dwSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + 256 * sizeof( RGBQUAD ) +
m_pDibObject->GetHeight() * nNewWidthBytes;
hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize );
if( hGlobal == NULL )
{
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
pBuffer = (char *) ::GlobalLock( hGlobal );
if( pBuffer == NULL )
{
::GlobalFree( hGlobal );
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//获得新图像的文件头指针
pNewBFH = (BI TMAPFILEHEADER *) pBuffer;
//获得新图像的信息头指针
pNewBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
//获得新图像的调色板指针
pNewRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BI TMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
//复制原图像文件头数据到新图像文件头
*pNewBFH = *pOldBFH;
//复制原图像信息头数据到新图像信息头
*pNewBIH = *pOldBIH;
//循环变量定义
int i, j = 256, x, y;
pNewBIH->biBitCount = 8;
pNewBIH->biSizeImage = nNewWidthBytes * m_pDibObject->GetHeight(); pNewBIH->biClrUsed = 256;
pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
256 * sizeof( RGBQUAD ) +
pNewBIH->biSizeImage;
pNewBFH->bfOffBits = sizeof( BI TMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
nNumNewColors * sizeof( RGBQUAD );
pNewBits = (unsigned char *) &pBuffer[sizeof(BI TMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
m_pDibObject->SetPaletteBytes( 256 * sizeof( RGBQUAD ));
//创建256色灰度调色板
for( i = 0; i < j; i++ )
{
pNewRGBPalette[i].rgbRed = i;
pNewRGBPalette[i].rgbGreen = i;
pNewRGBPalette[i].rgbBlue = i;
}
unsigned char *pLookup; //调色板查找表
DWORD dwGray; //灰度级别
switch( m_pDibObject->GetNumBits() )
{
case 8: //256色图像
pLookup = new unsigned char [256];
if( pLookup == NULL ) break;
memset( pLookup, 0, 256 ); //调色板查找表清0(256项)
switch( mGrayType)
{
case 0: //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
for( i=0; i<256; i++ )
{
dwGray = ( (DWORD) pOldRGBPalette[i].rgbRed * 30 + (DWORD) pOldRGBPalette[i].rgbGreen * 59 +
(DWORD) pOldRGBPalette[i].rgbBlue * 11 ) / 100;
pLookup[i] = (unsigned char) dwGray;
}
break;
case 1: //按亮度Y=R将彩色图像转换为灰度图像
for( i=0; i<256; i++ )
{
dwGray = (DWORD) pOldRGBPalette[i].rgbR ed;
pLookup[i] = (unsigned char) dwGray;
}
break;
case 2: //按亮度Y=G将彩色图像转换为灰度图像
for( i=0; i<256; i++ )
{
dwGray = (DWORD) pOldRGBPalette[i].rgbGreen;
pLookup[i] = (unsigned char) dwGray;
}
break;
case 3: //按亮度Y=B将彩色图像转换为灰度图像
for( i=0; i<256; i++ )
{
dwGray =(DWORD) pOldRGBPalette[i].rgbBlue;
pLookup[i] = (unsigned char) dwGray;
}
break;
}
for( y = 0; y < pOldBIH->biHeight; y++ )
{
pTemp = pOldBits; //位图数据起始指针
pTemp += y * nOldWidthBytes; //位图数据下一行起始指针
//转换成灰度索引
for( x = 0; x < pOldBIH->biWidth; x++ ) pTemp[x] = pLookup[pTemp[x]]; }
delete [] pLookup; //释放pLookup查找表所占内存
memcpy( pNewBits, pOldBits, nNewWidthBytes * m_pDibObject->GetHeight());
break;
case 16: //16位色真彩色图像
unsigned char ucRed, ucGreen, ucBlue;
for( y=0; y<pOldBIH->biHeight; y++ )
{
//位图数据起始指针
pTemp = pOldBits;
pNewTemp = pNewBits;
//位图数据下一行起始指针
pTemp += y * nOldWidthBytes;
pNewTemp += y * nNewWidthBytes;
switch( mGrayType )
{
case 0:
for( x=0; x<pOldBIH->biWidth; x++ )
{
GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
//按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
dwGray = (ucR ed * 30 + ucGreen * 59 +ucBlue * 11) / 100; //给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 1:
for( x=0; x<pOldBIH->biWidth; x++ )
{
GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
//按亮度Y=R将彩色图像转换为灰度图像
dwGray = (ucR ed * 30 + ucGreen * 59 +ucBlue * 11) / 100; //给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 2:
for( x=0; x<pOldBIH->biWidth; x++ )
{
GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
//按亮度Y=G将彩色图像转换为灰度图像
dwGray = (ucR ed * 30 + ucGreen * 59 +ucBlue * 11) / 100; //给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 3:
for( x=0; x<pOldBIH->biWidth; x++ )
{
GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
//按亮度Y=B将彩色图像转换为灰度图像
dwGray = (ucR ed * 30 + ucGreen * 59 +ucBlue * 11) / 100; //给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
}
}
break;
case 24: //24位真彩色图像
for( y=0; y<pOldBIH->biHeight; y++ )
{
//位图数据起始指针
pTemp = pOldBits;
pNewTemp = pNewBits;
//位图数据下一行起始指针
pTemp += y * nOldWidthBytes;
pNewTemp += y * nNewWidthBytes;
switch( mGrayType )
{
case 0: //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像for( x=0; x<pOldBIH->biWidth; x++ )
{
dwGray = ( (DWORD) pTemp[x*3+2] * 30 //红色
+(DWORD) pTemp[x*3+1] * 59 //绿色
+(DWORD) pTemp[x*3] * 11 //兰色
) / 100;
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 1: //按亮度Y=R将彩色图像转换为灰度图像
for( x=0; x<pOldBIH->biWidth; x++ )
{
dwGray = (DWORD) pTemp[x*3+2]; //红色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 2: //按亮度Y=G将彩色图像转换为灰度图像
for( x=0; x<pOldBIH->biWidth; x++ )
{
dwGray = (DWORD) pTemp[x*3+1] ; //绿色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 3: //按亮度Y=B将彩色图像转换为灰度图像
for( x=0; x<pOldBIH->biWidth; x++ )
{
dwGray =(DWORD) pTemp[x*3]; //兰色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
}
}
break;
case 32: //32位真彩色图像
for( y=0; y<pOldBIH->biHeight; y++ )
{
//位图数据起始指针
pTemp = pOldBits;
pNewTemp = pNewBits;
//位图数据下一行起始指针
pTemp += y * nOldWidthBytes;
pNewTemp += y * nNewWidthBytes;
switch( mGrayType )
{
case 0:
for( x=0; x<pOldBIH->biWidth; x++ )
{
//按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像dwGray = ( (DWORD) pTemp[x*4] * 30 //红色+(DWORD) pTemp[x*4+1] * 59 //绿色
+(DWORD) pTemp[x*4+2] * 11 //兰色
) / 100;
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 1:
for( x=0; x<pOldBIH->biWidth; x++ )
{
//按亮度Y=R将彩色图像转换为灰度图像
dwGray = (DWORD) pTemp[x*4];//红色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 2:
for( x=0; x<pOldBIH->biWidth; x++ )
{
//按亮度Y=G将彩色图像转换为灰度图像
dwGray = (DWORD) pTemp[x*4+1] ; //绿色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
case 3:
for( x=0; x<pOldBIH->biWidth; x++ )
{
//按亮度Y=B将彩色图像转换为灰度图像
dwGray =(DWORD) pTemp[x*4+2] ; //兰色
//给新图像数据赋值
pNewTemp[x] = (unsigned char)dwGray;
}
break;
}
}
break;
}
::GlobalUnlock( m_pDibObject->GetDib() );
::GlobalFree( m_pDibObject->GetDib() );
::GlobalUnlock( hGlobal );
m_pDibObject->SetDib( hGlobal );
m_pDibObject->ProcessImageHeader();
m_pDibObject->m_nLastError = IMAGELIB_SUCCESS; return( TRUE );
}。