HBITMAP hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);          // 创建单色掩码位图 
HDC     hMaskDC = CreateCompatibleDC(hdcDest); // 设置背景色 
SetBkColor(hImageDC, crTransparent); // 生成透明区域为白色,其它区域为黑色的掩码位图 
//彩色转单色,如果是背景色转换为1,非背景色,转换为0
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); 

解决方案 »

  1.   

    不好意思,不太理解你这个,还能具体点吗?网上搜了一大堆都是生成的biBitCount=24的位图,方法也不尽相同,我写的dll需要调用这个函数生成一个单色位图的int Down_Bitmap(char *BitmapName,int Width,int Height,char *BitmapData)BitmapName,生成图的名字,BitmapData位图数据
      

  2.   

    函数原型:HBITMAP CreateBitmap(int nWidth,int nHeight, UINT cPlanes, UINT cBitsPeral,CONST VOID *lpvBits);
    参数:
    nWidth:指定位图宽度、单位为像素。
    nHeight:指定位图高度、单位为像素。
    CPlanes:指定该设备使用的颜色位面数目
    CBitsPerPel:指定用来区分单个像素点颜色的位数(比特数目)。
    LpvBits:指向颜色数据数组指针。这些颜色数据用来设置矩形区域内像素的颜色。矩形区域中的每一扫描线必须是双字节的整数倍(不足部分以0填充)。如果该参数为NULL,将不对新生成的位图进行初始化。
    返回值:如果函数成功,那么返回值是位图的句柄;如果失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError函数。
    红色的 2个 1,1 就是
      

  3.   

    谢谢了,以前从来没有做过GDI,hdcDest和hImageDC分别怎么来的呢?创建好之后怎么保存到某个路径呢?
      

  4.   

     int Down_Bitmap(char *BitmapName,int Width,int Height,char *BitmapData)
    {
    CBitmap bmpNew;
      BOOL bRet = bmpNew.CreateBitmap(Width, Height, 1, 1, BitmapData);
      if(bRet)
      {
      TRACE(_T("OK"));   }
    else
    { TRACE(_T("False"));
    }
    BITMAP bmNew;
    bmpNew.GetBitmap(&bmNew);
    char szFileName[32];
    sprintf(szFileName, "c:/%04d.bmp",BitmapName);  
    FILE* fBmp = fopen(szFileName, "wb");
    BITMAPFILEHEADER bmHead;
    ZeroMemory(&bmHead, sizeof(bmHead)); bmHead.bfSize = sizeof(bmHead);
    bmHead.bfType = 0x4d42;
    bmHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fwrite(&bmHead, sizeof(bmHead), 1, fBmp); BITMAPINFOHEADER bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo));
    bmpInfo.biSize = sizeof(bmpInfo);
    bmpInfo.biWidth = bmNew.bmWidth;
    bmpInfo.biHeight = bmNew.bmHeight;
    bmpInfo.biPlanes = bmNew.bmPlanes;
    bmpInfo.biBitCount = bmNew.bmBitsPixel;
    bmpInfo.biSizeImage = ((bmNew.bmWidth * bmNew.bmBitsPixel) + 7) / 8 * bmNew.bmHeight;
    BYTE* pData = new BYTE[bmpInfo.biSizeImage];
       bmpNew.GetBitmapBits(bmpInfo.biSizeImage, (LPVOID)pData);
       fwrite(pData, bmpInfo.biSizeImage, 1, fBmp);
       delete []pData;
       fclose(fBmp);
    }
    这么调用的char BitmapName[5]={'0','0','0','1','\0'};
    char BitmapData[50]={0xff};
    Down_Bitmap(BitmapName,30,50,BitmapData);
    大家帮我看看写的代码哪里有不对的地方吗?谢谢
      

  5.   

    char BitmapName[6]="00010";
    char BitmapData[500000]={0};
    int ret=Down_Bitmap(BitmapName,30,50,BitmapData);
      

  6.   

    sprintf(szFileName, "C://%04s.bmp",BitmapName); BitmapName=0001
    HBITMAP bmpball,bmpBk;  
    bmpball = (HBITMAP)LoadImage( NULL, (LPCWSTR)szFileName, IMAGE_BITMAP, 0, 0,
    LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    总是加载图片失败,GetLastError()=2,找不到文件
      

  7.   

    现在我生成的单色bmp不是全白的背景,怎么生成全白背景呢?
      

  8.   

    你不是 “LoadImage” 的吗 ?
    怎么 又是 Create ?
      

  9.   

    先生成一个单色的白板bmp,然后才加载获取的,loadimage的问题解决了,现在发现生成的白板bmp有点问题?不知道哪里出错了,麻烦帮我看看。下面是代码:
    int creatBMP()
    {
     CBitmap bmpNew;
      BOOL bRet = bmpNew.CreateBitmap(640, 384, 1, 1, NULL); /*memDC.SelectObject(bmpNew);
    memDC.SetBkColor(RGB(0, 244, 0));
    memDC.TextOut(0, 0, _T("AAA"));
    memDC.LineTo(10, 10);*/ BITMAP bmNew;
    bmpNew.GetBitmap(&bmNew); 
    FILE* fBmp = fopen("D:\\back.bmp", "wb");

    int widthbytes  = (int)((bmNew.bmWidth*bmNew.bmBitsPixel+31)/32)*4; 
    BITMAPFILEHEADER bmHead;
    ZeroMemory(&bmHead, sizeof(bmHead));
    bmHead.bfType = 0x4d42;
    //bmHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmHead.bfOffBits =(DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2*4);  
    //bmHead.bfSize = sizeof(bmHead);
    bmHead.bfSize=(DWORD)(bmHead.bfOffBits + bmNew.bmHeight * widthbytes); 
    fwrite(&bmHead, sizeof(bmHead), 1, fBmp); BITMAPINFOHEADER bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo));
    bmpInfo.biSize = sizeof(bmpInfo);
    bmpInfo.biWidth = bmNew.bmWidth;
    bmpInfo.biHeight = bmNew.bmHeight;
    bmpInfo.biPlanes = bmNew.bmPlanes;
    bmpInfo.biBitCount = bmNew.bmBitsPixel;
    bmpInfo.biSizeImage = bmNew.bmHeight * widthbytes; fwrite(&bmpInfo, sizeof(bmpInfo), 1, fBmp); BYTE* pData = new BYTE[bmpInfo.biSizeImage];
       bmpNew.GetBitmapBits(bmpInfo.biSizeImage, (LPVOID)pData);
       for(int i=0;i<bmpInfo.biSizeImage;i++)
       {
       pData[i]=0xff;
       }
    //这里给图形数据都赋成1来显示白板,这样不知道行不行?还是有其他的方法?
       fwrite(pData, bmpInfo.biSizeImage, 1, fBmp);    delete []pData;
       fclose(fBmp);
       return 1;
    }
      

  10.   

    for(int i=0;i<bmpInfo.biSizeImage;i++)
       {
       pData[i]=0xff;
       }memset(pData,0xFF,bmpInfo.biSizeImage)
      

  11.   

    这两个有区别吗?这样的方式生成的白板图片可用吗?因为后面我还要加载这个白板然后把一个小图片贴上去,现在出现的问题是把小图片贴在我自己生成的这个图片上看不见,而从其他地方找来的图片就能看见,这啥问题?上面的那段代码有问题吗?
    bmHead.bfType = 0x4d42;
    //bmHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmHead.bfOffBits =(DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2*4);  
    //bmHead.bfSize = sizeof(bmHead);
    bmHead.bfSize=(DWORD)(bmHead.bfOffBits + bmNew.bmHeight * widthbytes); 
    fwrite(&bmHead, sizeof(bmHead), 1, fBmp);BITMAPINFOHEADER bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo));
    bmpInfo.biSize = sizeof(bmpInfo);
    bmpInfo.biWidth = bmNew.bmWidth;
    bmpInfo.biHeight = bmNew.bmHeight;
    bmpInfo.biPlanes = bmNew.bmPlanes;
    bmpInfo.biBitCount = bmNew.bmBitsPixel;
    bmpInfo.biSizeImage = bmNew.bmHeight * widthbytes;这段到底对不对呢?找了很多资料整成这样的,不过还是不确定
      

  12.   


    // If the bitmap is monochrome, the bmiColors member contains two entries.
    // Each bit in the bitmap array represents a pixel. 
    // If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table;
    // if the bit is set, the pixel has the color of the second entry in the table.
    int creatBMP()
    {
    CBitmap bmpNew;
    BOOL bRet = bmpNew.CreateBitmap(640, 384, 1, 1, NULL); BITMAP bmNew;
    bmpNew.GetBitmap(&bmNew); 
    FILE* fBmp = fopen("back.bmp", "wb"); int widthbytes  = (int)((bmNew.bmWidth*bmNew.bmBitsPixel+31)/32)*4; 
    BITMAPFILEHEADER bmHead;
    ZeroMemory(&bmHead, sizeof(bmHead));
    bmHead.bfType = 0x4d42;
    bmHead.bfOffBits =(DWORD)(sizeof(BITMAPFILEHEADER) + 
                          sizeof(BITMAPINFOHEADER) + 
      2*sizeof(RGBQUAD));  
    bmHead.bfSize=(DWORD)(bmHead.bfOffBits + bmNew.bmHeight * widthbytes); 
    // write BITMAPFILEHEADER
    fwrite(&bmHead, sizeof(bmHead), 1, fBmp);
    // 
    BITMAPINFOHEADER bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo));
    bmpInfo.biSize      = sizeof(bmpInfo);
    bmpInfo.biWidth     = bmNew.bmWidth;
    bmpInfo.biHeight = bmNew.bmHeight;
    bmpInfo.biPlanes = bmNew.bmPlanes;
    bmpInfo.biBitCount = bmNew.bmBitsPixel;
    bmpInfo.biSizeImage = bmNew.bmHeight * widthbytes;
    // write BITMAPINFOHEADER
    fwrite(&bmpInfo, sizeof(bmpInfo), 1, fBmp);
    RGBQUAD  bmiColors[2]={{0,0,0,0},{0xFF,0xFF,0xFF,0}}; // white
    // if exchange these 
    // RGBQUAD  bmiColors[2]={{0xFF,0xFF,0xFF,0},{0,0,0,0}}; // black 
    fwrite(bmiColors, 2*sizeof(RGBQUAD), 1, fBmp);
    // write pallete
    BYTE* pData = new BYTE[bmpInfo.biSizeImage];
    bmpNew.GetBitmapBits(bmpInfo.biSizeImage, (LPVOID)pData);
    memset(pData,0xFF,bmpInfo.biSizeImage);
    fwrite(pData, bmpInfo.biSizeImage, 1, fBmp);
    //
    delete []pData;
    fclose(fBmp);
    return 1;
    }、
    注意:
    RGBQUAD  bmiColors[2]={{0,0,0,0},{0xFF,0xFF,0xFF,0}}; // white
    // if exchange these 
    // RGBQUAD  bmiColors[2]={{0xFF,0xFF,0xFF,0},{0,0,0,0}}; // black 
    fwrite(bmiColors, 2*sizeof(RGBQUAD), 1, fBmp);
      

  13.   

    谢谢你的回答,调色板弄好了,现在有一个问题
    char BitmapData[60]={0xE0,0x7E,0x00,0x00,0xE0,0x7E,0x00,0x00,0xE0,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xFC,0x7E,0x00,0x00,0xE0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0xFF,0xFE,0x00,0x00,0xFF,0xFE,0x00,0x00};
    Down_Bitmap(BitmapName,15,15,BitmapData);
    我这样传入数据想显示一个“丁”字,可是查看二值化数据只写进去前30位,红色表示的字节,后面30位全是CD,怎么回事呢?
      

  14.   

    没看到 “Down_Bitmap(BitmapName,15,15,BitmapData);”函数15(2个 字节 一行) ,15(共 15行) = 2 bytes *15= 30 个 字节
      

  15.   

    真是多谢你了,我用下面代码旋转位图有一个问题,旋转45度可以,旋转90度两边就多了两条线。
    HDC RotateAnyAngle(HDC dcSrc,int SrcWidth,int SrcHeight,double angle)
    {
    double x1,x2,x3;
    double y1,y2,y3;
    double maxWidth,maxHeight,minWidth,minHeight;
    double srcX,srcY;
    double sinA,cosA;
    double DstWidth;
    double DstHeight;
    HDC dcDst;//旋转后的内存设备环境
    HBITMAP newBitmap;
    sinA = sin(angle);
    cosA = cos(angle);
    x1 = -SrcHeight * sinA;
    y1 = SrcHeight * cosA;
    x2 = SrcWidth * cosA - SrcHeight * sinA;
    y2 = SrcHeight * cosA + SrcWidth * sinA;
    x3 = SrcWidth * cosA;
    y3 = SrcWidth * sinA;
    minWidth = x3>(x1>x2?x2:x1)?(x1>x2?x2:x1):x3;
    minWidth = minWidth>0?0:minWidth;
    minHeight = y3>(y1>y2?y2:y1)?(y1>y2?y2:y1):y3;
    minHeight = minHeight>0?0:minHeight;
    maxWidth = x3>(x1>x2?x1:x2)?x3:(x1>x2?x1:x2);
    maxWidth = maxWidth>0?maxWidth:0;
    maxHeight = y3>(y1>y2?y1:y2)?y3:(y1>y2?y1:y2);
    maxHeight = maxHeight>0?maxHeight:0;
    DstWidth = maxWidth - minWidth;
    DstHeight = maxHeight - minHeight;
    dcDst = CreateCompatibleDC(dcSrc);
    newBitmap = CreateCompatibleBitmap(dcSrc,(int)DstWidth,(int)DstHeight);
    SelectObject(dcDst,newBitmap);
    for( int I = 0 ;I<DstHeight;I++)
    {
    for(int J = 0 ;J< DstWidth;J++)
    {
    srcX = (J + minWidth) * cosA + (I + minHeight) * sinA;
    srcY = (I + minHeight) * cosA - (J + minWidth) * sinA;
    if( (srcX >= 0) && (srcX <= SrcWidth) &&(srcY >= 0) && (srcY <= SrcHeight))
    {
    BitBlt(dcDst, J, I, 1, 1, dcSrc,(int)srcX, (int)srcY, SRCCOPY);
    }
    }
    } //显示旋转后的位图
    HDC pDC = ::GetDC(AfxGetMainWnd()->m_hWnd);
    //CDC*pDC=GetDC();   
    HDC hThisDC=CDC::FromHandle(pDC)->GetSafeHdc();  
    BitBlt(hThisDC,40,40,(int)DstWidth,(int)DstHeight,dcDst,0,0,SRCCOPY);
    return dcDst;
    DeleteObject(newBitmap);
    DeleteDC(dcDst);

    }
    angle= (45/180.0)*3.14159;//旋转45Degree,可为任意角度
    RhBkDC=RotateAnyAngle(hBkDC,640,384,angle);
      

  16.   

    真是多谢你了,我用下面代码旋转位图有一个问题,旋转45度可以,旋转90度两边就多了两条线。
    HDC RotateAnyAngle(HDC dcSrc,int SrcWidth,int SrcHeight,double angle)
    {
    double x1,x2,x3;
    double y1,y2,y3;
    double maxWidth,maxHeight,minWidth,minHeight;
    double srcX,srcY;
    double sinA,cosA;
    double DstWidth;
    double DstHeight;
    HDC dcDst;//旋转后的内存设备环境
    HBITMAP newBitmap;
    sinA = sin(angle);
    cosA = cos(angle);
    x1 = -SrcHeight * sinA;
    y1 = SrcHeight * cosA;
    x2 = SrcWidth * cosA - SrcHeight * sinA;
    y2 = SrcHeight * cosA + SrcWidth * sinA;
    x3 = SrcWidth * cosA;
    y3 = SrcWidth * sinA;
    minWidth = x3>(x1>x2?x2:x1)?(x1>x2?x2:x1):x3;
    minWidth = minWidth>0?0:minWidth;
    minHeight = y3>(y1>y2?y2:y1)?(y1>y2?y2:y1):y3;
    minHeight = minHeight>0?0:minHeight;
    maxWidth = x3>(x1>x2?x1:x2)?x3:(x1>x2?x1:x2);
    maxWidth = maxWidth>0?maxWidth:0;
    maxHeight = y3>(y1>y2?y1:y2)?y3:(y1>y2?y1:y2);
    maxHeight = maxHeight>0?maxHeight:0;
    DstWidth = maxWidth - minWidth;
    DstHeight = maxHeight - minHeight;
    dcDst = CreateCompatibleDC(dcSrc);
    newBitmap = CreateCompatibleBitmap(dcSrc,(int)DstWidth,(int)DstHeight);
    SelectObject(dcDst,newBitmap);
    for( int I = 0 ;I<DstHeight;I++)
    {
    for(int J = 0 ;J< DstWidth;J++)
    {
    srcX = (J + minWidth) * cosA + (I + minHeight) * sinA;
    srcY = (I + minHeight) * cosA - (J + minWidth) * sinA;
    if( (srcX >= 0) && (srcX <= SrcWidth) &&(srcY >= 0) && (srcY <= SrcHeight))
    {
    BitBlt(dcDst, J, I, 1, 1, dcSrc,(int)srcX, (int)srcY, SRCCOPY);
    }
    }
    } //显示旋转后的位图
    HDC pDC = ::GetDC(AfxGetMainWnd()->m_hWnd);
    //CDC*pDC=GetDC();   
    HDC hThisDC=CDC::FromHandle(pDC)->GetSafeHdc();  
    BitBlt(hThisDC,40,40,(int)DstWidth,(int)DstHeight,dcDst,0,0,SRCCOPY);
    return dcDst;
    DeleteObject(newBitmap);
    DeleteDC(dcDst);

    }
    angle= (45/180.0)*3.14159;//旋转45Degree,可为任意角度
    RhBkDC=RotateAnyAngle(hBkDC,640,384,angle);