繁体   English   中英

如何从iPhone上的OpenGL ES上下文获取透明图像

[英]How to get transparent image from OpenGL ES context on iPhone

我在iPhone上遇到了OpenGL ES的问题。

我正在研究一个项目,它在视图上绘制一些东西,然后保存图像。 它还有一个背景图片。 我结合了视图和背景图像的图像。

我将视图的opaque属性设置为NO,但是从视图中获取的图像仍然是不透明的。 所以我无法将两个图像组合在一起。 我只能看到前面的图像,背景图像无处可寻。

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

我该怎么办? 任何建议都会很高兴。 提前致谢。

我做到了这一点。

我使用了以下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();

希望这可以帮助 :)

你是如何创建OpenGL缓冲区的? 具体来说,在您的EAGLView中,当您或您设置CAEAGLLayer的drawableProperties类属性时,它应该类似于:

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

如果使用kEAGLColorFormatRGB565而不是kEAGLColorFormatRGBA8,则帧缓冲区将不会存储alpha值,因此它始终是不透明的。

如果您尚未设置此属性,请尝试进行设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM