2012-08-31 4 views
0

AVCaptureSession을 사용하여 이미지를 가져 오려고합니다. 나는이 튜토리얼 http://www.benjaminloulier.com/posts/2-ios4-and-direct-access-to-the-camera을 따라 갔다. 나는 심상 ref에서 uiimage를 창조하고 그 uiimage에서 화소를 얻고있다. 하지만 언젠가 (30 초 미만) 후에 앱이 다운됩니다. 내가 누수를 사용하여 분석을 시도하고 그 너무 충돌합니다. 로그를 사용하여 CGContextDrawImage (context, rect, image1.CGImage) 라인 바로 전에 앱이 다운되는 것을 발견했습니다. 너희들은 내가 뭘 잘못하고 있는지에 대한 제안을하고 있니? 또한 응용 프로그램이 충돌하기 전에 몇 초 동안 메모리 할당 오류가 표시됩니다. 도와주세요. 코드는 아래 게시CGContextDrawImage 카메라 앱 충돌

..

// Create a UIImage from sample buffer data 

- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{ 
lock = @"YES"; 

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

// Lock the base address of the pixel buffer 
CVPixelBufferLockBaseAddress(imageBuffer, 0); 

// Get the number of bytes per row for the pixel buffer 
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

// Get the number of bytes per row for the pixel buffer 
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
// Get the pixel buffer width and height 
size_t width = CVPixelBufferGetWidth(imageBuffer); 
size_t height = CVPixelBufferGetHeight(imageBuffer); 

// Create a device-dependent RGB color space 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 


size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer); 

// Create a Quartz direct-access data provider that uses data we supply. 
NSData *data = [NSData dataWithBytes:baseAddress length:bufferSize]; 

CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 

CGImageRef quartzImage = CGImageCreate(width, height, 8, 32, bytesPerRow, 
       colorSpace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, 
       dataProvider, NULL, true, kCGRenderingIntentDefault); 

CGDataProviderRelease(dataProvider); 

// Unlock the pixel buffer 

CGColorSpaceRelease(colorSpace); 

// Create an image object from the Quartz image 
UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

// Release the Quartz image 
CGImageRelease(quartzImage); 

CVPixelBufferUnlockBaseAddress(imageBuffer,0); 
baseAddress = nil; 
[data release]; 
lock = @"NO"; 
return(image); 
} 

-(void)calculate 
{ 
@try { 

     UIImage *image1 = [self stillImage]; //Capture an image from the camera. 
     //Extract the pixels from the camera image. 

     CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 

     size_t bytesPerRow = image1.size.width*4; 
     unsigned char* bitmapData = (unsigned char*)malloc(bytesPerRow*image1.size.height); 

     CGContextRef context = CGBitmapContextCreate(bitmapData, image1.size.width, image1.size.height, 8, bytesPerRow,colourSpace,kCGImageAlphaPremultipliedFirst|kCGBitmapByteOrder32Big); 

     CGColorSpaceRelease(colourSpace); 

     CGContextDrawImage(context, rect, image1.CGImage); 

     unsigned char* pixels = (unsigned char*)CGBitmapContextGetData(context); 

     totalLuminance = 0.0; 
     for(int p=0; p<image1.size.width*image1.size.height*4; p+=4) 
     { 
      totalLuminance += pixels[p]*0.3 + pixels[p+1]*0.59 + pixels[p+2]*0.11; 
     } 

     totalLuminance /= (image1.size.height * image1.size.width);     

     pixels = nil; 

     bitmapData = nil; 

     [image1 release]; 

    CGContextRelease(context); 
     //image1 = nil; 

     //totalLuminance = [n floatValue];     //Calculate the total luminance. 
     float f = [del.camcont.slider value]; 
     float total = totalLuminance * f; 
     NSString *ns = [NSString stringWithFormat:@"Lux : %0.2f", total]; 
     NSLog(@"slider = %f",f); 
     NSLog(@"totlaluminance = %f",totalLuminance); 
     NSLog(@"%@",ns); 
     //NSString *ns = [NSString initWithFormat:@"Lux : %0.2f", total]; 
     [del.camcont.lux setText:ns];//Display the total luminance. 

     self.stillImage = nil; 
     //[self.stillImage release]; 
     ns = nil; 
     //n = nil; 
     //del = nil; 
    } 

    @catch (NSException *exception) { 
     NSLog(@"main: Caught %@: %@", [exception name], [exception reason]); 
} 
} 
+0

