有关单色位图创建和保存的问题,大家帮我看看,谢谢啦~

我先准备了两张像素为100*100的单色位图(0.bmp 1.bmp),想将它们以二进制的形式复制(横向)并保存到compose.bmp 中,00.bmp 起到一个中转的作用,期间要对位图结构进行创建

由于从网上搜到的函数跟不是很匹配,而且不是对单色位图进行处理的,所以我就把下的自己改了一下

一开始调试运行,会生成901M的位图,后来发现是CreatBMP SaveNewImage 两个函数的图片大小不知道怎么出问题了,所以我直接对新位图的尺寸进行赋值(原函数是通过函数取的),即宽 200 像素,高 100 像素

继续调试,这回生成的图片 20K ,但是图片是黑的,没有任何信息

于是,我想应该是调色板的部分出了问题,由于原函数调色板处,没看懂代码,所以我当时没有动那块儿

不过对单色位图的调色板不太会创建,所以请各位老大帮忙下,谢谢啦

//

下面的这个函数是对图片进行合并的函数

BOOL CTESTDlg::ImageCompose(CString strimage1, CString strimage2)

{

 CDib image1,image2;//新建位图对象,CDib类网上很多下载

 image1.Load(strimage1);//加载两幅图片 load函数是DIB类里带的

 image2.Load(strimage2);

 

//获得位图需要用到的信息,如尺寸和位图指针

       //函数GetDIBInf返回一个指向BITMAPINFO结构的指针

 BITMAPINFO *infoimage1 = image1.GetDIBInfo();              

 BITMAPINFO *infoimage2 = image2.GetDIBInfo();

       //函数GetDIBBits获取image1的指针

 unsigned char *dataimage1 = image1.GetDIBBits();                

 unsigned char *dataimage2 = image2.GetDIBBits();

       //获取位图的宽、高

 int wimage1 = infoimage1->bmiHeader.biWidth;              

 int himage1 = infoimage1->bmiHeader.biHeight;

 int wimage2 = infoimage2->bmiHeader.biWidth;

 int himage2 = infoimage2->bmiHeader.biHeight;

       //获取新建位图的宽、高

 int wnewimage,hnewimage;

 wnewimage = wimage1+wimage2;

 hnewimage = himage1;//取小值,否则报错

//  CClientDC dc(&m_resultimage); 

 

//新建NEWIMAGE,只要尺寸符合标准即可,此函数网上也很多,这是我自己写的,篇幅有限就没有粘贴上来。

//这块的CreatBMP是我自己从网上找的,然后自己改的,好像问题出在这里!!!

CDib temp;

 HBITMAP hbit = temp.CreatBMP(wnewimage,hnewimage,1);

 

//保存新建的位图,方便后面调用

//这个SaveNewImage 也是我从网上找的,然后自己改的,貌似这个函数里面也有问题!!!

 temp.SaveNewImage(hbit,"f://00.bmp",1);

 CDib newimage;

 if(newimage.Load("f://00.bmp")==false)

  return FALSE;

 

//获得新位图NEWIMAGE的指针

 unsigned char *dataimagenew = newimage.GetDIBBits();

 

//下面的一大段被我直接删掉了,因为不是很明白

// GetBMPImagePixelsPerLine(wnewimage)这个函数看注释是获得每行的字节数,但我的理解,图片在用二进制形式复制的话应该是按位复制吧?不知道我理解的是否正确?那个for循环式就是我按照这个理解写的。

//下面是关键算法:一行行“扫描”,有hnewimage行,1列。每一行有GetBMPImagePixelsPerLine(wnewimage字节。这个函数是这样的:

 

//int CTESTDlg::GetBMPImagePixelsPerLine(int ImageX)//获得一个扫描行所占的字节数

//{

// int weishu = 24;//图像位数

// int bytes_per_line ;

// bytes_per_line=(ImageX*weishu+31)/8;

// bytes_per_line=bytes_per_line/4*4;//得到图像的一行的位数

// return bytes_per_line;

//}

 

// 我这里很多地方都乘以了3,是因为位图的位数位24

 

// for (int i = 0; i <hnewimage; ++i ){

//

// //先将IMAGE1复制过去

//       for (int j = 0; j < himage1; ++j )     {

//            dataimagenew[j+i*GetBMPImagePixelsPerLine(wnewimage)] = dataimage1[j+i*GetBMPImagePixelsPerLine(wimage1)];

//     }

//

再将IMAGE2复制过去

//     for (int n = 0; n < himage2; ++n)    {

//   dataimagenew[n+GetBMPImagePixelsPerLine(wimage1)+i*GetBMPImagePixelsPerLine(wnewimage)] = dataimage2[n+i*GetBMPImagePixelsPerLine(wimage2)];

//     } 

//  }

 

 for (int i = 0; i < 100; ++i)

 {

 //先将IMAGE1复制过去

       for (int j = 0; j < 100; ++j)

          {

            dataimagenew[j+i*200] = dataimage1[j+i*100];

     }

 

//再将IMAGE2复制过去

     for (int n = 0; n < 100; ++n)

        {

   dataimagenew[n+100+i*200] = dataimage2[n+i*100];

     } 

 }

 

//保存合并后的位图 save 函数是DIB类里带的

 newimage.Save("f://compose.bmp");

 DeleteObject(hbit);

 

return true;

}

