原创 (原创)图像处理学习系列1:bmp文件的操作之色彩转换

2009-3-5 14:09 3385 8 8 分类: 软件与OS
接着上面的,可以做24位图片到8位的转换,仅支持bmp文件
这方面的网站;/
帖子
http://topic.csdn.net/t/20040824/09/3303224.html
基础知识
http://www.roboticfan.com/blog/user_2005/11932/archives/2008/2008111143115.shtml
程序
http://www.cppblog.com/windcsn/archive/2006/07/27/Grayscale.html

后面这个说的不错

写的时候遇到的问题?
1.使用BITMAPINFO的方法错误,搞昏了BITMAPINFO的结构和BMP文件的存储格式。
  在文件的save的时候可以
            m_file.Write(&pbmphdr,sizeof(BITMAPFILEHEADER));
          m_file.Write(pbmpinfo,sizeof(BITMAPINFOHEADER));
          m_file.Write(ColorRGB,ColorNum * sizeof(RGBQUAD));
         
          在对bitmapinfo操作的时候,对颜色表不是简单的copy就可以的是,是在
          BITMAPINFO里面的IMCOLOR结构中进行初始化的
2.指针的操作

BOOL Rgb2Gray(BITMAPFILEHEADER *pbmpfh , BITMAPINFO *pbmpinfo , BYTE *pbmpdata)
如果你在内部开辟空间的话,是返回不了地址的(郁闷的是,自己竟然不知道原因)
3.其实,BITMAPINFOHEADER和后面的 颜色表以及数据是在一个内存块中的,完全可以通过只传递BITMAPINFO指针
通过地址来查找颜色表和其他数据 要修改的太多了,暂且不动库函数了
/****************************************************************************
//彩色图片转换到灰度图片
**************************************************************/
BOOL Rgb2Gray(BITMAPFILEHEADER **pbmpfh , BITMAPINFO **pbmpinfo , BYTE **pbmpdata)
{
    if ((*pbmpinfo)->bmiHeader.biBitCount < 24)
    {
        AfxMessageBox("请输入彩色图片!");
        return FALSE;
    }

    LONG imagewidth  = (*pbmpinfo)->bmiHeader.biWidth;
    LONG imageheigth = (*pbmpinfo)->bmiHeader.biHeight;

    LONG Linebyte=(imagewidth * (*pbmpinfo)->bmiHeader.biBitCount + 31)/32 * 4;
    LONG ImageSize = imageheigth * Linebyte ;

    LONG GrayImage_Linebyte=(imagewidth * 8 +31)/32 * 4;
    LONG GrayImage_size=GrayImage_Linebyte* imageheigth;

    BYTE *tempdata;
    tempdata  = (BYTE*)malloc(GrayImage_size);
    memset(tempdata,0,GrayImage_size);

    int width,heigth;
    BYTE  *psrc ;
    BYTE  *pdest;
    int r,g,b;
    psrc=*pbmpdata;
    pdest=tempdata;

    for (heigth = 0 ; heigth < imageheigth   ;heigth++  )
    {
        for ( width = 0 ; width < imagewidth  ; width++)
        {

         //psrc  = pbmpdata+(ImageSize-Linebyte-
            //    heigth*Linebyte) + width*3;

         //pdest = tempdata + (GrayImage_size - GrayImage_Linebyte - heigth * GrayImage_Linebyte ) +width;

         b = *(psrc++);
         g = *(psrc++);
         r = *(psrc++);

         *(pdest++)=(BYTE)(r*0.299 + g*0.587 + b*0.114);

        }
    }

    BITMAPFILEHEADER *fher;
    fher = new BITMAPFILEHEADER;
    fher->bfType = 0x4D42;
    fher->bfReserved1=0;
    fher->bfReserved2=0;
    fher->bfSize =  GrayImage_size;
    fher->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) ;

    memcpy(*pbmpfh,fher, sizeof(BITMAPFILEHEADER));

    delete fher;
    BITMAPINFO *info;
    info = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));;
    info->bmiHeader.biBitCount=8;
    info->bmiHeader.biClrUsed=0;
    info->bmiHeader.biCompression=BI_RGB;
    info->bmiHeader.biHeight=imageheigth;
    info->bmiHeader.biPlanes =1 ;
    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info->bmiHeader.biSizeImage = 0;
    info->bmiHeader.biWidth=imagewidth;
    info->bmiHeader.biXPelsPerMeter=0;
    info->bmiHeader.biYPelsPerMeter=0;
     for ( int i=0 ;i < 256 ;i++)
    {
         info->bmiColors.rgbBlue = (BYTE)i;
         info->bmiColors.rgbGreen = (BYTE)i;
         info->bmiColors.rgbRed = (BYTE)i;
         info->bmiColors.rgbReserved= (BYTE)i;
    }
   
    free((*pbmpinfo));
   
    (*pbmpinfo) = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));

    memcpy((*pbmpinfo),info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
    free( *pbmpdata);
    *pbmpdata =(BYTE*)((*pbmpinfo)+sizeof(BITMAPINFOHEADER)+256 * sizeof(RGBQUAD));
    *pbmpdata = (BYTE*)malloc(GrayImage_size);
    memcpy(*pbmpdata,tempdata,GrayImage_size);

    free(tempdata);
    delete info;
 
return TRUE;

}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /1 下一条