如题,我已知图片大小和内容,想做成位图文件,并显示。
急急急,各位帮忙啊。

解决方案 »

  1.   

    BITMAPFILEHEADER bmpfile;
    BITMAPINFOHEADER bmpinfo;
    //set bmpfile////////////////////////////
    bmpfile.bfType = 0x4d42; //'BM'
    bmpfile.bfReserved1 = bmpfile.bfReserved2 = 0;
        bmpfile.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
        bmpfile.bfSize = bmpfile.bfOffBits;//+10000-14;//m_nSize;
    //set bmpinfo///////////////////////////////////
        bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
    bmpinfo.biWidth = 100;  //m_nW;
    bmpinfo.biHeight = 100;   //m_nH;
    bmpinfo.biPlanes = 1;
    bmpinfo.biBitCount = 24;
    bmpinfo.biCompression = BI_RGB;
    bmpinfo.biSizeImage = 0;
    bmpinfo.biXPelsPerMeter = 0;
    bmpinfo.biYPelsPerMeter = 0;
    bmpinfo.biClrUsed = 0;
    bmpinfo.biClrImportant = 0;
        CFile file("abc.bmp",CFile::modeCreate|CFile::modeWrite);   //open a file for test
        file.Write(&bmpfile,sizeof(BITMAPFILEHEADER));
    file.Write(&bmpinfo,sizeof(BITMAPINFOHEADER));
        m_RGB = new RGBTRIPLE[100*100];
    for(int i=0;i<10000;i++)            //  bmp data
    {   
    m_RGB[i].rgbtBlue=(15);
    m_RGB[i].rgbtGreen =(255);
    m_RGB[i].rgbtRed = (255);
    }
    file.Write(m_RGB,30000);            //write to a file
    仔细研究BITMAPFILEHEADER 和 BITMAPINFOHEADER 两个结构  就ok 了
    装到内存显示,还是重新从file读进内存显示都可以
      

  2.   

    如果是DIB的话:
    //数据加信息头
    HDIB AddDIBInfo(BYTE *pImage, int h, int w)
    {
    HDIB hDib = NULL;
    hDib = (HDIB)GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER)+3*w*h);
    BYTE* lpDib = (BYTE*)GlobalLock((HGLOBAL)hDib);
    BYTE* lpDIBBits = (BYTE*)lpDib+sizeof(BITMAPINFOHEADER);
    BITMAPINFO* pbmi = (BITMAPINFO*)lpDib;
    memset(pbmi, 0, sizeof(BITMAPINFOHEADER));
    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = w;
    pbmi->bmiHeader.biHeight = h;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 24;
    pbmi->bmiHeader.biCompression = BI_RGB;
    for(i = 0; i < 3*w*h; i++)
    {
    *(lpDIBBits+i) = *(pImage+i);
    }
    ::GlobalUnlock((HGLOBAL)hDib);
    return hDib;
    }
    //保存
    BOOL SaveDIB(HDIB hDib, CFile& file)
    { BITMAPFILEHEADER bmfHdr;
    LPBITMAPINFOHEADER lpBI;
    // DIB大小
    DWORD dwDIBSize;
    if (hDib == NULL)
    {
    // 如果DIB为空,返回FALSE
    return FALSE;
    }
    // 读取BITMAPINFO结构,并锁定
    lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
    if (lpBI == NULL)
    {
    // 为空,返回FALSE
    return FALSE;
    }
    // 文件类型"BM"
    bmfHdr.bfType = 0x4d42;
    dwDIBSize = *(LPDWORD)lpBI)+(lpBI->biWidth)*(lpBI->biHeight)*3;
    // 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
    bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
    // 两个保留字
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    // 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
    // 尝试写文件
    TRY
    {
    // 写文件头
    file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
    // 写DIB头和象素
    file.WriteHuge(lpBI, dwDIBSize);
    }
    CATCH (CFileException, e)
    {
    // 解除锁定
    ::GlobalUnlock((HGLOBAL) hDib);
    // 抛出异常
    THROW_LAST();
    }
    END_CATCH
    // 解除锁定
    ::GlobalUnlock((HGLOBAL) hDib);
    // 返回TRUE
    return TRUE;
    }
    只要有了图像的HDIB,显示只要调用StretchDIBits就可以了
      

  3.   

    oid CImageRetrievalView::OnDraw(CDC* pDC) 
    {

    UpdateData(FALSE); //把m_JiShu中的数传给EDIT控件,对图像计数

    // TODO: Add your specialized code here and/or call the base class

    //以下是对打开关键图进行显示

    CWnd* pWnd = GetDlgItem(IDC_KEY_IMAGE);//得到指向该ID的窗口类的指针
    CRect rectWnd;
    pWnd->GetWindowRect(&rectWnd);    //得到该窗口的大小
        

    //以下代码是为了防止宽高比不同的图像,显示在宽高比固定的Picture控件中,会出现变形
    double wk = 0,hk = 0,wc = 0,hc = 0;
    wk = GetDocument()->keyimage.getWidth();
    hk = GetDocument()->keyimage.getHeight();
    wc = rectWnd.Width();
    hc = rectWnd.Height();

    if (wk / hk > wc / hc)  //这种情况,说明控件中的高度过大,所以高度不用全部显示
    {
    double hcnew = (hk / wk)*wc;
    rectWnd.top = int (rectWnd.top + (hc-hcnew)/2);
    rectWnd.bottom = int (rectWnd.bottom - (hc-hcnew)/2);
    }
    else if (wk / hk < wc / hc)//这种情况,说明控件中的宽度过大,所以宽度不用全部显示
    {
    double wcnew = (wk / hk)*hc;
    rectWnd.left = int (rectWnd.left + (wc-wcnew)/2);
    rectWnd.right = int (rectWnd.right - (wc-wcnew)/2);
    }
        
    ScreenToClient(rectWnd);          //将屏幕的图像转换成窗口尺寸的大小来显示
    GetDocument()->keyimage.draw(pDC->GetSafeHdc(), rectWnd); 
    //显示该图像,因为image是在CImageRetrievalDoc类中定义的,所以
    //先要得到Document类的指针,GetDocument()就是用来得到该指针的
    }