Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从1bpp位图读取像素(CreateDIBSection)_C++_Winapi - Fatal编程技术网

C++ 从1bpp位图读取像素(CreateDIBSection)

C++ 从1bpp位图读取像素(CreateDIBSection),c++,winapi,C++,Winapi,此代码适用于32、24、16、8、4 bpp图像。但不是1个基点 #include <stdio.h> #include <windows.h> #pragma comment(lib, "user32.lib") #pragma comment(lib, "gdi32.lib") void GetWindowBitmapBitsAndSave(const HWND& hWnd, int nBitCount, char *szFilePath); void E

此代码适用于32、24、16、8、4 bpp图像。但不是1个基点

#include <stdio.h>
#include <windows.h>

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")

void GetWindowBitmapBitsAndSave(const HWND& hWnd, int nBitCount, char *szFilePath);
void EnumerateBits(LPBYTE pBits, int nBitCount, int nWidth, int nHeight);

int main(int argc, char **argv)
{   
    //GetWindowBitmapBits(HWND_DESKTOP, 32);
    //32, 24, 16, 8, 4 works fine...
    GetWindowBitmapBitsAndSave(HWND_DESKTOP, 1, "test.bmp");

    return 0;
}

void EnumerateBits(LPBYTE pBits, int nBitCount, int nWidth, int nHeight)
{
    int nPixels = nWidth * nHeight; 
    WORD wByteCount = nBitCount / 8; 
    if(wByteCount == 0)
        wByteCount = 1;
    int nBytes = nPixels * wByteCount; 

    for(int i = 0; i < nBytes; i += wByteCount) 
    { 
        int r = (int)(*(pBits+i));
        //int g = (int)(*(pBits+i+1));
        //int b = (int)(*(pBits+i+2));

        //just for test
        if(r != 0 /*&& g != 0 && b != 0*/)
            if(r != 255 /*&& g != 255 && b != 255*/)
            //printf("(%d, %d, %d)\n", r, g, b);
                    printf("%d\n", r);
    } 
}