///

这个是CreatBMP,我从网上下了,改的

HBITMAP CDib::CreatBMP(int width, int height, unsigned short biBitCount)

{

int   dwidth   = width*biBitCount;          //这块不太明白是什么意思

WORD   color_num = 2;           //还有这里

 

//compute   the   dib   data   size

//dwidth   is   the   image   data   bits 's   size

 

DWORD   dwBitSize   =   dwidth*height   +   40   +   color_num*sizeof(RGBQUAD);         //此处未完成,最后color_num*sizeof(RGBQUAD)不理解

 

LPSTR   pDIB;//pointer   to   the   DIB

 

HBITMAP   hBitmap   =   (HBITMAP)   ::GlobalAlloc(GMEM_MOVEABLE   |   GMEM_ZEROINIT,dwBitSize);

if   (hBitmap   ==   0)

{

return   NULL;

}

 

pDIB   =   (LPSTR)   ::GlobalLock((HGLOBAL)   hBitmap);

 

LPBITMAPINFO   lpmf   =   (LPBITMAPINFO)pDIB;

 

lpmf-> bmiHeader.biSize   =   40;

lpmf-> bmiHeader.biWidth   =   width;

lpmf-> bmiHeader.biHeight   =   height;

lpmf-> bmiHeader.biPlanes   =   1;

lpmf-> bmiHeader.biBitCount   =   biBitCount;

lpmf-> bmiHeader.biCompression   =   BI_RGB;

lpmf-> bmiHeader.biSizeImage   =   dwidth*height;

lpmf-> bmiHeader.biXPelsPerMeter   =   0;

lpmf-> bmiHeader.biYPelsPerMeter   =   0;

lpmf-> bmiHeader.biClrUsed   =   0;

lpmf-> bmiHeader.biClrImportant   =   0;

 

//此处对调色板的处理不理解

if(color_num!=0)

{

int   i;

for(i=0;i <color_num;i++)

{

lpmf-> bmiColors[i].rgbRed   =   (BYTE)   i;

lpmf-> bmiColors[i].rgbGreen   =   (BYTE)   i;

lpmf-> bmiColors[i].rgbBlue   =   (BYTE)   i;

}

}

 

::GlobalUnlock((HGLOBAL)   hBitmap);

 

return   hBitmap;

}

/

BOOL CDib::SaveNewImage(HBITMAP hbitmap, LPSTR filename, int nColor)

