我有一个方法可以为图像添加过滤器。这个工作正常,直到几个月前,现在当我尝试使用此方法时,应用程序将在图像缓冲区崩溃。我创建缓冲区并将其设置为图像的数据,稍后访问特定索引会导致访问崩溃。我已经找了一两个小时,现在我确信有一些东西可以忽略。我认为应该发布一些不应该发布的内容。我正在使用xos的ios DP 4预览版,我认为这个问题始于测试版的更新,但我真的不确定。
这是第一个 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
答案 0 :(得分: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);