10

iPhone'da görüntü işleme manipülasyonu yapmaya çalışıyorum, Apple'ın GLImageProcessing örneğindeki şeyleri temel aldım.iPhone'da bir ekran üstü FBO'dan okuma yazma; simülatörde çalışır, fakat cihazda değil?

Sonuç olarak yapmak istediğim, bir görüntüyü bir dokuya yüklemek, örnek kodda (ton, doygunluk, parlaklık, vb.) Bir veya daha fazla işlemi gerçekleştirmek ve sonuçta ortaya çıkan görüntüyü okumaktır. Daha sonra işleme/kaydetme için. Çoğunlukla, bu ekrana asla dokunmak zorunda kalmayacaktı, bu yüzden FBO'ların gitmenin yolu olabileceğini düşündüm.

Başlangıç ​​olarak, bir ekran FBO'su oluşturan, ona çizen ve ardından verileri bir görüntü olarak geri okuyan küçük bir örneği birlikte ekledim. Bu, simülatörde mükemmel bir şekilde çalıştığında psyched oldum, daha sonra gerçek cihazda siyah bir ekranım olduğunu anladığım kadarıyla bummedim.

Sorumluluk reddi: OpenGL'm yeteri kadar eskidir ve OpenGL ES'ye giden bir öğrenme eğrisine sahip oldum ve hiçbir zaman doku büyücüsü olmadım. Cihazın simülatörden çerçevebacker erişimi (zorunlu off-screen FBO ve cihazdaki swap, simülatöre doğrudan erişim) açısından farklı özelliklere sahip olduğunu biliyorum, fakat yanlış yaptığım şeyi bulamadım. oldukça kapsamlı bir aramadan sonra bile.

Herhangi bir öneriniz var mı?

// set up the offscreen FBO sizes 

int renderBufferWidth = 1280; 
int renderBufferHeight = 720; 

// now the FBO 
GLuint fbo = 0; 
glGenFramebuffersOES(1, &fbo); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo); 

GLuint renderBuffer = 0; 
glGenRenderbuffersOES(1, &renderBuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderBuffer); 
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, 
         GL_RGBA8_OES, 
         renderBufferWidth, 
         renderBufferHeight); 

glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 
          GL_COLOR_ATTACHMENT0_OES, 
          GL_RENDERBUFFER_OES, 
          renderBuffer); 

GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 
if (status != GL_FRAMEBUFFER_COMPLETE_OES) { 
    NSLog(@"Problem with OpenGL framebuffer after specifying color render buffer: %x", status); 
} 

// throw in a test drawing 
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 


static const GLfloat triangleVertices[] = { 
    -0.5f, -0.33f, 
    0.5f, -0.33f, 
    -0.5f, 0.33f 
}; 

static const GLfloat triangleColors[] = { 
    1.0, 0.0, 0.0, 0.5, 
    0.0, 1.0, 0.0, 0.5, 
    0.0, 0.0, 1.0, 0.5 
}; 

GLint backingWidth = 320; 
GLint backingHeight = 480; 

NSLog(@"setting up view/model matrices"); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 


glVertexPointer(2, GL_FLOAT, 0, triangleVertices); 
glEnableClientState(GL_VERTEX_ARRAY); 
glColorPointer(4, GL_FLOAT, 0, triangleColors); 
glEnableClientState(GL_COLOR_ARRAY); 



// draw the triangle 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); 


// Extract the resulting rendering as an image 
int samplesPerPixel = 4; // R, G, B and A 
int rowBytes = samplesPerPixel * renderBufferWidth; 
char* bufferData = (char*)malloc(rowBytes * renderBufferHeight); 
if (bufferData == NULL) { 
    NSLog(@"Unable to allocate buffer for image extraction."); 
} 

// works on simulator with GL_BGRA, but not on device 
glReadPixels(0, 0, renderBufferWidth, 
      renderBufferHeight, 
      GL_BGRA, 
      GL_UNSIGNED_BYTE, bufferData); 
NSLog(@"reading pixels from framebuffer"); 

// Flip it vertically - images read from OpenGL buffers are upside-down 
char* flippedBuffer = (char*)malloc(rowBytes * renderBufferHeight); 
if (flippedBuffer == NULL) { 
    NSLog(@"Unable to allocate flipped buffer for corrected image."); 
} 

for (int i = 0 ; i < renderBufferHeight ; i++) { 
    bcopy(bufferData + i * rowBytes, 
      flippedBuffer + (renderBufferHeight - i - 1) * rowBytes, 
      rowBytes); 
} 

// unbind my FBO 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

// Output the image to a file 


CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
int bitsPerComponent = 8; 

CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; 
CGContextRef contextRef = CGBitmapContextCreate(flippedBuffer, 
               renderBufferWidth, 
               renderBufferHeight, 
               bitsPerComponent, 
               rowBytes, colorSpace, bitmapInfo); 
if (contextRef == nil) { 
    NSLog(@"Unable to create CGContextRef."); 
} 

CGImageRef imageRef = CGBitmapContextCreateImage(contextRef); 

if (imageRef == nil) { 
    NSLog(@"Unable to create CGImageRef."); 
} else { 
    if (savedImage == NO) { 
     UIImage *myImage = [UIImage imageWithCGImage:imageRef]; 
     UIImageWriteToSavedPhotosAlbum(myImage, nil, nil, nil); 
     savedImage = YES; 
    } 
} 

Düzenleme: tabii ki, bitmap formatı GL_BGRA GL_RGBA değil olması gerektiği

cevap oldu:

// works on simulator with GL_BGRA, but not on device 
glReadPixels(0, 0, renderBufferWidth, 
     renderBufferHeight, 
     **GL_RGBA**, 
     GL_UNSIGNED_BYTE, bufferData); 
+0

Bu konuda herhangi bir ilerleme kaydettiniz mi? Benzer bir şey yapmak istiyorum: http://stackoverflow.com/questions/4412587/how-can-i-access-the-raw-pixel-data-of-an-opengl-es-2-off-screen- render-buffer – akaru

+0

Andrew, düzenlemeniz değişikliklerin sorununuzu çözdüğü anlamına mı geliyor? Eğer öyleyse, bunu bir cevap olarak eklemelisiniz ve kabul etmelisiniz. Ama beni en çok ilgilendiren: GLImageProcessing tabanlı görüntü işleme kütüphanesini bitirdin mi? – Palimondo

cevap

4

Andrew kendini cevap gibi:

cevap, bitmap formatının GL_BGRA

// works on simulator with GL_BGRA, but not on device 
glReadPixels(0, 0, renderBufferWidth, 
          renderBufferHeight, 
          GL_RGBA, // <-- 
          GL_UNSIGNED_BYTE, bufferData); 
değil olması gerektiği
İlgili konular