怎么把bmp图像二值化,变成黑白两色

arabicsara arabicsara 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
bmp可以是256色,24位位图,16位位图或单色位图,我要把它转成只有黑白两色的图像
我试了n种方法都不行,一种是GetDIBits或GetBitmapBits得到bmp的数据;
	CBitmap   m_Bitmap; 
//m_Bitmap.LoadBitmap()

m_Bitmap.m_hObject = LoadImage(NULL,strFilePath,IMAGE_BITMAP,0, 0,LR_LOADFROMFILE);
BITMAP btm;
m_Bitmap.GetBitmap(&btm);
if (btm.bmWidth!=104&&btm.bmHeight!=80)
{
AfxMessageBox(L"logo像素需符合:104*80!");
return 0;
}


#if 1
CDC dc;
dc.CreateDC(L"DISPLAY",NULL,NULL,NULL);

// BITMAP btm;
//bm.GetBitmap(&btm);
DWORD size=btm.bmWidthBytes*btm.bmHeight;
LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);
//BYTE *pBmpBuffer = new BYTE[size];
//memset(pBmpBuffer,0,size);
/////////////////////////////////////////////
BITMAPINFOHEADER bih;
bih.biBitCount=btm.bmBitsPixel;
bih.biClrImportant=0;
bih.biClrUsed=0;
bih.biCompression=0;
bih.biHeight=btm.bmHeight;
bih.biPlanes=1;
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biSizeImage=size;
bih.biWidth=btm.bmWidth;
bih.biXPelsPerMeter=0;
bih.biYPelsPerMeter=0;
///////////////////////////////////
GetDIBits(dc,m_Bitmap,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);

//TraceShow(L"logo:",pBmpBuffer,size,0);
// TRACE(lpData);

bih.biBitCount=1;//btm.bmBitsPixel;
BITMAPFILEHEADER bfh;
bfh.bfReserved1=bfh.bfReserved2=0;
bfh.bfType=((WORD)('M'<< 8)|'B');
bfh.bfSize=54+size;
bfh.bfOffBits=54;

CFile bf;
if(bf.Open(strFilePath+L".bmp",CFile::modeCreate|CFile::modeWrite)){
bf.Write(&bfh,sizeof(BITMAPFILEHEADER));
bf.Write(&bih,sizeof(BITMAPINFOHEADER));
bf.Write(lpData,size);
bf.Close();
// nCount++;
}
GlobalFreePtr(lpData);

//IFDELS(pBmpBuffer)

m_Bitmap.Detach();
#endif

另一种方法用了GDI+,保存的时候,不知道怎么保存成biBitCount=1的单色的图片,图片还不全是黑和白
	Color color,colorTemp;

Bitmap Bimage(L"C:\\24.bmp");
int bWidth=Bimage.GetWidth();
int bHeight=Bimage.GetHeight();
//graphics.DrawImage(&Bimage,20,bHeight-10,bWidth,bHeight);
Bitmap* Bimage2=Bimage.Clone(0,0,bWidth,bHeight,PixelFormatDontCare);
int i,j,middle;
for(i=bWidth;i>0;i--)
{
for(j=bHeight;j>0;j--)
{
Bimage.GetPixel(i,j,&color);
middle=(color.GetRed()+color.GetGreen()+color.GetBlue())/3;
if(middle<128)
middle=0;
else
middle=255;
Bimage2->SetPixel(i,j,middle);
}
}
CLSID pngClsid;
GetEncoderClsid(L"image/bmp", &pngClsid);

又试了CDib类的一种方法,好像只能处理24色的,处理结果图像变成乱码:

BOOL CDib::Load( const TCHAR *pszFilename )
{

CFile cf;

// Attempt to open the Dib file for reading.
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );

// Get the size of the file and store
// in a local variable. Subtract the
// size of the BITMAPFILEHEADER structure
// since we won't keep that in memory.
DWORD dwDibSize;
dwDibSize =cf.GetLength() - sizeof( BITMAPFILEHEADER );

// Attempt to allocate the Dib memory.
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );

