wxWidgets 屏幕截图

本文介绍了如何利用wxWidgets库在Mac OS系统中获取屏幕截图的完整过程,包括初始化OpenGL上下文、抓取屏幕像素数据并最终转换为wxBitmap对象。该教程对于希望在Mac平台上实现屏幕截图功能的开发者具有实用价值。

wxScreenshotMaker.h#pragma once #include <wx/wx.h> #ifdef __WXMAC__ #include <OpenGL/OpenGL.h> #endif class wxScreenshotMaker { public: wxScreenshotMaker(); ~wxScreenshotMaker(); wxBitmap GetScreenshot(); private: #ifdef __WXMAC__ int screenWidth; int screenHeight; CGLContextObj glContextObj; int rowSize; unsigned char * glBitmapData; unsigned char * glRowData; void InitOpenGL(); void GrabGLScreen(); void SwizzleBitmap(); void FinalizeOpenGL(); #endif };

wxScreenshotMaker.cpp#include "wxScreenshotMaker.h" #ifndef __WXMAC__ #include <wx/dcscreen.h> #else #include <CoreFoundation/CoreFoundation.h> #include <ApplicationServices/ApplicationServices.h> #include <OpenGL/gl.h> #endif wxScreenshotMaker::wxScreenshotMaker() #ifdef __WXMAC__ : screenWidth(0), screenHeight(0), glBitmapData(NULL), glRowData(NULL) #endif { #ifdef __WXMAC__ wxSize size = wxGetDisplaySize(); screenWidth = size.GetWidth(); screenHeight = size.GetHeight(); InitOpenGL(); #endif } wxScreenshotMaker::~wxScreenshotMaker() { #ifdef __WXMAC__ FinalizeOpenGL(); #endif } wxBitmap wxScreenshotMaker::GetScreenshot() { #ifndef __WXMAC__ wxScreenDC screenDC; wxBitmap bmp(screenDC.GetSize().GetWidth(), screenDC.GetSize().GetHeight()); wxMemoryDC mdc(bmp); mdc.Blit(0, 0, bmp.GetWidth(), bmp.GetHeight(), &screenDC, 0, 0); mdc.SelectObject(wxNullBitmap); return bmp; #else if(glBitmapData) { GrabGLScreen(); wxImage img = wxImage(screenWidth, screenHeight, glBitmapData, true); return wxBitmap(img.Copy()); } #endif } #ifdef __WXMAC__ void wxScreenshotMaker::InitOpenGL() { do { rowSize = screenWidth * 3; rowSize = (rowSize + 2) & ~2; glRowData = (unsigned char *)realloc(glRowData, rowSize); glBitmapData = (unsigned char *)realloc(glBitmapData, rowSize * screenHeight); bzero(glRowData, rowSize); bzero(glBitmapData, rowSize * screenHeight); CGDirectDisplayID display = CGMainDisplayID(); CGLPixelFormatObj pixelFormatObj ; GLint numPixelFormats; CGLPixelFormatAttribute attribs[] = { kCGLPFAFullScreen, kCGLPFADisplayMask, (CGLPixelFormatAttribute)0, /* Display mask bit goes here */ (CGLPixelFormatAttribute)0 }; attribs[2] = (CGLPixelFormatAttribute) CGDisplayIDToOpenGLDisplayMask(display); /* Build a full-screen GL context */ CGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats ); if ( pixelFormatObj == NULL ) break; CGLCreateContext( pixelFormatObj, NULL, &glContextObj ) ; CGLDestroyPixelFormat( pixelFormatObj ) ; if ( glContextObj == NULL ) break; CGLSetCurrentContext( glContextObj ) ; CGLSetFullScreen( glContextObj ) ; } while(false); } void wxScreenshotMaker::FinalizeOpenGL() { CGLSetCurrentContext( NULL ); CGLClearDrawable( glContextObj ); CGLDestroyContext( glContextObj ); free(glRowData); free(glBitmapData); } void wxScreenshotMaker::GrabGLScreen() { glReadBuffer(GL_FRONT); /* Read framebuffer into our bitmap */ glFinish(); glPixelStorei(GL_PACK_ALIGNMENT, 3); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); /* * Fetch the data in RGB format, matching the bitmap context. */ glReadPixels((GLint)0, (GLint)0, (GLint)screenWidth, (GLint)screenHeight, GL_RGB, GL_BYTE, glBitmapData); SwizzleBitmap(); } void wxScreenshotMaker::SwizzleBitmap() { int top, bottom; top = 0; bottom = screenHeight - 1; void * base = glBitmapData; void * topP = NULL; void * bottomP = NULL; while(top < bottom) { topP = (void *)((top * rowSize) + (intptr_t)base); bottomP = (void *)((bottom * rowSize) + (intptr_t)base); bcopy( topP, glRowData, rowSize ); bcopy( bottomP, topP, rowSize ); bcopy( glRowData, bottomP, rowSize ); ++top; --bottom; } } #endif

来源:http://wxwidgets.info/taking-screenshots-with-wxwidgets-under-mac-os-is-really-tricky/

转载于:https://www.cnblogs.com/iapp/archive/2011/06/29/3631847.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值