我正在尝试使用 Core Graphics 进行逐像素图像过滤器(使用 CFData 将 CGImage 分解为无符号整数)
但是,当我尝试使用处理后的数据创建图像时,生成的图像的颜色明显不同。
我注释掉了整个循环,我实际上改变了像素的 RGB 值,但也没有任何变化。
当我初始化我在过滤器中使用的 UIImage 时;我使用带有 UIGraphicsBeginContext() 的 drawInRect 来调整大小;在从相机拍摄的图像上。
当我删除调整大小步骤并直接从相机设置图像时;过滤器似乎工作得很好。这是我初始化正在使用的图像的代码(从 didFinishPickingImage 内部)
self.editingImage
是一个 UIImageView,self.editingUIImage
是一个 UIImage
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage : (UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
self.didAskForImage = YES;
UIGraphicsBeginImageContext(self.editingImage.frame.size);
float prop = image.size.width / image.size.height;
float left, top, width, height;
if(prop < 1){
height = self.editingImage.frame.size.height;
width = (height / image.size.height) * image.size.width;
left = (self.editingImage.frame.size.width - width)/2;
top = 0;
}else{
width = self.editingImage.frame.size.width;
height = (width / image.size.width) * image.size.height;
top = (self.editingImage.frame.size.height - height)/2;
left = 0;
}
[image drawInRect:CGRectMake(left, top, width, height)];
self.editingUIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.editingImage.image = self.editingUIImage;
[self.contrastSlider addTarget:self action:@selector(doImageFilter:) forControlEvents:UIControlEventValueChanged];
[self.brightnessSlider addTarget:self action:@selector(doImageFilter:) forControlEvents:UIControlEventValueChanged];
[picker dismissModalViewControllerAnimated:YES];
picker = nil;
}
按照我需要的方式调整图像的大小和位置;
这是图像过滤函数,我已经把实际的循环内容去掉了,因为它们不相关。
- (void) doImageFilter:(id)sender{
CGImageRef src = self.editingUIImage.CGImage;
CFDataRef dta;
dta = CGDataProviderCopyData(CGImageGetDataProvider(src));
UInt8 *pixData = (UInt8 *) CFDataGetBytePtr(dta);
int dtaLen = CFDataGetLength(dta);
for (int i = 0; i < dtaLen; i += 3) {
//the loop
}
CGContextRef ctx;
ctx = CGBitmapContextCreate(pixData, CGImageGetWidth(src), CGImageGetHeight(src), 8, CGImageGetBytesPerRow(src), CGImageGetColorSpace(src), kCGImageAlphaPremultipliedLast);
CGImageRef newCG = CGBitmapContextCreateImage(ctx);
UIImage *new = [UIImage imageWithCGImage:newCG];
CGContextRelease(ctx);
CFRelease(dta);
CGImageRelease(newCG);
self.editingImage.image = new;
}
图片一开始是这样的
然后在执行 doImageFilter 之后...
如前所述,只有当我使用上面所示的调整大小方法时才会发生这种情况。
真的被这个问题难住了,一整天都在研究它......非常感谢任何帮助!
干杯
更新:我已经检查了所有图像对象的颜色空间,它们都是 kCGColorSpaceDeviceRGB。很困惑这个家伙,当我将图像分解为无符号整数时,我很确定出了什么问题,但我不确定是什么......有人吗?
最佳答案
你的问题在最后一行:
ctx = CGBitmapContextCreate(pixData,
CGImageGetWidth(src),
CGImageGetHeight(src),
8,
CGImageGetBytesPerRow(src),
CGImageGetColorSpace(src),
kCGImageAlphaPremultipliedLast);
您正在对源图像数据的 Alpha 和组件顺序做出假设,这显然是不正确的。您应该通过 CGImageGetBitmapInfo(src) 从源图像中获取该信息。
为了避免此类问题,如果您从任意 CGImage 开始并且想要直接操作位图的字节,最好以您指定的格式创建一个 CGBitmapContext
指定您自己(不是直接从源图像中获取)。然后,将源图像绘制到位图上下文中;如有必要,CG 会将图像数据转换为位图上下文的格式。然后从位图上下文中获取数据并对其进行操作。
关于iphone - 核心显卡RGB数据问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11303390/