크래시의 세부 사항을 볼 수 있도록 기호화 된 오류 로그를 제공 할 수 있습니다. 이 문제에 대한 해결책을 찾았습니까? http://developer.apple.com/library/ios/#technotes/tn2151/_index.html – Bobjt

+0

@viks를 참조하십시오. 동일한 문제에 직면하고 있습니다. –

답변

0

메모리 관리는 언뜻 보면 좋아 보인다. 이 문제를 해결하기 위해 UIImage -imageWithData: 을 고려해 볼 수 있습니다. 사용자 정의 CGImageCreate 코드에 대한 문제가있는 경우를 대비하십시오. CGImage를 사용하여 어쨌든 UIImage를 생성했기 때문입니다.

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 그러나 imageWithData를 사용하여 작동하지 않습니다. 몇 초 후에 같은 줄에 계속 실패합니다. – viks

+0

시도해 볼 가치가있었습니다. 오류 로그를 게시 할 수 있습니까? 예를 들어,이 사건을 애플 DTS에 제출했다면, 그들이 묻는 첫 번째 것은 ... – Bobjt

+0

Xcode organizer.i에서 충돌 로그가 발견되지 않았습니다. 각 라인 다음에 NSLog를 추가하면 앱이 닫힐 때마다 충돌 로그가 없거나 콘솔에 오류 메시지가 표시되지 않는 경우가 있습니다. – viks

1

내가 왜 당신이 복용 후 CMSampleBufferRef을 복용 한 후 다음 CGImageRefUIImage를 만들고있어 불분명 해요 UIImageCGImageRef과 (데이터를 흡입 한 다음 unsigned char 포인터로 그 밀어하는 지점이 기본적으로 CMSampleBufferRef에 있던 것과 동일한 바이트). 당신이 뭔가를 할 경우

당신은 당신의 인생을 단순화하는 것이다 (당신은 디버그에 쉽게 찾을해야합니다) :

CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
CVPixelBufferLockBaseAddress(imageBuffer,0); 
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
size_t width = CVPixelBufferGetWidth(imageBuffer); 
size_t height = CVPixelBufferGetHeight(imageBuffer); 
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
uint8_t *pixels = malloc(bytesPerRow*height); 
memcpy(pixels, baseAddress, bytesPerRow*height); 
baseAddress = nil; 
imageBuffer = nil; 
sampleBuffer = nil; 
float totalLuminance = 0.0; 
for(int r=0; r<height; r++) 
{ 
    for(int p=0, p<width, p+=4) 
    { 
     totalLuminance += pixels[p+(r*bytesPerRow)]*0.3 
        + pixels[p+1+(r*bytesPerRow)]*0.59 
        + pixels[p+2+(r*bytesPerRow)]*0.11; 
    { 
} 
free(pixels); 
totalLuminance /= (width * height); 

(중첩 된 for 루프 bytesPerRow가로 가정 할 수 없다는 사실을 보상하기 위해입니다 패딩 때문에 width*4과 같아야합니다.)

+0

답변 해 주셔서 감사합니다. 사실입니다. 불필요하게 만든 복잡성을 알지 못했습니다. 다시 한 번 감사드립니다. 앱의 실적에 도움이 될 것입니다. 그런데, 평판이 좋지 않아서 대답을 포기할 수 없습니다. 죄송합니다 – viks