Как получить прозрачное изображение из контекста OpenGL ES на iPhone - PullRequest
3 голосов
/ 28 июля 2010

У меня проблема с OpenGL ES на iPhone.

Я работаю над проектом, он рисует что-то на виде, а затем сохраняет изображение. У этого также есть фоновое изображение. Я объединил изображение, полученное из вида, и фоновое изображение.

Я установил непрозрачное свойство представления как НЕТ, но изображение, полученное из вида, все еще непрозрачно. Поэтому я не мог объединить два изображения вместе. Я мог видеть только переднее изображение, фоновое изображение нигде не было видно.

CAEAGLLayer *EAGLLayer = (CAEAGLLayer *)self.layer;
        EAGLLayer.opaque = NO;

Получить код изображения так:

- (UIImage *)GetImage
{
    CGFloat Width = self.frame.size.width;
    CGFloat Height = self.frame.size.height;
    GLubyte *TmpBuffer = (GLubyte *)malloc(Width * Height * 4);
    glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, TmpBuffer);
    GLubyte *Buffer = (GLubyte *)malloc(Width * Height * 4);

    for(int y=0; y<Height; y++) {
        for(int x=0; x<Width * 4; x++) {
            Buffer[((NSInteger)Height - 1 - y) * (NSInteger)Width * 4 + x] = TmpBuffer[y * 4 * (NSInteger)Width + x];
        }
    }
    CGDataProviderRef Provider = CGDataProviderCreateWithData(NULL, Buffer, Width * Height * 4, NULL);

    int BitsPerComponent = 8;
    int BitsPerPixel = 32;
    int BytesPerRow = 4 * 480;
    CGColorSpaceRef ColorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo BitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent RenderingIntent = kCGRenderingIntentDefault;

    // Make the cgimage.
    CGImageRef ImageRef = CGImageCreate(480, 320, 
                                        BitsPerComponent, 
                                        BitsPerPixel, 
                                        BytesPerRow, 
                                        ColorSpaceRef, 
                                        BitmapInfo, 
                                        Provider, 
                                        NULL, NO, 
                                        RenderingIntent);

    return [UIImage imageWithCGImage:ImageRef];
}

Объедините код следующим образом:

- (void)Combine:(UIImage *)Back
{
    UIGraphicsBeginImageContext(self.frame.size);

    CGContextRef aContext = UIGraphicsGetCurrentContext();

    CGContextSaveGState(aContext);

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

    UIImage *Front = [self GetImage];

    CGContextDrawImage(aContext, 
                       CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), 
                       Back.CGImage);

    CGContextDrawImage(aContext, 
                       CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), 
                       Front.CGImage);

    CGContextRestoreGState(aContext);

    UIImageWriteToSavedPhotosAlbum(UIGraphicsGetImageFromCurrentImageContext(), nil, nil, nil);

    UIGraphicsEndImageContext();
}

Что мне делать? Любое предложение будет приятно. заранее спасибо.

Ответы [ 2 ]

1 голос
/ 25 января 2012

Я сделал именно это.

Я использовал следующие свойства CAEAGLLayer:

eaglLayer.opaque = NO;      
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

и в вашем - (UIImage *) GetImage метод скорее использует:

CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;

при необходимости ваш метод Combine: можно настроить для сохранения двух объединенных изображений в UIImage, используя:

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

надеюсь, что этопомогает:)

0 голосов
/ 28 июля 2010

Как вы создаете свой буфер OpenGL? В частности, в вашем EAGLView, когда или вы устанавливаете свойство класса drawableProperties вашего CAEAGLLayer, оно должно выглядеть примерно так:

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

Если вы используете kEAGLColorFormatRGB565 вместо kEAGLColorFormatRGBA8, ваш кадровый буфер не будет хранить альфа-значение, поэтому он всегда будет непрозрачным.

Если вы еще не устанавливали это свойство, попробуйте установить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...