我在视图中画的图怎么样把他存成BMP的图?

解决方案 »

  1.   

    有很多以前的文章
    http://expert.csdn.net/Expert/topic/2302/2302117.xml?temp=.7770197
    http://expert.csdn.net/Expert/topic/2350/2350656.xml?temp=.7658502
    这几个讲得都不错。
      

  2.   

    这个函数是我在做把屏幕的内容存为图像时写的,所以位图的高和宽是以屏幕为大小的,你把里边改一下就行了。用的时候你可以把视图中的的位图对象提取出来,并把位图句柄拿来用就可以了。/////////////////////////////////////////////////////////////////////////////
    //////////////*************//////////////////////////////////////////////////
    //本函数实现把一个存在于内存中的代表一张位图的位图句柄给存到文件中去。
    //第一个参数是位图句柄
    //第二个参数是要保存的位图文件名,带全路径
    //返回值为FALSE表示函数失败
    //返回值为TRUE表示函数成功
    BOOL SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName) //hBitmap 为屏幕位图句柄
    {      //lpFileName 为位图文件名带全路径
    HDC hDC; //设备描述表   
        int iBits;//当前显示分辨率下每个像素所占字节数 
    WORD wBitCount;//位图中每个像素所占字节数   
         //定义调色板大小, 位图中像素字节大小  位图文件大小 , 写入文件字节数
    DWORD dwPaletteSize=0,dwBmBitsSize, dwDIBSize, dwWritten;
    BITMAP Bitmap;//位图属性结构
    BITMAPFILEHEADER bmfHdr;//位图文件头结构
        BITMAPINFOHEADER bi;//位图信息头结构 
    LPBITMAPINFOHEADER lpbi;//指向位图信息头结构
        HANDLE fh, hDib; //定义文件,分配内存句柄,调色板句柄
    HPALETTE hPal,hOldPal=NULL;  
       //计算位图文件每个像素所占字节数
    hDC = ::CreateDC("DISPLAY",NULL,NULL,NULL);
    iBits = ::GetDeviceCaps(hDC, BITSPIXEL)* ::GetDeviceCaps(hDC, PLANES);
    ::DeleteDC(hDC);
        if (iBits<=1)
    wBitCount = 1;
        else if (iBits <=4)
            wBitCount = 4;
        else if (iBits <= 8)
            wBitCount = 8;
        else if (iBits<=24)
            wBitCount = 24;
        //计算调色板大小
        if (wBitCount<= 8)
            dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);   
       //设置位图信息头结构
        ::GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
        bi.biSize            = sizeof(BITMAPINFOHEADER);
        bi.biWidth           = Bitmap.bmWidth;
        bi.biHeight          = Bitmap.bmHeight;
        bi.biPlanes          = 1;
        bi.biBitCount        = wBitCount;
        bi.biCompression     = BI_RGB;
        bi.biSizeImage       = 0;
        bi.biXPelsPerMeter   = 0;
        bi.biYPelsPerMeter   = 0;
        bi.biClrUsed         = 0;
        bi.biClrImportant    = 0;    dwBmBitsSize =((Bitmap.bmWidth*wBitCount+31)/32)* 4*Bitmap.bmHeight;
        //为位图内容分配内存
        hDib  = ::GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
        lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
        *lpbi = bi;
        // 处理调色板   
        hPal = (HPALETTE)::GetStockObject(DEFAULT_PALETTE);
        if (hPal)
        {
    hDC  = ::GetDC(NULL);
            hOldPal = ::SelectPalette(hDC, hPal, FALSE);
            ::RealizePalette(hDC);
        }
        // 获取该调色板下新的像素值
        ::GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
    (LPBITMAPINFO )lpbi, DIB_RGB_COLORS);
        //恢复调色板   
        if (hOldPal)
        {
       ::SelectPalette(hDC, hOldPal, TRUE);
       ::RealizePalette(hDC);
       ::ReleaseDC(NULL, hDC);
        }
       //创建位图文件    
        fh = ::CreateFile(lpFileName, GENERIC_WRITE,0, NULL, 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;
        // 写入位图文件头
        ::WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
        // 写入位图文件其余内容
        ::WriteFile(fh, (LPSTR)lpbi, dwDIBSize,&dwWritten, NULL);
        //清除   
        ::GlobalUnlock(hDib);
        ::GlobalFree(hDib);
        ::CloseHandle(fh);
    return TRUE;
    }
      

  3.   

    分配一个内存,
    自己做一个BMP文件头,
    如果是256色还要调色板,
    把这些连同你画的图象象素值COPY到内存,将这块内存存到文件
      

  4.   

    CBitmapDoc* pDoc=GetDocument();
    CFileException fe;
    //如果文件名未定,调用“另存为”函数
    CString sFileName=pDoc->GetTitle();
    sFileName.MakeLower();
    /*if(sFileName=="untitled"||sFileName=="无标题")
    {
    OnFileSaveAs();
    return;
    }*/ CFile *pFile=new CFile(sFileName,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
    if(pFile==NULL)
    return;
    CArchive saveArchive(pFile,CArchive::store|CArchive::bNoFlushOnDelete);
    saveArchive.m_pDocument=pDoc;
    saveArchive.m_bForceFlat=TRUE;
    //保存
    pDoc->SetModifiedFlag(FALSE);
    saveArchive.Close();
    pDoc->ReleaseFile(pFile,FALSE);
      

  5.   

    BMP文件是Windows保存图像的一种通用文件格式,在数字图像处理方面占有重要的地位。BMP文件中保存的图像数据是一种DIB(Device-Independent Bitmap,即设备无关位图),DIB是标准的Windows位图格式,它自带颜色信息,因此调色板管理非常容易。有许多文章是关于讲述如何将BMP文件读取、显示的,而如何将数据保存为BMP文件则不是太多,本文作者通过一个实例讲述这一过程。
    一、 BMP文件的结构
    要想把数据正确地保存为BMP文件,首先对BMP文件的结构应该有一个清晰的了解。一个BMP文件大体上分成如下4个部分,如图1所示。
    ①王军伟,在读博士研究生,中国农业大学(东区)214#信箱,研究方向:图像处理,智能交通
    1、 第一部分为位图文件头BITMAPFILEHEADER,它是一个结构,其定义如下:
    typedef struc tagBITMAPFILEHEADER{
             WORD  bfType;
             WORD  bfSize;
             WORD  bfReserved1;
             WORD  bfReserved2;
             WORD  bfOffBits;
    }BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
    该结构的长度是固定的,为14个字节,各个域的说明如下:
    &#61656; bfType:指定文件类型,必须是0x4d42,即字符串“BM”。
    &#61656; bfSize:指定文件大小,包括这14个字节。
    &#61656; bfReserved1,bfReserved2:保留字,为0。
    &#61656; bfOffBits:从文件头到实际的位图数据的偏移字节数,即图1中前三个部分的长度之和。
    2、 第二部分为位图信息头BITMAPINFOHEADER,它也是一个结构,其定义如下:
    typedef struc tagBITMAPINFOHEADER{
              DWORD  biSize;
              LONG   biWidth;
              LONG   biHeight;
              WORD   biPlanes;
              WORD   biBitCount;
              DWORD  biCompression;
              DWORD  biSizeImage;
              LONG   biXPelsPerMeter;
              LONG   biYPelsPerMeter;
              DWORD  biClrUsed;
              DWORD  biClrImportant;
    }BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
    该结构的长度也是固定的,为40个字节,各个域的说明如下:
    &#61656; biSize:指定这个结构的长度,为40个字节。
    &#61656; biWidth:指定图像的宽度,单位是象素。
    &#61656; biHeight:指定图像的高度,单位是象素。
    &#61656; biPlanes:必须是1。
    &#61656; biBitCount:指定表示颜色时用到的位数,常用的值为1(黑白二色图)、4(16色图)、8(256色图)、24(真彩色图)。
    &#61656; biCompression:指定位图是否压缩,有效值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位图可采用RLE4和RLE8的压缩格式,BI_RGB表示不压缩。
    &#61656; biSizeImage:指定实际的位图数据占用的字节数,可用以下的公式计算出来:
                 biSizeImage = biWidth’× biHeight
        要注意的是:上述公式中的biWidth’必须是4的整数倍(不是biWidth,而是大于或等于biWidth的离4最近的整数倍)。如果biCompression为BI_RGB,则该项可能为0。
    &#61656; biXPelsPerMeter:指定目标设备的水平分辨率。
    &#61656; biYPelsPerMeter:指定目标设备的垂直分辨率。
    &#61656; biClrUsed:指定本图像实际用到的颜色数,如果该值为0,则用到的颜色数为2的biBitCount次幂。
    &#61656; biClrImportant:指定本图像中重要的颜色数,如果该值为0,则认为所有的颜色数都是重要的。
    3、 第三部分为调色板。有些位图需要调色板,有些位图,如真彩色图,不需要调色板,
    它们的BITMAPINFOHEADER后面直接是位图数据。
    调色板实际上是一个数组,共有biClrUsed个元素(如果该值为0,则有2的biBitCount次幂个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:
    typedef struct tagRGBQUAD{
             BYTE   rgbBlue;
             BYTE   rgbGreen;
             BYTE   rgbRed;
             BYTE   rgbReserved;
    }RGBQUAD;
    其中:
    &#61656; rgbBlue:该颜色的蓝色分量。
    &#61656; rgbGreen:该颜色的绿色分量。
    &#61656; rgbRed:该颜色的红色分量。
    &#61656; rgbReserved:保留值。
    4、 第四部分就是实际的图像数据。对于用到调色板的位图,图像数据就是该象素颜色
    在调色板中的索引值,对于真彩色图,图像数据就是实际的R、G、B值。
    &#61656; 对于2色图,用1位就可以表示该象素的颜色,所以1个字节可以表示8个象素。
    &#61656; 对于16色图,用4位可以表示一个象素的颜色,所以1个字节可以表示2个象素。
    &#61656; 对于256色图,1个字节刚好可以表示1个象素。
    &#61656; 对于真彩色图,3个字节才能表示1个象素。
      

  6.   

    二、 保存实例
    1、 图像数据
    图像数据来源于图像采集卡所采集的图像的一部分,保存在一Buffer中(char *lp1),图像高度为110个象素(保存在变量 int m_Width中),宽度为228个象素(保存在变量 int m_Height中,并且是4的整倍数),图像为一256色灰度图。
    2、实例代码
    BITMAPFILEHEADER bmfHdr; //定义文件头
    BITMAPINFOHEADER bmiHdr; //定义信息头
    RGBQUAD rgbQuad[256];    //定义调色板
            //对信息头进行赋值
    bmiHdr.biSize = sizeof(BITMAPINFOHEADER);
    bmiHdr.biWidth = m_WidthOfModel;
    bmiHdr.biHeight = m_HeightOfModel;
    bmiHdr.biPlanes = 1;
    bmiHdr.biBitCount = 8;
    bmiHdr.biCompression = BI_RGB;
    bmiHdr.biSizeImage = m_WidthOfModel*m_HeightOfModel;
    bmiHdr.biXPelsPerMeter = 0;
    bmiHdr.biYPelsPerMeter = 0;
    bmiHdr.biClrUsed = 0;
    bmiHdr.biClrImportant = 0;
            //对调色板进行赋值
    for(i=0; i<256; i++)
    {
    rgbQuad[i].rgbBlue = (BYTE)i;
    rgbQuad[i].rgbGreen = (BYTE)i;
    rgbQuad[i].rgbRed = (BYTE)i;
    rgbQuad[i].rgbReserved = 0;
    }
            //对文件头进行赋值
    bmfHdr.bfType = (WORD)0x4D42;//;((WORD)('M'<<8) | 'B')
    bmfHdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256 + m_WidthOfModel*m_HeightOfModel);
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    bmfHdr.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO        HEADER)+sizeof(RGBQUAD)*256);
            //保存文件
    CFile fp;
    fp.Open("d:\\Model.bmp",CFile::modeCreate | CFile::modeWrite);
    fp.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER)); //写文件头
    fp.Write((LPSTR)&bmiHdr,sizeof(BITMAPINFOHEADER)); //写信息头
    fp.Write((LPSTR)rgbQuad,sizeof(RGBQUAD)*256); //写调色板
        fp.Write(lpvBuffer2Bits,m_WidthOfModel*m_HeightOfModel);//写数据
    fp.Close();
      

  7.   

    把stringtable 中的IDR_MAINFRAME 一项的第四个和第五个参数改为.bmp 即可。