如何将彩色图片转换成黑白图片 如题,要那种只有黑白两种颜色的,RGB(255, 255, 255)和RGB(0,0,0)没有其他杂色的,有没有什么好的算法? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 应该就是把图片灰度化大概的公式可能是这样的B = PicBits(i * BytesPerPixel + 1) G = PicBits(i * BytesPerPixel + 2) R = PicBits(i * BytesPerPixel + 3) Gray = R * 0.39 + G * 0.5 + B * 0.11 void CDibView::OnMenuchange() file://图像转换实现函数{ // TODO: Add your command handler code here HANDLE data1handle; LPBITMAPINFOHEADER lpBi; BITMAPINFO *m_pBMI; CDibDoc *pDoc=GetDocument(); HDIB hdib; unsigned char *hData; unsigned char *data; hdib=pDoc->GetHDIB();//得到位图数据的句柄,其中包含图像信息头 BeginWaitCursor(); lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib); hData=(unsigned char*)FindDIBBits((LPSTR)lpBi); m_pBMI=new BITMAPINFO;//生成彩色图像的信息头 m_pBMI->bmiHeader.biBitCount=24; m_pBMI->bmiHeader.biClrImportant=0; m_pBMI->bmiHeader.biClrUsed=0; m_pBMI->bmiHeader.biCompression=BI_RGB; m_pBMI->bmiHeader.biHeight=lpBi->biHeight; m_pBMI->bmiHeader.biWidth=lpBi->biWidth; m_pBMI->bmiHeader.biPlanes=1; m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); m_pBMI->bmiHeader.biXPelsPerMeter=0; m_pBMI->bmiHeader.biYPelsPerMeter=0; m_pBMI->bmiHeader.biSizeImage=WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3; file://data=hData; int R,G,B,i,j; data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3); file://生成存储彩色图象数据的缓冲区 data=(unsigned char*)GlobalLock((HGLOBAL)data1handle); for(i=0;ibiHeight;i++)//实现灰度到彩色变换 for(j=0;jbiWidth*8);j++) { if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=64) {R=0; G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)); B=255; } if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>64 && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=128) {R=0; G=255; B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)); } if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>128 && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=192) {R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)-128); G=255; B=0; } if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>192 && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=255) {R=255; G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)); B=0; } file://将生成的R、G、B分量存入目标缓冲区 *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3)=B; *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+1)=G; *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+2)=R; } GlobalUnlock((HGLOBAL)hdib); GlobalUnlock(data1handle); EndWaitCursor(); CClientDC pDC(this); file://显示真彩色图像 StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->biWidth,lpBi->biHeight,0,0, lpBi->biWidth, lpBi->biHeight,data,m_pBMI,DIB_RGB_COLORS, SRCCOPY); delete m_pBMI;} ...不是灰度化,要的是黑白图,就是每个像素点的RGB颜色要么是255,255,255要么就是0,0,0没有其他的颜色 要做灰的话,直接把原像素点的颜色设置为(R + G + B)/3,(R + G + B)/3, (R + G + B)/3就行了,效果还挺好 这需要抖动技术。参考:http://en.wikipedia.org/wiki/Ordered_dithering利用 该技术转换后:注意上图中只包含两种颜色的,黑色和白色。 你这个叫Image Dithering这里有个sample code,自己改改用吧:http://www.flipcode.com/archives/Image_Dither.shtml 如何使纯文本自动换行 请问如何实现同一个界面的多视图间切换? 关于DX声音的问题 关于CAsyncsocket::asyncselect的作用 vc++中是否有一个函数,可以判断一个对话框中的内容发生改变 高手帮忙,如何求程序运行的时间(精确到毫秒) 我是菜鸟,谁能告诉我Tab Control控件怎么用呢? 那里有CD转录成wav的DLL(包括函数说明)?小弟有急用。 怎样在文档的光标位置上插入一个图片!用程序实现!谢谢各位帮忙 烦死了,我恨网络实名这套软件! 关于SOCKET的RecvFrom,在Release下内存出错? 怎么把字符串作为参数传递给SQL语句作为查询条件呢?
G = PicBits(i * BytesPerPixel + 2)
R = PicBits(i * BytesPerPixel + 3)
Gray = R * 0.39 + G * 0.5 + B * 0.11
{
// TODO: Add your command handler code here
HANDLE data1handle;
LPBITMAPINFOHEADER lpBi;
BITMAPINFO *m_pBMI;
CDibDoc *pDoc=GetDocument();
HDIB hdib;
unsigned char *hData;
unsigned char *data;
hdib=pDoc->GetHDIB();//得到位图数据的句柄,其中包含图像信息头
BeginWaitCursor();
lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);
hData=(unsigned char*)FindDIBBits((LPSTR)lpBi);
m_pBMI=new BITMAPINFO;//生成彩色图像的信息头
m_pBMI->bmiHeader.biBitCount=24;
m_pBMI->bmiHeader.biClrImportant=0;
m_pBMI->bmiHeader.biClrUsed=0;
m_pBMI->bmiHeader.biCompression=BI_RGB;
m_pBMI->bmiHeader.biHeight=lpBi->biHeight;
m_pBMI->bmiHeader.biWidth=lpBi->biWidth;
m_pBMI->bmiHeader.biPlanes=1;
m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_pBMI->bmiHeader.biXPelsPerMeter=0;
m_pBMI->bmiHeader.biYPelsPerMeter=0;
m_pBMI->bmiHeader.biSizeImage=WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3;
file://data=hData;
int R,G,B,i,j;
data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3);
file://生成存储彩色图象数据的缓冲区
data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);
for(i=0;ibiHeight;i++)//实现灰度到彩色变换
for(j=0;jbiWidth*8);j++)
{
if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=64)
{R=0;
G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
B=255;
}
if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>64
&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=128)
{R=0;
G=255;
B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
}
if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>128
&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=192)
{R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)-128);
G=255;
B=0;
}
if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>192
&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=255)
{R=255;
G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
B=0;
}
file://将生成的R、G、B分量存入目标缓冲区
*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3)=B;
*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+1)=G;
*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+2)=R;
}
GlobalUnlock((HGLOBAL)hdib);
GlobalUnlock(data1handle);
EndWaitCursor();
CClientDC pDC(this);
file://显示真彩色图像
StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->biWidth,lpBi->biHeight,0,0,
lpBi->biWidth, lpBi->biHeight,data,m_pBMI,DIB_RGB_COLORS,
SRCCOPY);
delete m_pBMI;
}
参考:http://en.wikipedia.org/wiki/Ordered_dithering利用 该技术转换后:
注意上图中只包含两种颜色的,黑色和白色。