首页
学习
活动
专区
圈层
工具
发布

截图
EN

Stack Overflow用户
提问于 2013-09-04 15:39:00
回答 3查看 243关注 0票数 0

拍截图有问题。一切都很好,但我在第1366x768号决议中有个问题。位图坏了,我无法打开这个文件。

代码语言:javascript
复制
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()的内容更改为:

代码语言:javascript
复制
void Zrzut::Szer_Wys()
{
    RECT re;
    GetWindowRect( okno, & re );
    w = re.right, h = re.bottom;

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

现在一切都很好:)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-04 16:02:49

位图中每一行的字节数必须是4的倍数。

代码语言:javascript
复制
(3*1366)/4=1024,5 not a multiple of 4

您必须逐行保存它,并在每一行中填充两个字节。请记住,这将更改biSizeImage和bfSize成员,但不会更改图像的宽度和高度。如果你每像素使用32位,你可以避免这个问题。

票数 0
EN

Stack Overflow用户

发布于 2013-09-04 15:51:51

试一试:-

  1. 使用MSPaint (或其他什么)并创建一个1366x768映像。
  2. 使图像变成纯红色
  3. 保存为BMP
  4. 修改代码,用红色填充位图,而不是复制屏幕。
  5. 运行您的代码
  6. 比较这两个文件,一个由MSPaint创建,另一个由您的代码创建
票数 0
EN

Stack Overflow用户

发布于 2013-09-04 16:22:43

您错过了扫描线 aligned (填充到下一个32位对齐边界)的事实。

扫描线是DWORD对齐的,除了RLE压缩位图.除了RLE压缩位图外,对于不能被4整除的扫描线宽度(以字节为单位),必须填充它们。例如,一个10×10像素的24-bpp位图将在每一行的末尾有两个填充字节.

所以,每条扫描线都是((w * 3) + 3) & ~3字节,然后乘以h得到图像大小。如果没有这个填充,图像就会被破坏。

您还可以利用Windows、amvideo.h提供的宏(它们还可以再次解释格式):

代码语言:javascript
复制
// 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,并无缘无故地将不同的值放置在那里。例如,您在那里放置了零个平面,而平面的数量必须设置为1

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18618163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档