从ios表面创建图像并保存 [英] Creating an image out of the ios surface and saving it
问题描述
我正在尝试获取与ios设备主屏幕关联的表面,从中创建图像并保存。这与此问题相关 - 从iOS应用程序中截取屏幕截图 - 模拟显示记录器(内部查询)。
代码如下:
I am trying to acquire the surface associated with the main screen of the ios device, create an image out of it and save it. This is in relevance to this question - Taking Screenshots from iOS app - emulating Display recorder (query on the internals).
The code is as follows:
IOMobileFramebufferConnection connect;
kern_return_t result;
io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleH1CLCD"));
if(!framebufferService)
framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD"));
if(!framebufferService)
framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD"));
result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);
result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &screenSurface);
uint32_t aseed;
IOSurfaceLock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
uint32_t width = IOSurfaceGetWidth(screenSurface);
uint32_t height = IOSurfaceGetHeight(screenSurface);
CFMutableDictionaryRef dict;
int pitch = width*4, size = 4*width*height;
int bPE=4;
char pixelFormat[4] = {'A','R','G','B'};
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(dict, kIOSurfaceIsGlobal, kCFBooleanTrue);
CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bPE));
CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat));
CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));
IOSurfaceRef destSurf = IOSurfaceCreate(dict);
IOSurfaceAcceleratorRef outAcc;
IOSurfaceAcceleratorCreate(NULL, 0, &outAcc);
CFDictionaryRef ed = (__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: nil];
IOSurfaceAcceleratorTransferSurface(outAcc, screenSurface, destSurf, ed, NULL);
IOSurfaceUnlock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, IOSurfaceGetBaseAddress(destSurf), (width*height*4), NULL);
CGImageRef cgImage=CGImageCreate(width, height, 8, 8*4, IOSurfaceGetBytesPerRow(destSurf), CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, provider, NULL, YES, kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage: cgImage];
CGImageRelease(cgImage);
UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
但我得到的是我的照片文件夹中保存的空白图像。请帮助我出错的部分。
谢谢。
But all I get is a blank image saved in my photos folder. Please help on what part am I going wrong.
Thanks.
推荐答案
我记得前段时间我在这个主题上看过一些内容(在后台截图)。我找不到我看到的确切地点和代码。我留给自己的唯一注意事项是使用createScreenIOSurface
I remember I saw something on this subject (taking screenshots in the background) some time ago. I wasn't able find exact place and code which I saw. The only note which I left for myself was usage of createScreenIOSurface
我用Google搜索了一下,发现了几个提及:
I googled a little bit and found couple of mentions:
https://github.com/rpetrich/FastBlurredNotificationCenter/blob/master/Tweak.x
http://pastie.org/pastes/3734430
因为我记住代码比你展示的更紧凑。
As I remember the code was way more compact then what you showed.
这篇关于从ios表面创建图像并保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!