我使用GetDIBits()
检索位图的位并将它们复制到缓冲区中。函数不会失败(结果与NULL不同),但是我得到错误的位图高度和错误的缓冲区。
这是我的代码的一部分:
HDC hdcMemDC = CreateCompatibleDC(hDC); // (hDC = hDC = BeginPaint(hwnd, &ps): i get it in WM_Paint)
int l_uiWidth = 400;
int l_uiHeight = 120;
HBITMAP hbmp = CreateCompatibleBitmap(hDC, l_uiWidth, l_uiHeight);
HGDIOBJ oldhbmp = SelectObject(hdcMemDC,hbmp);
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = l_uiWidth;
bi.bmiHeader.biHeight = l_uiHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 8;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 256;
bi.bmiHeader.biClrImportant = 0;
BYTE *l_ImagePDM = new BYTE[l_uiWidth * l_uiHeight];
GetDIBits(hdcMemDC,hbmp,0,l_uiHeight,l_Image,&bi,DIB_RGB_COLORS);
请帮帮我! 我的代码出了什么问题?
答案 0 :(得分:0)
您在查询位的位图上没有绘制任何内容。 CreateCompatibleBitmap()
不会复制源HDC
的像素。它仅分配与指定HBITMAP
兼容的HDC
,然后您可以选择HBITMAP
到HDC
。但是你仍然必须在位图上绘制一些内容,以使其内容有意义,然后再查询其位。
答案 1 :(得分:0)
使用C ++ Builder时,可以使用Graphics
单位处理图形。
从窗口复制内容的示例:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Create a bitmap
Graphics::TBitmap* bit = new Graphics::TBitmap();
bit->PixelFormat = pf24bit;
bit->HandleType = bmDIB;
bit->Width = 200;
bit->Height = 200; // or bit->SetSize(200, 200) - newer versions C++ Builder
// Copy something from this Form (from window)
bit->Canvas->CopyRect(TRect(0, 0, 200, 200), this->Canvas, TRect(0, 0, 200, 200));
// Do something with bitmap data
RGBTRIPLE* line;
for (int i = 0; i < bit->Height; i++)
{
// Get memory address from line i
line = (RGBTRIPLE*) bit->ScanLine[i];
// Change 5'th pixel
line[5].rgbtRed = 255;
}
// Get whole bitmap memory. Bitmap data are stored upside down and size of each row is rounded
// up to a multiple of 4 bytes.
unsigned char* bitmem = (unsigned char*)(bit->ScanLine[ bit->Height-1 ]);
//...
// Draw bitmap on Form
Canvas->Draw(0, 200, bit);
delete bit;
}
当你有设备上下文时,你可以像这样使用TCanvas:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
// Create device context
HDC hdc = GetDC(this->Handle); // or GetWindowDC - whole window with frame
// Create canvas and associate device context
TCanvas* canv = new TCanvas();
canv->Handle = hdc;
// Create a bitmap
Graphics::TBitmap* bit = new Graphics::TBitmap();
bit->PixelFormat = pf24bit;
bit->HandleType = bmDIB;
bit->Width = this->ClientWidth;
bit->Height = this->ClientHeight; // or bit->SetSize(w, h) - newer versions C++ Builder
// Copy window content
TRect r(0, 0, this->ClientWidth, this->ClientHeight);
bit->Canvas->CopyRect(r, canv, r); // USEING TCanvas
// Release context and delete canvas
ReleaseDC(this->Handle, hdc);
delete canv;
// Do something with the bitmap
bit->SaveToFile("screenshot.bmp");
delete bit;
}
您还可以将TCanvas用于BeginPaint的设备上下文:
canv->Handle = BeginPaint(hwnd, &ps);