作者:彭军 邮件:poonjun at gmail com
从RGB位图转换到灰度图片有好几种方法,我这里选择的是最简单的一种,就是将RGB的各分量值去平均值作为新的灰度图片的RGB各分量的值。而水平翻转和垂直翻转基本上就是图片像素位置的一个变化而已。下面是我的程序,全部自己写的哦!void CDIPDlg::OnBtnTograyimage()
{
// TODO: Add your control notification handler code here
if(m_nBitCount<24)
{
AfxMessageBox("只能处理24位真彩色图片");
return;
}//得到当前设备句柄指针
CDC* pDC=GetDC();
//锁定图像内存,得到返回的指针
BYTE* lpdib=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB);
//有图像指针获得
BITMAPINFO* m_pBitmapInfo=(BITMAPINFO*)lpdib;
//BYTE* m_dib=new BYTE[m_pBitmapInfo->bmiHeader.biSizeImage];
//BYTE* m_dib=new BYTE[m_nHeight*m_nWidth*3];
//memcpy(m_dib,m_pDibData,m_pBitmapInfo->bmiHeader.biSizeImage);
//上句等价于下句,但用下句的时候,图片的上边像素会少掉一些
//memcpy(m_dib,m_pDibData,m_nHeight*m_nWidth*3);
//操作每个像素的RGB分量值
int LineBytesWidth=WIDTHBYTES(m_nWidth*m_nBitCount);
for(int i=0;i<m_nHeight;i++)
{
int n;
for(int j=0;j<LineBytesWidth;j++)
{
//取得第i行,第j列的像素的RGB分量的值
BYTE BB=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE GG=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE RR=*(m_pDibData+LineBytesWidth*i+j);
//计算平均值
n=(RR+GG+BB)/3;
//将平均值一次赋给第i行,第j列的像素点的RGB分量值
*(m_pDibData+LineBytesWidth*i+j)=n;
j--;
*(m_pDibData+LineBytesWidth*i+j)=n;
j--;
*(m_pDibData+LineBytesWidth*i+j)=n;
j++;
j++;
}
}
//m_pDibData=(char*)m_dib;
//为什么不能删除m_dib
//delete[] m_dib;
::GlobalUnlock((HGLOBAL)m_hDIB);
::StretchDIBits(pDC->m_hDC,0,0,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pDibData,m_pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
}
//=====================================================
void CDIPDlg::OnBtnUdflip()
{
// TODO: Add your control notification handler code here
//为后面的显示位图做准备
CDC* pDC=GetDC();
BYTE* pdib=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB);
BITMAPINFO* pBitmapInfo=(BITMAPINFO*)pdib;//新开辟一块和图片大小一致的内存
BYTE* m_dib=new BYTE[m_nHeight*m_nWidth*3];
//将这块内存中的值全部置零
memset(m_dib,0,m_nHeight*m_nWidth*3);//获得位图一行所占的字节数
int LineBytesWidth=WIDTHBYTES(m_nWidth*m_nBitCount);
//依次操作位图的每一个像素的RGB分量值
for(int i=0;i<m_nHeight;i++)
{
for(int j=0;j<m_nWidth*3;j++)
{
//获得第i行,第j列的RGB分量值
BYTE B=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE G=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE R=*(m_pDibData+LineBytesWidth*i+j);
//设置新开辟的内存块中的RGB分量值
*(m_dib+LineBytesWidth*(m_nHeight-1-i)+j)=R;
j--;
*(m_dib+LineBytesWidth*(m_nHeight-1-i)+j)=G;
j--;
*(m_dib+LineBytesWidth*(m_nHeight-1-i)+j)=B;
j++;
j++;
}
}//让位图数据变量的值指向新开的内存
m_pDibData=(char*)m_dib;
::GlobalUnlock((HGLOBAL)m_hDIB);
//delete[] m_dib;
::StretchDIBits(pDC->m_hDC,0,0,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_dib,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
}
//===========================================================
void CDIPDlg::OnBtnLrflip()
{
// TODO: Add your control notification handler code here
//为后面的显示位图做准备
CDC* pDC=GetDC();
BYTE* pdib=(BYTE*)::GlobalLock((HGLOBAL)m_hDIB);
BITMAPINFO* pBitmapInfo=(BITMAPINFO*)pdib;
BYTE* m_dib=new BYTE[m_nHeight*m_nWidth*3];
memset(m_dib,0,m_nHeight*m_nWidth*3);
LONG LineBytesWidth=WIDTHBYTES(m_nWidth*m_nBitCount);
for(int i=0;i<m_nHeight;i++)
{
for(int j=0;j<LineBytesWidth;j++)
{
BYTE B=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE G=*(m_pDibData+LineBytesWidth*i+j);
j++;
BYTE R=*(m_pDibData+LineBytesWidth*i+j);
*(m_dib+LineBytesWidth*i+(m_nWidth*3-1-j))=B;
j--;
*(m_dib+LineBytesWidth*i+(m_nWidth*3-1-j))=G;
j--;
*(m_dib+LineBytesWidth*i+(m_nWidth*3-1-j))=R;
j++;
j++;
}
}m_pDibData=(char*)m_dib;
::GlobalUnlock((HGLOBAL)m_hDIB);
::StretchDIBits(pDC->m_hDC,0,0,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_dib,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
}
(彭军) |