0

我有一个基于图层的类,其中包含两个子精灵。让我们称它们为:背景和树。

在这个类中,我有一个方法来捕获该层的屏幕截图。该方法工作正常。每次我对该图层进行截图时,我都会获得背景上树的构成。美好的。在某一点上,我想获得没有树的那层的屏幕截图。所以我要做的是,隐藏树,截取屏幕截图并再次显示树......就像这样:

[myLayer hideTree];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];

令我惊讶的是,以这种方式生成的屏幕截图总是包含树。

这是 hideTree 和 showTree:

- (void) hideTree {
    [treeLayer setOpacity:0];
    // I have also tried [treelayer setVisible:NO];
}

- (void) showTree {
    [treeLayer setOpacity:255];
    // I have also tried [treelayer setVisible:YES];
}

我正在使用这种方法进行截图,来自 cocos2d 论坛:

-(UIImage*) screenshot
{
    CGSize displaySize  = [[CCDirector sharedDirector] winSize];
    CGSize winSize      = [self winSize];

    //Create buffer for pixels
    GLuint bufferLength = displaySize.width * displaySize.height * 4;
    GLubyte* buffer = (GLubyte*)malloc(bufferLength);

    //Read Pixels from OpenGL
    glReadPixels(0, 0, displaySize.width, displaySize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    //Make data provider with data.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);

    //Configure image
    int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = 4 * displaySize.width;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef iref = CGImageCreate(displaySize.width, displaySize.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    uint32_t* pixels = (uint32_t*)malloc(bufferLength);
    CGContextRef context = CGBitmapContextCreate(pixels, winSize.width, winSize.height, 8, winSize.width * 4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    CGContextTranslateCTM(context, 0, displaySize.height);
    CGContextScaleCTM(context, 1.0f, -1.0f);

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    switch (orientation)
    {
        case UIDeviceOrientationPortrait: break;
        case UIDeviceOrientationPortraitUpsideDown:
            CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(180));
            CGContextTranslateCTM(context, -displaySize.width, -displaySize.height);
            break;
        case UIDeviceOrientationLandscapeLeft:
            CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(-90));
            CGContextTranslateCTM(context, -displaySize.height, 0);
            break;
        case UIDeviceOrientationLandscapeRight:
            CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(90));
            CGContextTranslateCTM(context, displaySize.width * 0.5f, -displaySize.height);
            break;
        case UIDeviceOrientationUnknown:
            break;
        case UIDeviceOrientationFaceUp:
            break;
        case UIDeviceOrientationFaceDown:
            break;
    }

    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, displaySize.width, displaySize.height), iref);
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage *outputImage = [UIImage imageWithCGImage:imageRef];

    //Dealloc
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGImageRelease(iref);
    CGColorSpaceRelease(colorSpaceRef);
    CGContextRelease(context);
    free(buffer);
    free(pixels);

    return outputImage;
}

我错过了什么?为什么树总是出现?

4

2 回答 2

2

您的代码在游戏循环的更新过程中运行。

屏幕截图正在获取用于创建 UIImage 的当前像素。

当您告诉树不可见或不透明度为零时,直到下一个绘制周期才会生效。

要解决您的问题,您需要隐藏树,执行绘制循环,然后在下一次更新中捕获未显示树的帧。

说得通?

于 2012-08-02T00:31:08.313 回答
1

当您更改树的不透明度时,它只会在下次屏幕更新时生效。

一旦我遇到了这个问题,我就做了一些时间表。代替

[myLayer hideTree];
UIImage *screenshot = [myLayer screenshot];
[myLayer showTree];

[myLayer hideTree];
[self schedule:@selector(takeScreenshot)interval:0.05];

并将以下方法添加到您的场景中:

-(void)takeScreenshot {
    [self unschedule:@selector(takeScreenshot)];
    UIImage *screenshot = [myLayer screenshot];
    [myLayer showTree];
}

基本上,我们设置了 0.05 秒的间隔以允许屏幕更新。那应该行得通。

上面的方法对我有用,但我认为如果你[self visit]在隐藏树后调用它也可以。但我从未测试过。

于 2012-08-02T00:37:43.093 回答