void GetWindowBitmapBitsAndSave(const HWND& hWnd, int nBitCount, char* szFilePath)
{
    HWND hScreenWnd = hWnd;
    if(!hScreenWnd)
        hScreenWnd = HWND_DESKTOP;

    //calculate the number of color indexes in the color table
    int nColorTableEntries = -1;
    switch(nBitCount) 
    {
        case 1:
            nColorTableEntries = 2;
            break;
        case 4:
            nColorTableEntries = 16;
            break;
        case 8:
            nColorTableEntries = 256;
            break;
        case 16:
        case 24:
        case 32:
            nColorTableEntries = 0;
            break;
        default:
            nColorTableEntries = -1;
            break;
    }

    if(nColorTableEntries == -1)
    {
        printf("bad bits-per-pixel argument\n");
        return;
    }

    HDC hDC = GetDC(hScreenWnd);
    HDC hMemDC = CreateCompatibleDC(hDC);

    int nWidth = 0;
    int nHeight = 0;

    if(hScreenWnd != HWND_DESKTOP)
    {
        RECT rect;
        GetClientRect(hScreenWnd, &rect);
        nWidth = rect.right - rect.left;
        nHeight = rect.bottom - rect.top;
    }
    else
    {
        nWidth = ::GetSystemMetrics(SM_CXSCREEN);
        nHeight = ::GetSystemMetrics(SM_CYSCREEN);
    }


    HBITMAP hBMP = CreateCompatibleBitmap(hDC, nWidth, nHeight);
    SelectObject(hMemDC, hBMP);
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, 0, 0, SRCCOPY);

    int nStructLength = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;
    BITMAPINFOHEADER BitmapInfoHeader;

    BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    BitmapInfoHeader.biWidth = nWidth;
    BitmapInfoHeader.biHeight = nHeight;
    BitmapInfoHeader.biPlanes = 1;
    BitmapInfoHeader.biBitCount = nBitCount;
    BitmapInfoHeader.biCompression = BI_RGB;
    BitmapInfoHeader.biXPelsPerMeter = 0;
    BitmapInfoHeader.biYPelsPerMeter = 0;
    BitmapInfoHeader.biClrUsed = nColorTableEntries;
    BitmapInfoHeader.biClrImportant = nColorTableEntries;

    DWORD dwBytes = ((DWORD) nWidth * nBitCount) / 32;
    if(((DWORD) nWidth * nBitCount) % 32) {
        dwBytes++;
    }
    dwBytes *= 4;

    DWORD dwSizeImage = dwBytes * nHeight;
    BitmapInfoHeader.biSizeImage = dwSizeImage;

    BITMAPINFO* bitmapInfo = new BITMAPINFO[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * nColorTableEntries];
    bitmapInfo->bmiHeader = BitmapInfoHeader;

    if(nBitCount < 16)
    {
        for(int i = 0; i != nColorTableEntries; ++i)
        {
            bitmapInfo->bmiColors[i].rgbRed = 
                bitmapInfo->bmiColors[i].rgbGreen =
                bitmapInfo->bmiColors[i].rgbBlue = (BYTE)(i*(255/(nColorTableEntries-1)));
            bitmapInfo->bmiColors[i].rgbReserved = 0;
        }
    }

    LPBYTE lpDibBits = 0;
    HBITMAP hBitmap = ::CreateDIBSection(hMemDC, bitmapInfo, DIB_RGB_COLORS, (void**)&lpDibBits, NULL, 0);
    SelectObject(hMemDC, hBitmap);
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, 0, 0, SRCCOPY);
    ReleaseDC(hScreenWnd, hDC);

    //save bitmap
    BITMAPFILEHEADER bmfh;
    bmfh.bfType = 0x4d42;  // 'BM'
    int nHeaderSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;
    bmfh.bfSize = 0;
    bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries;    

    FILE *pFile = 0;
    fopen_s(&pFile, szFilePath, "wb");
    if(pFile)
    {
        fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, pFile);
        fwrite(bitmapInfo, nHeaderSize,1,pFile);
        fwrite(lpDibBits, dwSizeImage, 1, pFile);
        fclose(pFile);
    }

    EnumerateBits(lpDibBits, nBitCount, nWidth, nHeight);

    delete[]bitmapInfo;
    ::DeleteObject(hBMP);
    ::DeleteObject(hBitmap);
}
#包括
#包括
#pragma注释(lib,“user32.lib”)
#pragma注释(lib,“gdi32.lib”)
void GetWindowBitmapBitsAndSave(常量HWND&HWND,int-nBitCount,char*szFilePath);
无效枚举位(LPBYTE-pBits、int-nBitCount、int-nWidth、int-nHeight);
int main(int argc,字符**argv)
{   
//GetWindowBitmapBits(HWND_桌面,32);
//32,24,16,8,4行得很好。。。
GetWindowBitmapBitsAndSave(HWND_桌面,1,“test.bmp”);
返回0;
}
无效枚举位(LPBYTE pBits、int-nBitCount、int-nWidth、int-nHeight)
{
int nPixels=nWidth*nHeight;
字wByteCount=nBitCount/8;
如果(wByteCount==0)
wByteCount=1;
int nBytes=nPixels*wByteCount;
对于(int i=0;ibmiHeader=bitmapInfo标头;
如果(nBitCount<16)
{
for(int i=0;i!=nColorTableEntries;++i)
{
bitmapInfo->bmiColors[i]。RGR=
bitmapInfo->bmiColors[i].rgbGreen=
bitmapInfo->bmiColors[i].rgbBlue=(字节)(i*(255/(nColorTableEntries-1));
bitmapInfo->bmiColors[i].rgbReserved=0;
}
}
LPBYTE lpDibBits=0;
HBITMAP HBITMAP=::CreateDIBSection(hMemDC,bitmapInfo,DIB_RGB_颜色,(void**)和lpDibBits,NULL,0);
选择对象(hMemDC、hBitmap);
BitBlt(hMemDC,0,0,nWidth,nHeight,hDC,0,0,SRCCOPY);
释放DC(hScreenWnd,hDC);
//保存位图
位图文件头bmfh;
bmfh.bfType=0x4d42;//“BM”
int nHeaderSize=sizeof(bitmapinfo头)+sizeof(RGBQUAD)*nColorTableEntries;
bmfh.bfSize=0;
bmfh.bfReserved1=bmfh.bfReserved2=0;
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BitMapInfo Header)+sizeof(RGBQUAD)*nColorTableEntries;
文件*pFile=0;
fopen_s(&pFile,szFilePath,“wb”);
if(pFile)
{
fwrite(&bmfh,sizeof(BITMAPFILEHEADER),1,pFile);
fwrite(bitmapInfo,nHeaderSize,1,pFile);
fwrite(lpbits,dwsizemage,1,pFile);
fclose(pFile);
}
枚举位(lpDibBits、nBitCount、nWidth、nHeight);
删除[]位图信息;
::删除对象(hBMP);
::删除对象(hBitmap);
}
第一个问题:为什么当比特数为1时,除了黑色和白色之外还有其他颜色?(但图像是单色的。只需在GetWindowBitmapBitsAndSave函数中调用注释枚举位即可)


第二个问题:如何正确计算颜色位数组的偏移量?

我认为不是
nBitCount>>3
而是
nBitCount/8
。每像素一位意味着每像素一位。每像素读取三个字节。您需要读取一个字节并将其拆分为8个像素。我正在编辑代码(nBitCount>>3=>nBitCount/8)。但是我的问题没有解决。关于:“第一个问题:为什么当比特数为1时,除了黑白之外还有其他颜色?”比特深度小于16,并且启用了比特压缩的16,使用相关的颜色数组(即位图的调色板)确定它们的颜色,其中比特值是该数组的索引。数组中可以有任何颜色。因此,没有什么需要1bpp位图只使用黑白色。雷米·勒博感谢您的回答。现在我明白为什么会这样了。P