如何截取屏幕截图并将其保存为Windows上的JPEG?
发布时间:2020-12-13 20:01:34 所属栏目:Windows 来源:网络整理
导读:我试图找到一个(有点)简单的方法来在窗口上截图,并将得到的HBITMAP保存为JPEG.这里的棘手部分是,由于代码是C,我不能使用GDI,因为代码是一个更大的程序的模块,我不能使用外部lib(如libjpeg). 此代码需要截图并返回HBITMAP.将该位图保存到文件中很容易.问题是
我试图找到一个(有点)简单的方法来在窗口上截图,并将得到的HBITMAP保存为JPEG.这里的棘手部分是,由于代码是C,我不能使用GDI,因为代码是一个更大的程序的模块,我不能使用外部lib(如libjpeg).
此代码需要截图并返回HBITMAP.将该位图保存到文件中很容易.问题是位图是2或3mb. HDC hDCMem = CreateCompatibleDC(NULL); HBITMAP hBmp; RECT rect; HDC hDC; HGDIOBJ hOld; GetWindowRect(hWnd,& rect); hBmp = NULL; { hDC = GetDC(hWnd); hBmp = CreateCompatibleBitmap(hDC,rect.right - rect.left,rect.bottom - rect.top); ReleaseDC(hWnd,hDC); } hOld = SelectObject(hDCMem,hBmp); SendMessage(hWnd,WM_PRINT,(WPARAM) hDCMem,PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED); SelectObject(hDCMem,hOld); DeleteObject(hDCMem); return hBmp; 任何想法如何做到这一点? 编辑: #include <windows.h> #include <stdio.h> #include <gdiplus.h> using namespace Gdiplus; int GetEncoderClsid(WCHAR *format,CLSID *pClsid) { unsigned int num = 0,size = 0; GetImageEncodersSize(&num,&size); if(size == 0) return -1; ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size)); if(pImageCodecInfo == NULL) return -1; GetImageEncoders(num,size,pImageCodecInfo); for(unsigned int j = 0; j < num; ++j) { if(wcscmp(pImageCodecInfo[j].MimeType,format) == 0){ *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; } } free(pImageCodecInfo); return -1; } int GetScreeny(LPWSTR lpszFilename,ULONG uQuality) // by Napalm { ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL); HWND hMyWnd = GetForegroundWindow(); // get my own window RECT r; // the area we are going to capture int w,h; // the width and height of the area HDC dc; // the container for the area int nBPP; HDC hdcCapture; LPBYTE lpCapture; int nCapture; int iRes; CLSID imageCLSID; Bitmap *pScreenShot; HGLOBAL hMem; int result; // get the area of my application's window //GetClientRect(hMyWnd,&r); GetWindowRect(hMyWnd,&r); dc = GetWindowDC(hMyWnd);// GetDC(hMyWnd) ; w = r.right - r.left; h = r.bottom - r.top; nBPP = GetDeviceCaps(dc,BITSPIXEL); hdcCapture = CreateCompatibleDC(dc); // create the buffer for the screenshot BITMAPINFO bmiCapture = { sizeof(BITMAPINFOHEADER),w,-h,1,nBPP,BI_RGB,}; // create a container and take the screenshot HBITMAP hbmCapture = CreateDIBSection(dc,&bmiCapture,DIB_PAL_COLORS,(LPVOID *)&lpCapture,NULL,0); // failed to take it if(!hbmCapture) { DeleteDC(hdcCapture); DeleteDC(dc); GdiplusShutdown(gdiplusToken); printf("failed to take the screenshot. err: %dn",GetLastError()); return 0; } // copy the screenshot buffer nCapture = SaveDC(hdcCapture); SelectObject(hdcCapture,hbmCapture); BitBlt(hdcCapture,h,dc,SRCCOPY); RestoreDC(hdcCapture,nCapture); DeleteDC(hdcCapture); DeleteDC(dc); // save the buffer to a file pScreenShot = new Bitmap(hbmCapture,(HPALETTE)NULL); EncoderParameters encoderParams; encoderParams.Count = 1; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Guid = EncoderQuality; encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong; encoderParams.Parameter[0].Value = &uQuality; GetEncoderClsid(L"image/jpeg",&imageCLSID); iRes = (pScreenShot->Save(lpszFilename,&imageCLSID,&encoderParams) == Ok); delete pScreenShot; DeleteObject(hbmCapture); GdiplusShutdown(gdiplusToken); return iRes; }
好的,经过这么多的努力,这里的答案是:
int SaveJpeg(HBITMAP hBmp,LPCWSTR lpszFilename,ULONG uQuality) { ULONG *pBitmap = NULL; CLSID imageCLSID; EncoderParameters encoderParams; int iRes = 0; typedef Status (WINAPI *pGdipCreateBitmapFromHBITMAP)(HBITMAP,HPALETTE,ULONG**); pGdipCreateBitmapFromHBITMAP lGdipCreateBitmapFromHBITMAP; typedef Status (WINAPI *pGdipSaveImageToFile)(ULONG *,const WCHAR*,const CLSID*,const EncoderParameters*); pGdipSaveImageToFile lGdipSaveImageToFile; // load GdipCreateBitmapFromHBITMAP lGdipCreateBitmapFromHBITMAP = (pGdipCreateBitmapFromHBITMAP)GetProcAddress(hModuleThread,"GdipCreateBitmapFromHBITMAP"); if(lGdipCreateBitmapFromHBITMAP == NULL) { // error return 0; } // load GdipSaveImageToFile lGdipSaveImageToFile = (pGdipSaveImageToFile)GetProcAddress(hModuleThread,"GdipSaveImageToFile"); if(lGdipSaveImageToFile == NULL) { // error return 0; } lGdipCreateBitmapFromHBITMAP(hBmp,&pBitmap); iRes = GetEncoderClsid(L"image/jpeg",&imageCLSID); if(iRes == -1) { // error return 0; } encoderParams.Count = 1; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Guid = EncoderQuality; encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong; encoderParams.Parameter[0].Value = &uQuality; lGdipSaveImageToFile(pBitmap,lpszFilename,&encoderParams); return 1; } >什么是hModuleThread?看看在here.你可以用GetModuleHandle() 现在的问题是,如何将编码的pBitmap(作为jpeg)保存到BYTE缓冲区? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 客户端证书Windows Phone 8.1
- 在Windows 7上编辑IDLE(Python GUI)上下文菜单
- .net – System.Drawing(GDI)vs System.Windows.Media(WPF)
- 获取异常 – “属性值大于表服务允许的值”,天蓝存储表中的
- 错误:软件包“Microsoft SQL Management Studio软件包”加
- Windows中的Mercurial没有看到.hgignore – 为什么?
- windows-server-2003 – RSAT性能下降
- windows – “作为服务登录”实际上意味着什么?
- operating-system – Windows内核模式驱动程序如何访问分页
- 如何获取角色中的所有用户(Microsoft ASP.NET Identity Ent
推荐文章
站长推荐
- windows-server-2003 – 设置域环境中的“官方实
- iis – 在端口80上的Windows Server 2012上运行G
- Windows命令“date%s”的等价物是什么
- skype – 您的团队在远程设置中如何协同工作?
- 2018-2019-2 20165235《网络对抗技术》Exp2 后门
- 为什么我需要SharpSvn-DB44-20-win32和SharpSvn-
- 批量脚本,Powershell,而不是在Windows中触发UAC
- batch-file – 在IF语句WinXP Batch Script中使用
- 域名系统 – 需要Windows Server 2008 R2域控制器
- xaml – DataTriggerBehavior不适用于Enum?
热点阅读