Swift 和 Objective-C 应用程序中不同的 UIImage RGB 数据输出
Different UIImage RGB data output in Swift and Objective-C apps
我正在研究图像处理框架并使用此代码读取 RGB 数据:
if let data = image.cgImage?.dataProvider?.data {
let dataPtr: UnsafePointer<UInt8> = CFDataGetBytePtr(data)
let width = Int(image.size.width)
let height = Int(image.size.height)
for y in 0..<height {
for x in 0..<width {
let pixelInfo: Int = ((width * y) + x) * 4
let r = dataPtr[pixelInfo]
let g = dataPtr[pixelInfo + 1]
let b = dataPtr[pixelInfo + 2]
print("\(r), \(g), \(b)")
}
}
}
如果我创建新的 Swift 项目和新的 Objective-C 项目并使用相同的代码(使用 Objc 项目的桥头文件),我会得到不同的结果,例如:
5, 36, 20; 24, 69, 48 (Swift)
5, 36, 18; 21, 69, 47 (Objc)
这会导致进一步处理的结果大不相同。我尝试使用 Objective-C 代码并使用 CGBitmapContextCreate() 读取数据,但得到的结果完全相同。它在两个应用程序中显示相同的 ColorSpace,我尝试将其手动设置为 DeviceRGB 和 sRGB,但没有成功。
我必须将 Objc 输出与 Android 应用相匹配,结果与 Swift 应用完全相同。
更新。
我尝试过的第二个解决方案是为 Objective-C 编写另一个代码,它 returns 完全相同的结果与 Swift:
不匹配
size_t bytesSize = 0;
unsigned char *bytes = [self getBytesFromImage:image dataSize:&bytesSize];
size_t doubleSize = sizeof(double) * bytesSize;
double *doubles = (double *)malloc(doubleSize);
size_t doublesIndex = 0;
size_t counter = 0;
while (counter < bytesSize) {
unsigned char r = bytes[counter];
unsigned char g = bytes[counter+1];
unsigned char b = bytes[counter+2];
counter += 4;
}
- (unsigned char*) getBytesFromImage:(UIImage *)image dataSize:(size_t *)dataSize {
*dataSize = size_t(4 * image.size.width * image.size.height);
unsigned char *imageData = (unsigned char*)malloc(*dataSize);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef imageRef = [image CGImage];
CGContextRef bitmap = CGBitmapContextCreate( imageData, image.size.width, image.size.height, 8, image.size.width * 4 , colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(bitmap, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);
CGContextRelease(bitmap);
CGColorSpaceRelease(colorSpace);
return imageData;
}
根据您的 Swift 代码,我编码了您在下面看到的内容。
我使用了你的代码和这段代码,它们似乎完美匹配 - 至少对于我使用这一面的图像而言。
// Dump some bytes
- ( void ) test
{
UIImage * img = [UIImage imageNamed:@"test"];
CGDataProviderRef dp = CGImageGetDataProvider( img.CGImage );
CFDataRef data = CGDataProviderCopyData ( dp );
CFIndex length = CFDataGetLength ( data );
NSUInteger i = 0;
unsigned char rgba [ 4 ];
// Print all
// while ( i < length )
// Print first few
while ( i < 100 )
{
CFDataGetBytes( data, CFRangeMake( i, sizeof( rgba ) ), rgba );
i += 4;
NSLog ( @"RGB %d %d %d", rgba[ 0 ], rgba[ 1 ], rgba[ 2 ] );
}
CFRelease ( data );
CGDataProviderRelease ( dp );
}
我正在研究图像处理框架并使用此代码读取 RGB 数据:
if let data = image.cgImage?.dataProvider?.data {
let dataPtr: UnsafePointer<UInt8> = CFDataGetBytePtr(data)
let width = Int(image.size.width)
let height = Int(image.size.height)
for y in 0..<height {
for x in 0..<width {
let pixelInfo: Int = ((width * y) + x) * 4
let r = dataPtr[pixelInfo]
let g = dataPtr[pixelInfo + 1]
let b = dataPtr[pixelInfo + 2]
print("\(r), \(g), \(b)")
}
}
}
如果我创建新的 Swift 项目和新的 Objective-C 项目并使用相同的代码(使用 Objc 项目的桥头文件),我会得到不同的结果,例如:
5, 36, 20; 24, 69, 48 (Swift)
5, 36, 18; 21, 69, 47 (Objc)
这会导致进一步处理的结果大不相同。我尝试使用 Objective-C 代码并使用 CGBitmapContextCreate() 读取数据,但得到的结果完全相同。它在两个应用程序中显示相同的 ColorSpace,我尝试将其手动设置为 DeviceRGB 和 sRGB,但没有成功。
我必须将 Objc 输出与 Android 应用相匹配,结果与 Swift 应用完全相同。
更新。 我尝试过的第二个解决方案是为 Objective-C 编写另一个代码,它 returns 完全相同的结果与 Swift:
不匹配size_t bytesSize = 0;
unsigned char *bytes = [self getBytesFromImage:image dataSize:&bytesSize];
size_t doubleSize = sizeof(double) * bytesSize;
double *doubles = (double *)malloc(doubleSize);
size_t doublesIndex = 0;
size_t counter = 0;
while (counter < bytesSize) {
unsigned char r = bytes[counter];
unsigned char g = bytes[counter+1];
unsigned char b = bytes[counter+2];
counter += 4;
}
- (unsigned char*) getBytesFromImage:(UIImage *)image dataSize:(size_t *)dataSize {
*dataSize = size_t(4 * image.size.width * image.size.height);
unsigned char *imageData = (unsigned char*)malloc(*dataSize);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef imageRef = [image CGImage];
CGContextRef bitmap = CGBitmapContextCreate( imageData, image.size.width, image.size.height, 8, image.size.width * 4 , colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(bitmap, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);
CGContextRelease(bitmap);
CGColorSpaceRelease(colorSpace);
return imageData;
}
根据您的 Swift 代码,我编码了您在下面看到的内容。
我使用了你的代码和这段代码,它们似乎完美匹配 - 至少对于我使用这一面的图像而言。
// Dump some bytes
- ( void ) test
{
UIImage * img = [UIImage imageNamed:@"test"];
CGDataProviderRef dp = CGImageGetDataProvider( img.CGImage );
CFDataRef data = CGDataProviderCopyData ( dp );
CFIndex length = CFDataGetLength ( data );
NSUInteger i = 0;
unsigned char rgba [ 4 ];
// Print all
// while ( i < length )
// Print first few
while ( i < 100 )
{
CFDataGetBytes( data, CFRangeMake( i, sizeof( rgba ) ), rgba );
i += 4;
NSLog ( @"RGB %d %d %d", rgba[ 0 ], rgba[ 1 ], rgba[ 2 ] );
}
CFRelease ( data );
CGDataProviderRelease ( dp );
}