【问题标题】:Core graphics RGB data issue核心显卡RGB数据问题
【发布时间】:2012-07-03 10:16:20
【问题描述】:

我正在尝试使用 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。对这个家伙感到很困惑,当我将图像分解为无符号整数时,我很可能出了点问题,但我不确定是什么......有人吗?

【问题讨论】:

    标签: iphone ios ios5 rgb core-image


    【解决方案1】:

    你的问题在最后一行:

    ctx = CGBitmapContextCreate(pixData, 
                                CGImageGetWidth(src), 
                                CGImageGetHeight(src), 
                                8, 
                                CGImageGetBytesPerRow(src), 
                                CGImageGetColorSpace(src), 
                                kCGImageAlphaPremultipliedLast);
    

    您正在对源图像数据的 alpha 和组件排序做出假设,这显然是不正确的。您应该通过CGImageGetBitmapInfo(src) 从源图像中获取它。

    为避免此类问题,如果您从任意 CGImage 开始,并且想要直接操作位图的字节,最好以您自己指定的格式制作 CGBitmapContext(而不是直接取自源图像)。然后,将源图像绘制到位图上下文中;如有必要,CG 会将图像的数据转换为位图上下文的格式。然后从位图上下文中获取数据并进行操作。

    【讨论】:

    • 太棒了,成功了。我理解你所说的关于 alpha 组件的内容,这实际上是我目前正在调试的地方,但我没有意识到你可以从原始图像中得到它。感谢您的回复,对我对这些东西的理解帮助了我很多。干杯!
    猜你喜欢
    • 2015-05-20
    • 2011-07-03
    • 1970-01-01
    相关资源
    最近更新 更多