2012-09-07 47 views
0

我有一個方法將添加到圖像的過濾器。這工作得很好,直到幾個月前,現在當我嘗試使用這種方法時,應用程序將在圖像緩衝區中崩潰。我創建緩衝區並將其設置爲圖像的數據,稍後訪問特定索引會導致訪問崩潰。我已經找了過去的一兩個小時,現在我確信有一些可以忽略的東西。我認爲有些事情不應該被釋放。我正在使用xcode的ios DP 4預覽版,我認爲這個問題是從測試版的更新開始的,但我真的不確定。UInt8 EXC_BAD_ACCESS

這是它崩潰上靠近第一中間 for循環

m_PixelBuf[index+2] = m_PixelBuf[index+2]/*aRed*/; 

通常它被設置爲ARED我已經檢查了線路,它不應該走出去的緩衝邊界。

-(void)contrastWithContrast:(float)contrast colorWithColor:(float)color{ 
    drawImage.image = original; 
    UIImage * unfilteredImage2 = [[[UIImage alloc]initWithCGImage:drawImage.image.CGImage] autorelease]; 
    CGImageRef inImage = unfilteredImage2.CGImage;   
    CGContextRef ctx; 
    CFDataRef m_DataRef; 
    m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 
    UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef); 
    int length = CFDataGetLength(m_DataRef); 
    NSLog(@"Photo Length: %i",length); 
    //////Contrast///////////// 
    //NSLog(@"Contrast:%f",contrast); 
    int aRed; 
    int aGreen; 
    int aBlue; 
    for (int index = 0; index < length; index += 4){ 
    aRed = m_PixelBuf[index+2]; 
    aGreen = m_PixelBuf[index+1]; 
    aBlue = m_PixelBuf[index]; 

    aRed = (((aRed-128)*(contrast+100))/100) + 128; 
    if (aRed < 0) aRed = 0; if (aRed>255) aRed=255; 
    m_PixelBuf[index+2] = m_PixelBuf[index+2]/*aRed*/;//Always crashes here 

    aGreen = (((aGreen-128)*(contrast+100))/100) + 128; 
    if (aGreen < 0) aGreen = 0; if (aGreen>255) aGreen=255; 
    m_PixelBuf[index+1] = aGreen; 

    aBlue = (((aBlue-128)*(contrast+100))/100) + 128; 
    if (aBlue < 0) aBlue = 0; if (aBlue>255) aBlue=255; 
    m_PixelBuf[index] = aBlue; 
} 
ctx = CGBitmapContextCreate(m_PixelBuf, 
          CGImageGetWidth(inImage), 
          CGImageGetHeight(inImage), 
          CGImageGetBitsPerComponent(inImage), 
          CGImageGetBytesPerRow(inImage), 
          CGImageGetColorSpace(inImage), 
          CGImageGetBitmapInfo(inImage)); 
CGImageRef imageRef = CGBitmapContextCreateImage (ctx); 
UIImage* rawImage = [[UIImage alloc]initWithCGImage:imageRef]; 
drawImage.image = rawImage; 

[rawImage release]; 
CGContextRelease(ctx); 
CFRelease(imageRef); 
CFRelease(m_DataRef); 

unfilteredImage2 = [[[UIImage alloc]initWithCGImage:drawImage.image.CGImage] autorelease]; 
inImage = unfilteredImage2.CGImage;   
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 
m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef); 
length = CFDataGetLength(m_DataRef); 

///////Color////////////////  
for (int index = 0; index < length; index += 4) 
{ 
    //Blue 
    if((m_PixelBuf[index] + ((int)color * 2))>255){ 
     m_PixelBuf[index] = 255; 
    }else if((m_PixelBuf[index] + ((int)color * 2))<0){ 
     m_PixelBuf[index] = 0; 
    } 
    else{ 
     m_PixelBuf[index]=m_PixelBuf[index] + ((int)color * 2); 
    } 

    //Green 
    if((m_PixelBuf[index+1] + ((int)color * 2))>255){ 
     m_PixelBuf[index+1] = 255; 
    }else if((m_PixelBuf[index+1] + ((int)color * 2))<0){ 
     m_PixelBuf[index+1] = 0;    
    } 
    else{ 
     m_PixelBuf[index+1]=m_PixelBuf[index+1] + ((int)color * 2); 
    } 

    //Red 
    if((m_PixelBuf[index+2] + ((int)color * 2))>255){ 
     m_PixelBuf[index+2] = 255; 
    }else if((m_PixelBuf[index+2] + ((int)color * 2))<0){ 
     m_PixelBuf[index+2] = 0;    
    } 
    else{ 
     m_PixelBuf[index+2]=m_PixelBuf[index+2] + ((int)color * 2); 
    } 

    //m_PixelBuf[index+3]=255;//Alpha 
} 

ctx = CGBitmapContextCreate(m_PixelBuf, 
          CGImageGetWidth(inImage), 
          CGImageGetHeight(inImage), 
          CGImageGetBitsPerComponent(inImage), 
          CGImageGetBytesPerRow(inImage), 
          CGImageGetColorSpace(inImage), 
          CGImageGetBitmapInfo(inImage)); 
imageRef = CGBitmapContextCreateImage (ctx); 
rawImage = [[UIImage alloc]initWithCGImage:imageRef]; 
drawImage.image = rawImage; 
[rawImage release]; 
CGContextRelease(ctx); 
CFRelease(imageRef); 
CFRelease(m_DataRef); 
//drawImage.image = unfilteredImage2; 
willUpdate = YES; 
} 

任何額外的意見/信息我只是複製整個方法遺憾。

感謝,

Storealutes

回答

1

我有同樣的問題。 您應該使用下面的代碼來獲取指向像素緩衝區的指針,而不是CFDataGetBytePtr()。

CGImageRef cgImage = originalImage.CGImage; 
size_t width = CGImageGetWidth(cgImage); 
size_t height = CGImageGetHeight(cgImage); 

char *buffer = (char*)malloc(sizeof(char) * width * height * 4); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef cgContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); 
CGContextSetBlendMode(cgContext, kCGBlendModeCopy); 
CGContextDrawImage(cgContext, CGRectMake(0.0f, 0.0f, width, height), cgImage); 

free(buffer); 
CGContextRelease(cgContext); 
CGColorSpaceRelease(colorSpace);