0

この関数の目的は、openGLイメージからUIImageを返すことです。CG画像に変換される理由は、openGL要素とUIKit要素を重ねてレンダリングできるためです。これは別の関数で処理されます。

奇妙なことに、アプリをシミュレーターで実行すると、すべてが正常に機能します。ただし、複数の異なるiPadでアプリをテストした後、drawGlToImageメソッドが呼び出されるとself、アプリはEXC_BAD_ACCESS code=1エラーでクラッシュします。誰かが私がここで何をしているのか知っていますか?以前はスレッドセーフの問題があったことを読みましたUIGraphicsBeginImageContext()が、iOS4で修正されたようです。

    - (UIImage *)drawGlToImage
{
    self.context = [EAGLContext currentContext];
    [EAGLContext setCurrentContext:self.context];
    UIGraphicsBeginImageContext(self.view.frame.size);

    unsigned char buffer[1024 * 768 * 4];
    NSInteger dataSize = 1024 * 768 * 4;

    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(currentContext);

    glReadPixels(0, 0, 1024, 768, GL_RGBA, GL_UNSIGNED_BYTE, &buffer);

    //flip the image
    GLubyte *flippedBuffer = (GLubyte *) malloc(dataSize);

    for(int y = 0; y <768; y++)
    {
        for(int x = 0; x <1024 * 4; x++)
        {
            if(buffer[y* 4 * 1024 + x]==0)
                flippedBuffer[(767 - y) * 1024 * 4 + x]=1;
            else
                flippedBuffer[(767 - y) * 1024 * 4 + x] = buffer[y* 4 * 1024 + x];
        }
    }



    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, flippedBuffer, 1024 * 768 * 4, NULL);
    CGImageRef iref = CGImageCreate(1024,768,8,32,1024*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaLast, ref, NULL, true, kCGRenderingIntentDefault);

    CGContextScaleCTM(currentContext, 1.0, -1.0);
    CGContextTranslateCTM(currentContext, 0, -self.view.frame.size.height);

    UIGraphicsPopContext();
    UIImage *image = [[UIImage alloc] initWithCGImage:iref];
    UIGraphicsEndImageContext();

    return image;
    free(flippedBuffer);
    UIGraphicsPopContext();
}

ボタンが押されると、呼び出されるメソッドがこの割り当てを行い、アプリがクラッシュします。

UIImage *glImage = [self drawGlToImage];
4

2 に答える 2

0

I am not sure in which phase you are calling this method. But before calling any OpenGL functions you need to set the right OpenGL context. In the Xcode template it is this line

[EAGLContext setCurrentContext:self.context];
于 2012-07-03T21:02:28.023 に答える
0

これを解決するために使用されるコードは次のとおりです

- (UIImage *)drawGlToImage {

    // Code borrowed and tweaked from:
    // http://stackoverflow.com/questions/9881143/missing-part-of-the-image-when-taking-screenshot-while-supporting-retina-display

    CGFloat scale = UIScreen.mainScreen.scale;
    CGFloat xOffset = 40.0f;
    CGFloat yOffset = -16.0f;
    CGSize size = CGSizeMake((self.chart.frame.size.width) * scale,
                             self.chart.frame.size.height * scale);

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

    //Read Pixels from OpenGL
    glReadPixels(0.0f, 0.0f, size.width, size.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 * size.width;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef iref = CGImageCreate(size.width, size.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

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

    CGContextTranslateCTM(context, 0.0f, size.height);
    CGContextScaleCTM(context, 1.0f, -1.0f);

    // These numbers are a little magical.
    CGContextDrawImage(context, CGRectMake(xOffset, yOffset, ((size.width - (6.0f * scale)) / scale) - (xOffset / 2), (size.height / scale) - (yOffset / 2)), iref);
    UIImage *outputImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];

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

    return outputImage;
}
于 2012-07-24T20:26:09.223 に答える