代码之家  ›  专栏  ›  技术社区  ›  Sterling Lutes

8号机组EXC_BAD_ACCESS

  •  0
  • Sterling Lutes  · 技术社区  · 12 年前

    我有一个方法,将添加一个过滤器的图像。直到几个月前,这还很好,现在当我尝试使用这种方法时,应用程序会在图像缓冲区上崩溃。我创建缓冲区并将其设置为图像的数据,稍后访问特定索引会导致严重的访问崩溃。在过去的一两个小时里,我一直在寻找,现在我确信有什么东西我忽略了。我认为发布了一些不应该发布的东西。我正在使用xcode的ios DP 4预览版,我认为这个问题始于测试版的更新,但我真的不确定。

    这是它坠毁的线路,位于 中间的 for循环

        m_PixelBuf[index+2] = m_PixelBuf[index+2]/*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 回复  |  直到 12 年前
        1
  •  1
  •   mmtootmm    12 年前

    我也有同样的问题。 您应该使用以下代码来获取指向像素缓冲区的指针,而不是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);