【发布时间】:2010-11-05 18:47:21
【问题描述】:
我目前正在尝试获取 UIImageView 中像素的 alpha 值。我从 [UIImageView image] 获得了 CGImage 并由此创建了一个 RGBA 字节数组。 Alpha 是预乘的。
CGImageRef image = uiImage.CGImage;
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
rawData = malloc(height * width * 4);
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(
rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
CGContextRelease(context);
然后我使用来自 UIImageView 的坐标计算给定 Alpha 通道的数组索引。
int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];
但是我没有得到我期望的值。对于图像的完全黑色透明区域,我得到 alpha 通道的非零值。我是否需要转换 UIKit 和 Core Graphics 之间的坐标 - 即:y 轴是否倒置?还是我误解了预乘的 alpha 值?
更新:
@Nikolai Ruhe 的建议对此至关重要。我实际上不需要在 UIKit 坐标和 Core Graphics 坐标之间进行转换。但是,在设置混合模式后,我的 alpha 值符合我的预期:
CGContextSetBlendMode(context, kCGBlendModeCopy);
【问题讨论】:
-
嘿teabot - 我意识到这个问题已经得到回答,但我几天前正在做类似的事情。您应该仅将源图像的 1px 绘制到 1px x 1px 位图上下文中,而不是绘制整个图像然后索引到字节数组中。您可以使用 CGContextDrawImage 中的 rect 参数来放入正确的像素,这就像快 1000 倍 :-)
-
感谢@Ben Gotow 的评论——我只画了一次图像,然后继续使用相同的字节数组。 @Nikolai Ruhe 也建议单像素绘制,但表示如果我不需要多次绘制图像,但需要重复查找 alpha,我的数组方法会更快。
-
在使用此问题和此处的另一个问题以解决类似问题后的快速更新(多年后):CGContextDrawImage 上的 rect 参数用于控制“边界框在用户空间中的位置和尺寸在其中绘制图像。”因此,如果您将该矩形的大小设为 1x1,它会在绘制之前将整个图像缩小到 1x1。为了获得正确的像素,您需要像 Nikolai 的回答那样使用 CGContextTranslateCTM,并使矩形的大小与源图像相同以防止缩放。
-
您好,我正在尝试使用您发布的代码,但无法获取“rawData”、“bytePerPixel”变量的数据类型。你能告诉我答案吗?
标签: iphone uikit core-graphics quartz-graphics