2012-03-25 49 views
2

嗨我正在尝试绘制应用程序,并有一个问题,当涉及到保存所绘制的图像。现在我很早就学习了这一点,但我添加了以下代码: How to get UIImage from EAGLView?保存绘制的图像。保存imageRef从GLPaint创建完全黑色的图像

我创建了一个新的应用程序,然后显示了我创建的viewController。在IB中,我添加了一个是PaintingView的视图,并且imageView位于它后面。

到目前为止,我对绘画视图所做的唯一修改是更改背景清除并设置背景清除,以便我可以在其后显示图像。绘图效果很好,我唯一的问题就是保存。

- (void)saveImageFromGLView:(UIView *)glView { 

    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
     { 
      /// This IS being activated with code 0 
      NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); 
    } 


    int s = 1; 
    UIScreen* screen = [ UIScreen mainScreen ]; 
    if ([ screen respondsToSelector:@selector(scale) ]) 
     s = (int) [ screen scale ]; 

    const int w = self.frame.size.width; 
    const int h = self.frame.size.height; 
    const NSInteger myDataLength = w * h * 4 * s * s; 
    // allocate array and read pixels into it. 
    GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
    glReadPixels(0, 0, w*s, h*s, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 
    // gl renders "upside down" so swap top to bottom into new array. 
    // there's gotta be a better way, but this works. 
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); 
    for(int y = 0; y < h*s; y++) 
    { 
     memcpy(buffer2 + (h*s - 1 - y) * w * 4 * s, buffer + (y * 4 * w * s), w * 4 * s); 
    } 
    free(buffer); // work with the flipped buffer, so get rid of the original one. 

    // make data provider with data. 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); 
    // prep the ingredients 
    int bitsPerComponent = 8; 
    int bitsPerPixel = 32; 
    int bytesPerRow = 4 * w * s; 
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 
    // make the cgimage 
    CGImageRef imageRef = CGImageCreate(w*s, h*s, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 
    // then make the uiimage from that 
    UIImage *myImage = [ UIImage imageWithCGImage:imageRef scale:s orientation:UIImageOrientationUp ]; 
    UIImageWriteToSavedPhotosAlbum(myImage, nil, nil, nil); 
    CGImageRelease(imageRef); 
    CGDataProviderRelease(provider); 
    CGColorSpaceRelease(colorSpaceRef); 
    free(buffer2);  

} 

将上面的代码添加到示例应用程序工作正常,问题是在我的新应用程序中。唯一的区别是我可以告诉我没有包含PaintingWindow - 那会是问题吗?

就好像saveImage方法没有看到图纸的数据。

+0

的方法似乎罚款,如果您还没有改变,从原来的代码什么(我想一定是布拉德·拉尔森的Cuz HES总是以这个东西的工作),我能想到的唯一的事情是,你在呼唤这个当帧缓冲区已被清除。你打电话来清除帧缓冲区?你是否尝试过这种方法,而不是设置背景清晰以及它是否工作? – Pochi 2012-03-27 04:51:37

+0

好主意 - 我没有试过,但可悲的是没有改变。只是一个坚实的黑色PNG。缓冲区被删除的唯一地方是一个名为destroyFrameBuffer的方法。这是只有一次,当视图第一次加载时调用。我认为这听起来像缓冲区已被清除。是否有一个很好的方法来NSLog缓冲区的内容/内容大小告诉? – Brodie 2012-03-27 05:06:59

+0

实际上 - 我只是在saveImage方法的顶部添加了一条NSLOG语句,它看起来像缓冲区有问题 - 我更新了这个问题以反映这个 – Brodie 2012-03-27 05:09:19

回答

4

保存方法应该在OpenGL上下文的范围内调用。 要解决这个问题,您可以在同一个渲染.m文件中移动您的方法,并从外部调用此函数。

另外你需要考虑OpenGL的清晰颜色。

(在评论详细说明,洛尔)

+0

再次感谢 - 总结这个问题的任何人,我从主绘图viewController中调用save方法,而不是渲染层本身。当我改变这个时,它仍然没有工作,因为我已经改变了openGL背景颜色清晰,在OpenGL中是黑色的。 – Brodie 2012-03-27 05:59:54

1

我发现,改变CGBitmapInfo成:

CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast; 

结果透明背景。

0

啊,你必须在开始时这样做。

[EAGLContext setCurrentContext:drawContext]; 
相关问题