2012-03-25 94 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]; 
相關問題