首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

将24位bmp转存为单色bmp的有关问题

2013-09-07 
将24位bmp转存为单色bmp的问题下面这个函数源码也是CSDN上找到的 版主在文章上说测试能用,但是。。。void Cut

将24位bmp转存为单色bmp的问题
下面这个函数源码也是CSDN上找到的 版主在文章上说测试能用,但是。。。

void CutPhoto(long StartLeft, long StartTop, long TargetWidth, long TargetHeight)
 {
     char FileName[32];
     sprintf(FileName, "input.bmp");
 
    BYTE* pDIBData;
     BITMAPFILEHEADER bf;
     BITMAPINFOHEADER bi;
     RGBQUAD rgb[2]={{0,0,0,0},{255,255,255,0}};
     
    CFile fileR(FileName, CFile::modeRead);
     fileR.Read(&bf, sizeof(BITMAPFILEHEADER));
     fileR.Read(&bi, sizeof(BITMAPINFOHEADER));
     long SrcWidth=bi.biWidth;
     long SrcHeight=bi.biHeight;
     int nSize = bf.bfSize - bi.biSize;
     pDIBData = new BYTE[nSize];
     fileR.Read(pDIBData, nSize);
     fileR.Close();
 
    StartTop = SrcHeight - TargetHeight - StartTop;
     bi.biWidth = TargetWidth;
     bi.biHeight = TargetHeight;
     bi.biBitCount = 1;
     bi.biXPelsPerMeter = 0;
     bi.biYPelsPerMeter = 0;
     bi.biSizeImage = (bi.biWidth*bi.biBitCount+31)/32*4*bi.biHeight;
 
    sprintf(FileName, "output.bmp");
     CFile file(FileName, CFile::modeWrite|CFile::modeCreate);
     bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*2;
     bf.bfSize = bf.bfOffBits + bi.biSizeImage;
     file.Write(&bf, sizeof(BITMAPFILEHEADER));
     file.Write(&bi, sizeof(BITMAPINFOHEADER));
     file.Write(rgb, 2*sizeof(RGBQUAD));
 
    BYTE writein = 0;
     int pitch = SrcWidth%4;
     int k, pitchcount;
     for(int i=StartTop;i<StartTop+TargetHeight;i++)
     {
         pitchcount = 0;
         k=0;


         int realPitch = i*pitch;
         for(int j=StartLeft;j<StartLeft+TargetWidth;j++)
         {
             BYTE b = pDIBData[(i*SrcWidth+j)*3+realPitch];
             BYTE g = pDIBData[(i*SrcWidth+j)*3+1+realPitch];
             BYTE r = pDIBData[(i*SrcWidth+j)*3+2+realPitch];
             writein<<=1;
             if ((r+g+b)/3>127)
                 writein|=1;
             if (++k==8)
             {
                 pitchcount++;
                 file.Write(&writein, 1);
                 writein = 0;
                 k=0;
             }
         }
         if (k != 0)
         {
             writein<<=(8-k);
             file.Write(&writein, 1);
             pitchcount++;
         }
         if (pitchcount%4 != 0)
         {
             writein = 0;
             for (j=0; j<4-pitchcount%4; j++)
                 file.Write(&writein, 1);
         }
     }


     file.Close(); 
    delete pDIBData; 
    pDIBData = NULL;
 }

