0

スクリーンショットを撮るのに問題があります。すべて問題ありませんが、解像度 1366x768 で問題があります。ビットマップが壊れていて、このファイルを開くことができません。

HDC _dc = GetWindowDC(okno); 
Szer_Wys(); //ustawia szerokosc i wysokosc aktywnego ekranu

dc = CreateCompatibleDC( 0 );
bm = CreateCompatibleBitmap( _dc, w, h );
SelectObject( dc, bm );
StretchBlt( dc, 0, 0, w, h, _dc, 0, 0, w, h, SRCCOPY );

GetObject( bm, 84, buf );
ddd = GetDC( 0 );
dc2 = CreateCompatibleDC( ddd );

tagBITMAPINFO bit_info; //tworzy obiekt na strukture 
bit_info.bmiHeader.biSize = sizeof( bit_info.bmiHeader );  //Rozmiar struktury bmiHeader (40 )
bit_info.bmiHeader.biWidth = w; //Szerokość bitmapy w pikselac
bit_info.bmiHeader.biHeight = h;  //wysokosc bitmapy w pikselac
bit_info.bmiHeader.biPlanes = 1;  
bit_info.bmiHeader.biBitCount = 24; //Liczba bitów kodujących piksel (RGB)
bit_info.bmiHeader.biCompression = 0; //0 - brak wewnętrznej kompresji
bit_info.bmiHeader.biSizeImage = 0; 

h_createDIB = CreateDIBSection( dc, & bit_info, DIB_RGB_COLORS, & buf, 0, 0 );                
GetDIBits( dc, bm, 0, h, buf, & bit_info, DIB_RGB_COLORS );


BITMAPFILEHEADER bit_header;
bit_header.bfType = MAKEWORD( 'B', 'M' ); //typ pliku
bit_header.bfSize = w * h * 3 + 54; //w * h * 3 kolory + nagłówek 
bit_header.bfOffBits = 54;

BITMAPINFOHEADER bit_info_header;
bit_info_header.biSize = 40;
bit_info_header.biWidth = w;
bit_info_header.biHeight = h;
bit_info_header.biPlanes = 0;
bit_info_header.biBitCount = 24;
bit_info_header.biCompression = 0;
bit_info_header.biSizeImage = w * h * 3;


sciezka = obiekt.PobierzPathSCREEN() +  obiekt.PobierzNazwe() + ".bmp";        
ofstream plik(sciezka, ios::binary);
if(plik.good())
{
        plik.write(reinterpret_cast<char*>(&bit_header), sizeof(bit_header));
        plik.write(reinterpret_cast<char*>(&bit_info_header), sizeof(bit_info_header));
        plik.write(reinterpret_cast<char*>(buf), w*h*3 );

}else cout<<"Blad pliku";

plik.close();

*Szer_Wys()* は画面解像度を読み取っています。

編集

Szer_Wys() の内容を次のように変更しました。

void Zrzut::Szer_Wys()
{
    RECT re;
    GetWindowRect( okno, & re );
    w = re.right, h = re.bottom;

    while(w%4 != 0)
    {
            w++;
    }
}

そして今、すべてが正常に動作します:)

4

3 に答える 3

0

スキャンラインを整列する必要がDWORDあるという事実を見逃しています(次の 32 ビット境界にパディングされます)。

スキャン ラインは、RLE 圧縮ビットマップを除き、DWORD に揃えられます。RLE 圧縮ビットマップを除き、4 で割り切れないスキャン ライン幅 (バイト単位) をパディングする必要があります。たとえば、10 x 10 ピクセルの 24 bpp ビットマップには、各スキャン ラインの最後に 2 つのパディング バイトがあります。

したがって、各スキャンラインは((w * 3) + 3) & ~3バイトになり、これを掛けてh画像サイズを取得します。このパディングがないと、画像が壊れます。

Windows SDK で提供されているマクロを利用することもできますamvideo.h(また、フォーマットについてももう一度説明します)。

// DIBSIZE calculates the number of bytes required by an image

#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8)
#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount)
#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight)
#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi))

これに加えて、ファイルに書き込むときに、もう一度構造bit_info_headerを初期化し、理由もなくそこに異なる値を入れます。たとえば、平面の数を に設定する必要があるのに、平面を 0 に設定し1ます。

于 2013-09-04T16:22:43.837 に答える
0

Bitmap の 1 行あたりのバイト数は 4 の倍数である必要があります。あなたの場合は

(3*1366)/4=1024,5 not a multiple of 4

各行に 2 バイトずつパディングして、行ごとに保存する必要があります。これにより、biSizeImage および bfSize メンバーが変更されますが、イメージの幅と高さは変更されないことに注意してください。1 ピクセルあたり 32 ビットを使用すると、この問題を回避できます。

于 2013-09-04T16:02:49.660 に答える