![](/img/trans.png)
[英]App with UITableView runs on iPad simulator but crashes on the iPhone simulator
[英]Getting an openGL image - runs in simulator, crashes on iPad
此函數的目的是從openGL圖像返回UIImage。 之所以將其轉換為CG圖像,是因為openGL和UIKit元素可以相互呈現,這在另一個函數中可以解決。
奇怪的是,當應用程序在模擬器中運行時,一切正常。 然而,測試在多個不同的iPad該應用中,當后drawGlToImage
方法被調用self
,應用程序崩潰與EXC_BAD_ACCESS碼= 1個錯誤。 有人知道我在這里做什么會導致這種情況嗎? 我讀過UIGraphicsBeginImageContext()
曾經有線程安全問題,但似乎在iOS 4中已解決。
- (UIImage *)drawGlToImage
{
self.context = [EAGLContext currentContext];
[EAGLContext setCurrentContext:self.context];
UIGraphicsBeginImageContext(self.view.frame.size);
unsigned char buffer[1024 * 768 * 4];
NSInteger dataSize = 1024 * 768 * 4;
CGContextRef currentContext = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(currentContext);
glReadPixels(0, 0, 1024, 768, GL_RGBA, GL_UNSIGNED_BYTE, &buffer);
//flip the image
GLubyte *flippedBuffer = (GLubyte *) malloc(dataSize);
for(int y = 0; y <768; y++)
{
for(int x = 0; x <1024 * 4; x++)
{
if(buffer[y* 4 * 1024 + x]==0)
flippedBuffer[(767 - y) * 1024 * 4 + x]=1;
else
flippedBuffer[(767 - y) * 1024 * 4 + x] = buffer[y* 4 * 1024 + x];
}
}
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, flippedBuffer, 1024 * 768 * 4, NULL);
CGImageRef iref = CGImageCreate(1024,768,8,32,1024*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaLast, ref, NULL, true, kCGRenderingIntentDefault);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGContextTranslateCTM(currentContext, 0, -self.view.frame.size.height);
UIGraphicsPopContext();
UIImage *image = [[UIImage alloc] initWithCGImage:iref];
UIGraphicsEndImageContext();
return image;
free(flippedBuffer);
UIGraphicsPopContext();
}
當按下按鈕時,將調用一個方法進行分配,這將導致應用程序崩潰。
UIImage *glImage = [self drawGlToImage];
我不確定您在哪個階段調用此方法。 但是在調用任何OpenGL函數之前,您需要設置正確的OpenGL上下文。 在Xcode模板中是這一行
[EAGLContext setCurrentContext:self.context];
這是用於解決它的代碼
- (UIImage *)drawGlToImage {
// Code borrowed and tweaked from:
// http://stackoverflow.com/questions/9881143/missing-part-of-the-image-when-taking-screenshot-while-supporting-retina-display
CGFloat scale = UIScreen.mainScreen.scale;
CGFloat xOffset = 40.0f;
CGFloat yOffset = -16.0f;
CGSize size = CGSizeMake((self.chart.frame.size.width) * scale,
self.chart.frame.size.height * scale);
//Create buffer for pixels
GLuint bufferLength = size.width * size.height * 4;
GLubyte* buffer = (GLubyte*)malloc(bufferLength);
//Read Pixels from OpenGL
glReadPixels(0.0f, 0.0f, size.width, size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//Make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);
//Configure image
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * size.width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(size.width, size.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
CGContextRef context = CGBitmapContextCreate(pixels, size.width, size.height, 8, size.width * 4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0.0f, size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
// These numbers are a little magical.
CGContextDrawImage(context, CGRectMake(xOffset, yOffset, ((size.width - (6.0f * scale)) / scale) - (xOffset / 2), (size.height / scale) - (yOffset / 2)), iref);
UIImage *outputImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
//Dealloc
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGContextRelease(context);
free(buffer);
free(pixels);
return outputImage;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.