Вопрос по ios5, ios4, ios, iphone-privateapi – Создание изображения из поверхности ios и сохранение его

0



Я пытаюсь получить поверхность, связанную с основным экраном устройства ios, создать из нее изображение и сохранить его. Это относится к этому вопросу -Делаем скриншоты из iOS-приложения - эмулируем дисплей диспетчера (запрос на внутренности).

Код выглядит следующим образом:

    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);



Но все, что я получаю, это пустое изображение, сохраненное в папке с моими фотографиями. Пожалуйста, помогите, в какой части я иду не так. Благодарю.

Ваш Ответ

2   ответа
2

что видел что-то на эту тему (снимки экрана на заднем плане) некоторое время назад. Я не былЯ не могу найти точное место и код, который я видел. Единственной запиской, которую я оставил для себя, было использование createScreenIOSurface

Я немного погуглил и нашел пару упоминаний:

Получить скриншот, пока приложение в фоновом режиме? (Частные API разрешены)

https://github.com/rpetrich/FastBlurredNotificationCenter/blob/master/Tweak.x

http://pastie.org/pastes/3734430

Насколько я помню, код был намного более компактным, чем вы показали.

Я не уверен. Я никогда не пробовал Victor Ronin
createScreenIOSurface действительно работает. Благодарю. Hrishikesh_Pardeshi
Спасибо за ссылки. Итак, у меня работает указанный код, он делает скриншот самой верхней поверхности. Тем не менее, я должен поставить сон на 2 секунды, чтобы он продолжал работать без приостановки. Код, который вы упомянули, компактен. Но улучшит ли это производительность? Hrishikesh_Pardeshi
1

если вы запускаете его в фоновом режиме. Он делает снимок самой верхней поверхности дисплея устройства iOS.

Проблема возникла из-за того, что внутри приложения был сделан скриншот пустого представления, созданного для приложения.

Однако вы должны делать снимки экрана с минимальными интервалами в 2 секунды, в противном случае ОС приостанавливает ваше приложение. Любые предложения о том, как улучшить это, будут полезны.

Привет, Hrishikesh_Pardeshi, ты нашел способ улучшить код, чтобы делать скриншоты с интервалами < 2 сек ям борется в течение нескольких дней в этом вопросе Dhekra Zaied

Похожие вопросы