Windows应用-屏幕截图
下载本应用
本应用获取屏幕图像,保存到bmp,jpg,png图片。下面是应用的界面图像。
应用的主要代码
C屏幕截图Dlg* pDlg = (C屏幕截图Dlg*)pParam;//CRect rect;截图矩形,已指定大小CWnd* pDesktop = pDlg->GetDesktopWindow();CDC* pDesktopDC = pDesktop->GetDC();CDC mDC;mDC.CreateCompatibleDC(pDesktopDC);//创建兼容DCCBitmap bmp;bmp.CreateBitmap(rect.Width(), rect.Height(), 1, 32, NULL);//创建32位位图mDC.SelectObject(&bmp);mDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDesktopDC, rect.left, rect.top, SRCCOPY);LONG len = rect.Width() * rect.Height() * 4;BYTE* lpData = (BYTE*)(LPVOID)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, len);//分配内存bmp.GetBitmapBits(len, lpData);//获取位图位mDC.DeleteDC();pDlg->ReleaseDC(pDesktopDC);pDlg->AutoBmp(lpData, rect.Width(), rect.Height());//创建bmp//pDlg->GBmp256(lpData, rect.Width(), rect.Height());//创建灰度bmp//pDlg->Jpg(lpData, rect.Width(), rect.Height());//创建jpg//pDlg->Png(lpData, rect.Width(), rect.Height());//创建pngGlobalFree(lpData);int AddTable(CArray<RGBQUAD, RGBQUAD>* pColorTable, RGBQUAD color)
{int Count = pColorTable->GetCount();for (int i = 0; i < Count; i++){RGBQUAD TableColor = pColorTable->GetAt(i);if (TableColor.rgbBlue == color.rgbBlue && TableColor.rgbGreen == color.rgbGreen && TableColor.rgbRed == color.rgbRed)return i;}pColorTable->Add(color);return Count;
}void C屏幕截图Dlg::AutoBmp(BYTE* pB, int w, int h)//首先尝试创建256色位图,如果颜色数量大于256,创建24位位图
{int ColorCount;int len;int Width = w;if (Width % 4)Width = Width / 4 * 4 + 4;//确保行的宽度是4的倍数len = Width * h;CArray<RGBQUAD, RGBQUAD> ColorTable;BYTE* p256B = new BYTE[len];BYTE* pS = NULL; BYTE* pD = NULL;for (int y = 0; y < h; y++){pS = pB + w * 4 * y;pD = p256B + Width * (h - y - 1);for (int x = 0; x < w; x++){RGBQUAD color = { pS[0], pS[1], pS[2],pS[3] };*pD = (BYTE)AddTable(&ColorTable, color);pS += 4; pD++;ColorCount = ColorTable.GetCount();if (ColorCount > 256){delete[] p256B;Bmp24(pB, w, h);//创建24位位图return;}}}BITMAPFILEHEADER Fhdr;//位图文件头Fhdr.bfType = ((WORD)('M' << 8) | 'B');Fhdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * 4 + len;//整个文件的大小Fhdr.bfReserved1 = 0;Fhdr.bfReserved2 = 0;Fhdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * 4;//从文件开头到图像数据的偏移量BITMAPINFOHEADER biHeader;//位图信息头ZeroMemory(&biHeader, sizeof(BITMAPINFOHEADER));biHeader.biSize = sizeof(BITMAPINFOHEADER);biHeader.biWidth = w;biHeader.biHeight = h;biHeader.biPlanes = 1;biHeader.biBitCount = 8;biHeader.biCompression = BI_RGB;biHeader.biSizeImage = len;biHeader.biClrUsed = 256;CFile F;F.Open(_T("截图.bmp"), CFile::modeCreate | CFile::modeWrite);F.Write(&Fhdr, sizeof(Fhdr));//写位图文件头F.Write(&biHeader, sizeof(biHeader));//写位图信息for (int i = 0; i < 256; i++)//写颜色表{RGBQUAD color;if (i < ColorCount){color = ColorTable.GetAt(i);}else{color.rgbBlue = 0; color.rgbGreen = 0; color.rgbRed = 0; color.rgbReserved = 0;}F.Write(&color, 4);}F.Write(p256B, len);//写图像数据F.Close();delete[] p256B;
}void C屏幕截图Dlg::GBmp256(BYTE* pB, int w, int h)//创建灰度位图
{int len;int Width = w;if (Width % 4)Width = Width / 4 * 4 + 4;//确保行的宽度是4的倍数len = Width * h;BYTE* p256B = new BYTE[len];BYTE* pS = NULL; BYTE* pD = NULL;for (int y = 0; y < h; y++){pS = pB + w * 4 * y;pD = p256B + Width * (h - y - 1);for (int x = 0; x < w; x++){*pD = (BYTE)(0.299 * pS[2] + 0.587 * pS[1] + 0.114 * pS[0]); //亮度值pS += 4; pD++;}}BITMAPFILEHEADER Fhdr;//位图文件头Fhdr.bfType = ((WORD)('M' << 8) | 'B');Fhdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256*4 + len;//整个文件的大小Fhdr.bfReserved1 = 0;Fhdr.bfReserved2 = 0;Fhdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256*4;//从文件开头到图像数据的偏移量BITMAPINFOHEADER biHeader;//位图信息头ZeroMemory(&biHeader, sizeof(BITMAPINFOHEADER));biHeader.biSize = sizeof(BITMAPINFOHEADER);biHeader.biWidth = w;biHeader.biHeight = h;biHeader.biPlanes = 1;biHeader.biBitCount = 8;biHeader.biCompression = BI_RGB;biHeader.biSizeImage = len;biHeader.biClrUsed = 256;CFile F;F.Open(_T("截图.bmp"), CFile::modeCreate | CFile::modeWrite);F.Write(&Fhdr, sizeof(Fhdr));//写位图文件头F.Write(&biHeader, sizeof(biHeader));//写位图信息BYTE zero = 0, val;for (int i = 0; i < 256; i++)//写颜色表{val = (BYTE)i;F.Write(&val, 1); F.Write(&val, 1); F.Write(&val, 1); F.Write(&zero, 1);}F.Write(p256B, len);//写图像数据F.Close();delete[] p256B;
}void C屏幕截图Dlg::Bmp24(BYTE* pB, int w, int h)//创建24位位图
{int bmWidthBytes = w * 3;if (bmWidthBytes % 4)bmWidthBytes = bmWidthBytes / 4 * 4 + 4;//确保行的宽度是4的倍数int len = bmWidthBytes * h;BYTE* p24B = new BYTE[len];int i = 0;for (int y = 0; y < h; y++){int j = bmWidthBytes * (h - y - 1);for (int x = 0; x < w; x++){p24B[j] = pB[i]; p24B[j + 1] = pB[i + 1]; p24B[j + 2] = pB[i + 2]; i += 4; j += 3;}}BITMAPFILEHEADER Fhdr;//位图文件头Fhdr.bfType = ((WORD)('M' << 8) | 'B');Fhdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + len;//整个文件的大小Fhdr.bfReserved1 = 0;Fhdr.bfReserved2 = 0;Fhdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//从文件开头到图像数据的偏移量BITMAPINFOHEADER biHeader;//位图信息头ZeroMemory(&biHeader, sizeof(BITMAPINFOHEADER));biHeader.biSize = sizeof(BITMAPINFOHEADER);biHeader.biWidth = w;biHeader.biHeight = h;biHeader.biPlanes = 1;biHeader.biBitCount = 24;biHeader.biCompression = BI_RGB;CFile F;F.Open(_T("截图.bmp"), CFile::modeCreate | CFile::modeWrite);F.Write(&Fhdr, sizeof(Fhdr));//写位图文件头F.Write(&biHeader, sizeof(biHeader));//写位图信息F.Write(p24B, len);//写图像数据F.Close();delete[] p24B;
}void C屏幕截图Dlg::Jpg(BYTE* pB, int w, int h)
{CBitmap bmp;bmp.CreateBitmap(w, h, 1, 32, pB);CImage image;image.Attach((HBITMAP)bmp);image.Save(L"截图.jpg", Gdiplus::ImageFormatJPEG);
}void C屏幕截图Dlg::Png(BYTE* pB, int w, int h)
{CBitmap bmp;bmp.CreateBitmap(w, h, 1, 32, pB);CImage image;image.Attach((HBITMAP)bmp);image.Save(L"截图.png", Gdiplus::ImageFormatPNG);
}
下载本应用