【问题标题】:CGContextDrawImage inconsistent byte values across devices?CGContextDrawImage 跨设备的字节值不一致?
【发布时间】:2012-12-06 00:05:13
【问题描述】:

我正在尝试比较两个图像(实际上是在较大的图像中找到一个较小的“子图像”),并且我正在使用下面提供的方法加载图像。

下面的代码现在包含一个测试 for 循环,它总结了所有单独的字节值。我发现这个总和因此字节不同,这取决于它正在运行的设备。我的问题是为什么会这样?

// Black and white configuration:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
NSUInteger bytesPerPixel = 1;
NSUInteger bitsPerComponent = 8;
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;

// Image
CGImageRef imageRef = [[UIImage imageNamed:@"image.jpg"] CGImage];
NSUInteger imageWidth = CGImageGetWidth(imageRef);
NSUInteger imageHeight = CGImageGetHeight(imageRef);
NSUInteger imageSize = imageHeight * imageWidth * bytesPerPixel;
NSUInteger imageBytesPerRow = bytesPerPixel * imageWidth;

unsigned char *imageRawData = calloc(imageSize, sizeof(unsigned char));
CGContextRef imageContext = CGBitmapContextCreate(imageRawData, imageWidth, imageHeight, bitsPerComponent,
                                                  imageBytesPerRow, colorSpace, bitmapInfo);

// Draw the actual image to the bitmap context
CGContextDrawImage(imageContext, CGRectMake(0, 0, imageWidth, imageHeight), imageRef);
CGContextRelease(imageContext);


NSUInteger sum = 0;
for (int byteIndex = 0; byteIndex < imageSize; byteIndex++)
{
    sum += imageRawData[byteIndex];
}

NSLog(@"Sum: %i", sum); // Output on simulator:    Sum: 18492272
                        // Output on iPhone 3GS:   Sum: 18494036
                        // Output on another 3GS:  Sum: 18494015
                        // Output on iPhone 4:     Sum: 18494015


free(imageRawData);
CGColorSpaceRelease(colorSpace);

【问题讨论】:

    标签: iphone objective-c ios bitmap core-graphics


    【解决方案1】:

    这些设备是否都运行相同版本的操作系统?另一种可能性(除了色彩空间,有人已经提到)是 JPG 解码库可能略有不同。由于 JPEG 是一种有损图像格式,因此不同的解码器会生成位图不相等的结果并非不可想象。鉴于 iOS UI 中大量使用图像,假设 JPG 解码器将不断调整以获得最佳性能,这似乎是合理的。

    我什至相信,在不同型号的设备(即不同的处理器)上运行的相同操作系统版本之间,如果有多个版本的 JPG 解码器,每个版本都针对一个特定的 CPU,尽管这并不能解释具有相同操作系统的 2 个相同型号的设备之间的差异。

    您可以尝试使用无损格式的图像重新运行实验。

    还可能值得指出的是,为 CGBitmapContext 提供您自己的后备内存,但不特别考虑字对齐可能会导致性能不佳。例如,您有:

    NSUInteger imageBytesPerRow = bytesPerPixel * imageWidth;
    

    如果 imageBytesPerRow 不是 CPU 原生字长的倍数,您将获得次优性能。

    【讨论】:

    • 我认为你是对的!实际上,我的示例中的两个结果是相同的,并且 iPhone 3GS 和 iPhone 4 具有相同的 iOS 版本 5.0.1
    【解决方案2】:

    我假设“设备灰色”颜色空间因设备而异。尝试使用独立于设备的色彩空间。

    【讨论】:

    • 嗯,我刚刚尝试将 CGColorSpaceCreateDeviceGray() 替换为 CGColorSpaceCreateCalibratedGray((float[3]){1.0, 1.0, 1.0}, (float[3]){0.0, 0.0, 0.0}, 1.0)这应该与设备无关,结果相同,总和不同(我得到的数字与我的问题中提到的相同)...
    猜你喜欢
    • 1970-01-01
    • 2020-05-27
    • 2020-12-19
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 2014-05-30
    • 2012-12-22
    • 2017-01-06
    相关资源
    最近更新 更多