请教各位前辈,我需要完成如下的任务,实在是没入门,如何入手,需要什么步骤,详细些谢谢!!
有一个源位图,是24位,windows格式,其中有图形,各位颜色都有,现在需要将一种颜色的图形提取出来
比如红色图形:RGB(255,0,0),将这个图像放到新文件中。就这么简单。说说我是怎么做的吧:我用CFile类(m_BaseBitmapFile对象)将文件打开,跳过文件头,跳过图像信息头:
this->m_BaseBitmapFile.Seek(this->m_BMFH.bfOffBits, CFile::begin);
m_BMFH是BITMAPFILEHEADER。然后我遍历了每个像素: for(LONG lHighIdx = NULL; lHighIdx < BMIH.biHeight; lHighIdx ++)
{
for(LONG lWidthIdx = NULL; lWidthIdx < (((BMIH.biWidth * BMIH.biBitCount + 31) / 32) * 4); lWidthIdx += sizeof(RGBTRIPLE))
{
// 源图像当前像素 RGB 值
RGBTRIPLE CurrentRT; // 读出源图像当前像素 RGB 值
PasteBitmapFile.Read(&CurrentRT, sizeof(RGBTRIPLE)); // 判断该像素是否在要求提取范围内
if(((UINT)::abs(CurrentRT.rgbtRed - GetRValue(this->m_DistillColor)) <= this->m_uiColorMissRange))
&& ((UINT)::abs(GetGValue(this->m_DistillColor) - CurrentRT.rgbtGreen) <= this->m_uiColorMissRange)
&& ((UINT)::abs(GetBValue(this->m_DistillColor) - CurrentRT.rgbtBlue) <= this->m_uiColorMissRange))
// 写入基片图像文件象素值
this->m_BaseBitmapFile.Write(&CurrentRT, sizeof(RGBTRIPLE));
else
// 在基片文件中跳过该象素
this->m_BaseBitmapFile.Seek(sizeof(RGBTRIPLE), CFile::current);
}
}循环控制应该没有问题,不会错位吧,我在循环里什么都不做(也就是把if给删除了),直接输出到目标文件是没问题的。
但是,如果我一加上if后,也就是跳过了一些像素后,输出位图文件中的图像就不正确了,不连续了。各位前辈,我这种思路对吗???可行否???哪为什么输出的图像就不是那么连续,我看了,少的部分也是红色的啊??!!
谢谢了,头有点大。

解决方案 »

  1.   

    else
    完了新图就不写数据了吗?要写底色进去阿,不然当然混乱了
      

  2.   

    你可以对某种像素做ROP运算,就直接得到了新图像。哪里这么麻烦啊,这么像素循环很慢的
      

  3.   

    asett1(asett1),这种方法很好,值得学习。
    不过应该是相应位用&操作吧
    条件的判断为:
    if(CurrentRT & RGB(255,0,0)==RGB(255,0,0))
    就显示,其它只显示背景色。
    可能要把RGB(255,0,0)转换为一个DWORD的格式才能这样做,我没有再电脑上面试。
    还有一个问题:
    就是windows下面的BMP的图像数据试RGBQUAD ,
    OS/2下面的BMP图像数据才是RGBTRIPLE,
    具体我也不记得了,如果有误,请海涵!
      

  4.   

    建义用GDI+的类Image或Bitmap