{

BITMAP Bitmap;

 HDC         hDC;                        

 DWORD     dwPaletteSize=0 ,  dwBmBitsSize,  dwDIBSize,   dwWritten;    

 BITMAPFILEHEADER       bmfHdr;                  

 BITMAPINFOHEADER       bi;                          

 LPBITMAPINFOHEADER   lpbi;          

 HANDLE   fh,   hDib,   hPal,hOldPal=NULL;  

   

 if   (nColor<=   8)  

  dwPaletteSize   =   (1<<nColor)   *sizeof(RGBQUAD);   //这里不明白是什么意思当时自己改的时候直接把 dwPaletteSize = 8

 GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&Bitmap);

 bi.biSize = sizeof(BITMAPINFOHEADER);

 bi.biWidth = 200;

 bi.biHeight = 100;

 bi.biPlanes = 1;

 bi.biBitCount = nColor;

 bi.biCompression = BI_RGB;

 bi.biSizeImage = 0;

 bi.biXPelsPerMeter = 0;

 bi.biYPelsPerMeter = 0;

 bi.biClrUsed = 0;

 bi.biClrImportant = 0;

 dwBmBitsSize   =   ((Bitmap.bmWidth  *   nColor+31)/32*4)*Bitmap.bmHeight;     //这里不明白为什么这样计算,我当时是直接用宽×高,直接复制20000

 //为位图分配内存

 hDib=  GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));  

 lpbi   =   (LPBITMAPINFOHEADER)GlobalLock(hDib);  

 *lpbi   =   bi;

 //设置调色板   这部分当时没看懂,后来改调色板时直接把这里删掉了,想自己用二进制方式创建一个的,不过貌似创建的有问题

 hPal   =   GetStockObject(DEFAULT_PALETTE);      

 if   (hPal)  

 {  

  hDC     =   ::GetDC(NULL);  

  hOldPal   =   SelectPalette(hDC,   (HPALETTE)hPal,   FALSE);  

  RealizePalette(hDC);  

 } 

 // 获取该调色板下新的像素值

 GetDIBits(hDC,   hbitmap,   0,   Bitmap.bmHeight,

  (LPSTR)lpbi   +   sizeof(BITMAPINFOHEADER)+dwPaletteSize,  

        (BITMAPINFO   *)lpbi,   DIB_RGB_COLORS);  

 if   (hOldPal)  

 {  

  SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);  

  RealizePalette(hDC);  

  ::ReleaseDC(NULL,hDC);  

 }  

/

我是这样创建的,不过这样做的话,*lpbi   =   bi 这一步就不行了,应为bi 要包含调色板,原来是不包含的,然后我就不太会了

bi.bmiColors[0].rgbBlue = 0x00;

 bi.bmiColors[0].rgbGreen = 0x00;

 bi.bmiColors[0].rgbRed = 0x00;

 bi.bmiColors[0].rgbReserved = 0x00;

 bi.bmiColors[1].rgbBlue = 0xff;

 bi.bmiColors[1].rgbGreen = 0xff;

 bi.bmiColors[1].rgbRed = 0xff;

 bi.bmiColors[1].rgbReserved = 0x00;

/

 

 fh   =   CreateFile(filename,   GENERIC_WRITE,    

        0,//not   be   shared  

        NULL,   //cannot   be   inherited  

        CREATE_ALWAYS,  

        FILE_ATTRIBUTE_NORMAL   |   FILE_FLAG_SEQUENTIAL_SCAN,    

        NULL);  

   

 if   (fh   ==   INVALID_HANDLE_VALUE)  

  return   FALSE;  

 //设置位图文件头

 bmfHdr.bfType   =   0x4D42;     //   "BM"  

 dwDIBSize           =   sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;      

 bmfHdr.bfSize   =   dwDIBSize;  

 bmfHdr.bfReserved1   =   0;  

 bmfHdr.bfReserved2   =   0;  

 bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+   dwPaletteSize;  

 

 //write   file   header  

 WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),   &dwWritten,   NULL);  

 

 //write   bmp   data  

 WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,   &dwWritten,   NULL);  

 

 GlobalUnlock(hDib);  

 GlobalFree(hDib);  

 CloseHandle(fh);  

 DeleteObject(hbitmap);   

 return   TRUE; 

}

 

至于DIB中的load save ,我改的主要是位图尺寸的取得方式,我直接给它们赋值,还有就是调色板大小,也是直接赋值的,8字节,觉得应该没什么问题,就不贴了,已经很多了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值