簡體   English   中英

獲取openGL圖像-在模擬器中運行,在iPad上崩潰

[英]Getting an openGL image - runs in simulator, crashes on iPad

此函數的目的是從openGL圖像返回UIImage。 之所以將其轉換為CG圖像,是因為openGL和UIKit元素可以相互呈現,這在另一個函數中可以解決。

奇怪的是,當應用程序在模擬器中運行時,一切正常。 然而,測試在多個不同的iPad該應用中,當后drawGlToImage方法被調用self ,應用程序崩潰與EXC_BAD_ACCESS碼= 1個錯誤。 有人知道我在這里做什么會導致這種情況嗎? 我讀過UIGraphicsBeginImageContext()曾經有線程安全問題,但似乎在iOS 4中已解決。

    - (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];

我不確定您在哪個階段調用此方法。 但是在調用任何OpenGL函數之前,您需要設置正確的OpenGL上下文。 在Xcode模板中是這一行

[EAGLContext setCurrentContext:self.context];

這是用於解決它的代碼

- (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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM