24bit彩色图像转8bit灰度图

        char szFileName[MAX_PATH] = "";
        OPENFILENAME file={0};
        file.lStructSize=sizeof(file);
        file.lpstrFile=szFileName;
        file.nMaxFile=MAX_PATH;
        file.lpstrFilter="BMP Files(*.bmp)/0*.bmp/0JPG Files(*.jpg)/0*.jpg/0All Files/0*.*/0/0";
        file.nFilterIndex=1;
        if(::GetOpenFileName(&file)){
            imgFile = new char[sizeof(szFileName) + 1];
            strcpy(imgFile, szFileName);
            //::MessageBox(NULL,imgFile,"TEST",MB_OK);
        }

        char* tmp = new char[255];
        sprintf(tmp,"Open File: %s",imgFile);


        if(imgFile == NULL || strlen(imgFile)<4){
            AfxMessageBox("Image FileName Not Right.");
            return;
        }

 

    //判断图像格式
        USES_CONVERSION;
        Bitmap bmp(A2W(imgFile));//加载BMP   
        int iPF= bmp.GetPixelFormat();
   
        sprintf(tmp,"data.PixelFormat=%d",  iPF);
        AfxMessageBox(tmp);

        if(iPF == PixelFormat8bppIndexed){
            objCDib = new CDib();
            objCDib->LoadFile(imgFile);

            //view->RedrawWindow();
            view->Invalidate();
        }else if(iPF == PixelFormat24bppRGB){               
            // Specify a pixel format.
            UINT w = bmp.GetWidth();
            UINT h = bmp.GetHeight();

            // Lock the bitmap's bits.
            Rect rect(0, 0, w, h);
           
            BitmapData data;
            bmp.LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &data);
            unsigned char *pData = static_cast<unsigned char*>(data.Scan0);
           

            int w0 = w;
            if(w % 4 !=0){
                //w0 += 4-w%4; //这里不需要对齐
            }           

            int bitwidth = w*3;
            if(w*3 % 4 !=0){
                bitwidth += 4-w*3%4;//原数据已对齐
            }

            sprintf(tmp,"w=%d,w0=%d,bitwidth=%d",w,w0,bitwidth);
            AfxMessageBox(tmp);

            BYTE* NewImg = new BYTE[w0*h];
            memset(NewImg,0,w0*h);

            for(int i=h-1;i>=0;i--) {   
                //memcpy(NewImg+i*ByteWidth,img+i*width*3,width*3);
                for(int j=0;j<w;j++){
                     UINT R = *(pData+i*bitwidth + j*3);
                     UINT G = *(pData+i*bitwidth + j*3 +1);
                     UINT B = *(pData+i*bitwidth + j*3 +2);
                     UINT Y = 0.299*R+0.587*G+0.114*B;
                     NewImg[i*w0+j] = R;
                }               
            }
           
            //释放位图资源
            bmp.UnlockBits(&data);

 

 

注:对24bit位图,一个像素使用3个字节存储。对齐是指行的总字节数对齐,即bitmapWidth*3 % 4必须为0,而不是bitmapWidth%4等于0。

 

对齐方法:

 

            int bitwidth = w*3;
            if(w*3 % 4 !=0){
                bitwidth += 4-w*3%4;//原数据已对齐
            }

你可能感兴趣的:(24bit彩色图像转8bit灰度图)