使用:
我把一张RGB为0,0,255 尺寸为264*264的蓝色二维码(“http://www.csdn.net/”)BMP BIT24的文件 使用你的这个函数
CutPhoto(0,0,384,320); 
我把原BMP 24BIT的 RGB 为 0,0,255 转到单色BITMAP(尺寸为384*320)
左上起始位置 就先不管了

但是我转出来的图片不对 黑黑的 稍许有点白点

弱弱地说句:我直接在WINDOWS画图板上直接 点 “黑白并且另存为BMP 1位单色” 就OK 
rgb bmp
[解决办法]
这个程序只是提供了一个参考实现,具体图片的阈值设定会不一样的,可以把前后图片贴上来看看。

引用:
下面这个函数源码也是CSDN上找到的 版主在文章上说测试能用,但是。。。

void CutPhoto(long StartLeft, long StartTop, long TargetWidth, long TargetHeight)
 {
     char FileName[32];
     sprintf(FileName, "input.bmp");
 
    BYTE* pDIBData;
     BITMAPFILEHEADER bf;
     BITMAPINFOHEADER bi;
     RGBQUAD rgb[2]={{0,0,0,0},{255,255,255,0}};
     
    CFile fileR(FileName, CFile::modeRead);
     fileR.Read(&bf, sizeof(BITMAPFILEHEADER));
     fileR.Read(&bi, sizeof(BITMAPINFOHEADER));
     long SrcWidth=bi.biWidth;
     long SrcHeight=bi.biHeight;
     int nSize = bf.bfSize - bi.biSize;
     pDIBData = new BYTE[nSize];
     fileR.Read(pDIBData, nSize);
     fileR.Close();
 
    StartTop = SrcHeight - TargetHeight - StartTop;
     bi.biWidth = TargetWidth;
     bi.biHeight = TargetHeight;
     bi.biBitCount = 1;
     bi.biXPelsPerMeter = 0;
     bi.biYPelsPerMeter = 0;


     bi.biSizeImage = (bi.biWidth*bi.biBitCount+31)/32*4*bi.biHeight;
 
    sprintf(FileName, "output.bmp");
     CFile file(FileName, CFile::modeWrite
[解决办法]
CFile::modeCreate);
     bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*2;
     bf.bfSize = bf.bfOffBits + bi.biSizeImage;
     file.Write(&bf, sizeof(BITMAPFILEHEADER));
     file.Write(&bi, sizeof(BITMAPINFOHEADER));
     file.Write(rgb, 2*sizeof(RGBQUAD));
 
    BYTE writein = 0;
     int pitch = SrcWidth%4;
     int k, pitchcount;
     for(int i=StartTop;i<StartTop+TargetHeight;i++)
     {
         pitchcount = 0;
         k=0;
         int realPitch = i*pitch;
         for(int j=StartLeft;j<StartLeft+TargetWidth;j++)
         {
             BYTE b = pDIBData[(i*SrcWidth+j)*3+realPitch];
             BYTE g = pDIBData[(i*SrcWidth+j)*3+1+realPitch];
             BYTE r = pDIBData[(i*SrcWidth+j)*3+2+realPitch];
             writein<<=1;
             if ((r+g+b)/3>127)
                 writein
[解决办法]
=1;
             if (++k==8)
             {
                 pitchcount++;
                 file.Write(&writein, 1);
                 writein = 0;


                 k=0;
             }
         }
         if (k != 0)
         {
             writein<<=(8-k);
             file.Write(&writein, 1);
             pitchcount++;
         }
         if (pitchcount%4 != 0)
         {
             writein = 0;
             for (j=0; j<4-pitchcount%4; j++)
                 file.Write(&writein, 1);
         }
     }
     file.Close(); 
    delete pDIBData; 
    pDIBData = NULL;
 }

使用:
我把一张RGB为0,0,255 尺寸为264*264的蓝色二维码(“http://www.csdn.net/”)BMP BIT24的文件 使用你的这个函数
CutPhoto(0,0,384,320); 
我把原BMP 24BIT的 RGB 为 0,0,255 转到单色BITMAP(尺寸为384*320)
左上起始位置 就先不管了

但是我转出来的图片不对 黑黑的 稍许有点白点

弱弱地说句:我直接在WINDOWS画图板上直接 点 “黑白并且另存为BMP 1位单色” 就OK 


[解决办法]
关注四方面问题:
◆彩色转灰度公式
◆灰度转二值算法(阈值、误差分散、网格)
◆每行数据按四字节对齐
◆每行数据按从下到上还是从上到下

热点排行