BITMAPFILEHEADER BFH;

// Read in the Dib header and data.
try{
// Did we read in the entire BITMAPFILEHEADER?
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||

// Is the type 'MB'?
BFH.bfType != 'MB' ||

// Did we read in the remaining data?
cf.Read( pDib, dwDibSize ) != dwDibSize ){

// Delete the memory if we had any
// errors and return FALSE.
delete [] pDib;
return( FALSE );
}
}

// If we catch an exception, delete the
// exception, the temporary Dib memory,
// and return FALSE.
catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}

cf.Close();
// If we got to this point, the Dib has been
// loaded. If a Dib was already loaded into
// this class, we must now delete it.
if( m_pDib != NULL )
delete m_pDib;

// Store the local Dib data pointer and
// Dib size variables in the class member
// variables.
m_pDib = pDib;
m_dwDibSize = dwDibSize;

// Pointer our BITMAPINFOHEADER and RGBQUAD
// variables to the correct place in the Dib data.
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];

// Calculate the number of palette entries.
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;

// Point m_pDibBits to the actual Dib bits data.
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];

// If we have a valid palette, delete it.
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();

// If there are palette entries, we'll need
// to create a LOGPALETTE then create the
// CPalette palette.
if( m_nPaletteEntries != 0 ){

// Allocate the LOGPALETTE structure.
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];

if( pLogPal != NULL ){

// Set the LOGPALETTE to version 0x300
// and store the number of palette
// entries.
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;

// Store the RGB values into each
// PALETTEENTRY element.
for( int i=0; i<m_nPaletteEntries; i++ ){
pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}

// Create the CPalette object and
// delete the LOGPALETTE memory.
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}

m_BitCount = 8;
return( TRUE );

}

BOOL CDib::Save( const TCHAR *pszFilename )
{

// If we have no data, we can't save.
if( m_pDib == NULL )
return( FALSE );

CFile cf;

// Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );

// Write the data.
try{

// First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );

// Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
}

// If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e ){
e->Delete();
return( FALSE );
}

return( TRUE );

}
bool CDib::ConvertToTwoValue()
{
DWORD i,size;
unsigned char *p;
// 一个特别简单的二值化程序
// 以128为界划分

p = m_pDibBits;
size = m_dwDibSize - (m_pDibBits - m_pDib);
for (i = 0; i < size;i++)
{
if (*p < 128)
{
*p = 0;
}
else
{
*p = 255;
}
p++;
}
return true;

}

各位高手有没有好的bmp转成黑白两色的函数接口提供一下,成分感谢!!!
...全文

相关推荐

C++图像二值化代码

C++图像二值化代码,很简单能看懂,很简单能看懂,很简单能看懂。

时长两年半android练习生

图像黑白化与二值化处理技术详解

二值化技术是图像处理中的一种基本方法,其核心思想是将彩色图像或灰度图像转化为仅包含黑白两色的图像,即所谓的二值图像。这种转换是通过设定一个阈值来实现的,当图像中的像素值高于这个阈值时,该像素点将被设置为白色,否则被设置为黑色。在图像二值化的过程中,关键步骤包括确定适当的阈值和应用这个阈值来决定每个像素点的最终颜色。这种方法对于简化图像、提取边界以及改善后续图像处理步骤如特征提取、图像分割等都非常重要。

BOBO爱吃菠萝

c#图像灰度化、灰度反转、二值化

图像灰度化: 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是R、G、B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少

gdjlc

灰度图像经典二值化Matlab代码

我自己实现的经典的灰度图像二值化Matlab代码:包括Otsu二值化方法,Niblack二值化,Kittler最小分类错误二值化。内有使用说明和示例图片。

Benny810

C语言读取BMP图像,并进行反色操作

用C/C++编写的读取一个BMP文件的数据,包括文件头,信息头,调色板和像素信息。然后对输入图像进行反色操作(只做了24色真彩图的反色)、、

含光剑
评论 10
收藏 已收藏
分享
返回顶部
arabicsara
图形处理/算法 19,463 成员 50,678 内容