glReadPixels crashes on specific render buffer widths
I need to read content of CAEAGLLayer, which has various widths and heights (based on background image size). on iPad emulator everything is okay, but on device I have crashes or weird horizontal lines instead of content. Crashes not happens on width, for example, from 537 to 544 pixels
I'm using following code
- (UIImage*)image
{
// Get the size of the backing CAEAGLLayer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
// Read pixel data from the framebuffer
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
// Create a CGImage with the pixel data
// If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel
// otherwise, use kCGImageAlphaPremultipliedLast
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
ref, NULL, true, kCGRenderingIntentDefault);
// OpenGL ES measures data in PIXELS
// Create a graphics context with the target size measured in POINTS
NSInteger widthInPoints, heightInPoints;
// if (NULL != UIGraphicsBeginImageContextWithOptions) {
// // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// // Set the scale parameter to your OpenGL ES view's contentScaleFactor
// // so that you get a high-resolution snapshot when its value is greater than 1.0
// CGFloat scale = eaglview.contentScaleFactor;
// widthInPoints = width / scale;
// heightInPoints = height / scale;
// UIGraphicsBeginImageContextWithOptions(CGSizeMake( widthInPoints, heightInPoints), NO, scale);
// }
// else {
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
widthInPoints = width;
heightInPoints = height;
UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
// }
CGContextRef cgcontext = UIGraphicsGetCurrentContext();
// UIKit coordinate system is upside down to GL/Quartz coordinate system
// Flip the CGImage by rendering it to the flipped bitmap context
// The size of the destination area is measured in POINTS
CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
CGContextDrawImage(cgcontext, CGR开发者_开发问答ectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);
// Retrieve the UIImage from the current context
UIImage *image1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Clean up
free(data);
CFRelease(ref);
CFRelease(colorspace);
CGImageRelease(iref);
return image1;
}
The view you are reading from, or your drawable area, must be a multiple of 32 (possibly 16, but I haven't tested this yet). Maybe you can try resizing your draw area to a multiple of 32? I had the horizontal line issue previously and resizing the section I was reading from 400x300 to 384x288 fixed everything.
In my case works any width multiplied by 4!
精彩评论