我的屏幕是32位,能否用GDI或GDI+抓出256色或其它颜色的位图?

解决方案 »

  1.   

    得到数据再处理虽然是可行,但免不了有点烦人,对于16位位图更麻烦。
    不知GDI+有没有现在的格式转换功能?本人对GDI+不熟悉。
      

  2.   

        CString FileName;
        FileName = "d:\\4.bmp"; //输出文件    //截屏
        DWORD width = GetSystemMetrics(SM_CXSCREEN);  //获取屏幕宽度
        DWORD height = GetSystemMetrics(SM_CYSCREEN); //获取屏幕高度
        HDC screenDC = ::GetDC(NULL); //得到屏幕HDC
        HDC memoryDC = CreateCompatibleDC(screenDC); //开辟兼容内存区域
        HBITMAP bmp = CreateCompatibleBitmap(screenDC, width, height); //建立兼容的HBITMAP
        HBITMAP oldBmp = (HBITMAP)SelectObject(memoryDC, bmp); //选择对象
        BitBlt(memoryDC, 0, 0, width, height, screenDC, 0, 0, SRCCOPY); //将当前屏幕内容复制到兼容内存区域中,得到当前屏幕的GDI位图
        //bmp = (HBITMAP) SelectObject(memoryDC, oldBmp); //要想获取可显示的位图句柄,必须再次选择对象    //构造位图文件数据内存区
        DWORD dataSize = width*height;                //图象数据大小
        DWORD offBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 4*256; //文件头,信息头,颜色表
        DWORD fileSize = offBits + dataSize;
        PBYTE buffer = new BYTE[fileSize];  //buffer的大小 = 文件头 + 信息头 + 颜色表 + 数据
        PBITMAPFILEHEADER fileHdr = (PBITMAPFILEHEADER)buffer; //文件头指向buffer头部
        PBITMAPINFO bmpInfo = (PBITMAPINFO)(buffer + sizeof(BITMAPFILEHEADER)); //指到文件头尾部
        PBITMAPINFOHEADER infoHdr = &bmpInfo->bmiHeader; //信息头指向
        PVOID bits = buffer + offBits;  //数据区指向    //构造文件头、信息头
        fileHdr->bfOffBits = offBits;  //位图数据的起始位置,以相对于位图,前五项是BITMAPFILEHEADER
        fileHdr->bfReserved1 = 0;        //位图文件保留字,必须为0
        fileHdr->bfReserved2 = 0;        //位图文件保留字,必须为0
        fileHdr->bfSize = fileSize;    //位图文件的大小,以字节为单位
        fileHdr->bfType = 'BM';        //位图文件的类型,必须为BM()    infoHdr->biBitCount = 8;         //每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一
        infoHdr->biClrImportant = 0;     //位图显示过程中重要的颜色数,前11项是BITMAPINFOHEADER
        infoHdr->biClrUsed = 0;             //位图实际使用的颜色表中的颜色数
        infoHdr->biCompression = BI_RGB; //位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
        infoHdr->biHeight = height;         //位图的高度,以像素为单位
        infoHdr->biPlanes = 1;             //目标设备的级别,必须为1
        infoHdr->biSize = sizeof(BITMAPINFOHEADER); //本结构所占用字节数
        infoHdr->biSizeImage = dataSize; //位图的大小,以字节为单位 
        infoHdr->biWidth = width;         //位图的宽度,以像素为单位
        infoHdr->biXPelsPerMeter = 64;   //位图水平分辨率,每米像素数,0或者64都可以
        infoHdr->biYPelsPerMeter = 64;   //位图垂直分辨率,每米像素数,0或者64都可以    //按格式构造内存位图到数据区
        GetDIBits(memoryDC, bmp, 0, height, bits, bmpInfo, DIB_RGB_COLORS);
        SelectObject(memoryDC, oldBmp);
        DeleteDC(memoryDC);
      ::ReleaseDC(NULL, screenDC);//    //重新构造内存位图,获得句柄m_bmpCtrl.memDC.GetSafeHdc()
    //    HBITMAP hB = CreateDIBitmap(screenDC, &bmpInfo->bmiHeader, CBM_INIT, bits, bmpInfo, DIB_RGB_COLORS);
    //                                        //仅仅是为了获取句柄显示,直接用数据区bits,创建文件,则用整个文件buffer
    //    //显示位图buffer
    //    CRect rect;
    //    GetDlgItem(IDC_BTM_STATIC)->GetWindowRect(rect);
    //    ScreenToClient(rect);
    //    m_bmpCtrl.Create(WS_CHILD|WS_VISIBLE,rect,this);
    //    m_bmpCtrl.LoadHFile(hB);    HANDLE file = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file != INVALID_HANDLE_VALUE)
        {
            DWORD bytesWritten;
            WriteFile(file, buffer, fileSize, &bytesWritten, NULL); //创建文件,则用整个文件buffer
            CloseHandle(file);
        }
        else MessageBox("HANDLE file fail !");    delete buffer;这就是你要的256色了
      

  3.   

    万分感谢biweilun,我要的就是这个。