根据对a previous question的回复,我在UIImageView上创建了一个用于提取像素数据的类别。这在模拟器中工作正常,但在部署到设备时则不行。我应该说总是 - 奇怪的是,如果point.x == point.y,它会获取正确的像素颜色;否则,它给出了该行另一侧像素的像素数据,就像镜像一样。 (因此,点击图像右下角的像素会为我提供左上角相应像素的像素数据,但点击左下角的像素会返回正确的像素颜色)。触摸坐标(CGPoint)是正确的。
我做错了什么?
这是我的代码:
@interface UIImageView (PixelColor)
- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point;
@end
@implementation UIImageView (PixelColor)
- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point
{
UIColor* color = nil;
CGImageRef cgImage = [self.image CGImage];
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = height - (NSUInteger)floor(point.y);
if ((x < width) && (y < height))
{
CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
CFDataRef bitmapData = CGDataProviderCopyData(provider);
const UInt8* data = CFDataGetBytePtr(bitmapData);
size_t offset = ((width * y) + x) * 4;
UInt8 red = data[offset];
UInt8 blue = data[offset+1];
UInt8 green = data[offset+2];
UInt8 alpha = data[offset+3];
CFRelease(bitmapData);
color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
}
return color;
}
答案 0 :(得分:5)
我认为R B G 是错误的。你有:
UInt8 red = data[offset];
UInt8 blue = data[offset+1];
UInt8 green = data[offset+2];
但你真的不是指R G B 吗? :
UInt8 red = data[offset];
UInt8 green = data[offset+1];
UInt8 blue = data[offset+2];
但是,即使修复了这个问题,仍然存在一个问题,因为它在设备上显示了Apple byte swaps(伟大的文章)R和B值,但在模拟器上时不。
我有一个类似的模拟器/设备问题,CFDataGetBytePtr返回的PNG像素缓冲区。
这解决了我的问题:
#if TARGET_IPHONE_SIMULATOR
UInt8 red = data[offset];
UInt8 green = data[offset + 1];
UInt8 blue = data[offset + 2];
#else
//on device
UInt8 blue = data[offset]; //notice red and blue are swapped
UInt8 green = data[offset + 1];
UInt8 red = data[offset + 2];
#endif
不确定这是否会解决您的问题,但是在我修复之前,您行为不端的代码看起来与我的样子差不多。
最后一件事:我相信即使在调用data[]
之后,模拟器也会让您访问像素缓冲区CFRelease(bitmapData)
。在设备上,根据我的经验,这是不的情况。您的代码不应受到影响,但如果这有助于其他人,我认为我会提及它。
答案 1 :(得分:0)
您可以尝试以下替代方法:
这种方法适用于模拟器和设备。
答案 2 :(得分:0)
在原始问题中发布的代码中看起来像是代替:
NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = height - (NSUInteger)floor(point.y);
应该是:
NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = (NSUInteger)floor(point.y);