ios - 为什么 iPhone 7 和 iPhone 7 Plus 屏幕截图会发送与 RGB 色彩空间图像不兼容的 alpha?

标签 ios objective-c iphone ios10

我正在尝试创建位图上下文以调整从相机胶卷导入的图像的大小。这是代码:

    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            0,
                                            CGImageGetColorSpace(imageRef),
                                            CGImageGetBitmapInfo(imageRef));

我有两张在 iPhone 7 上截取的屏幕截图,当我尝试从相机胶卷加载它们时,一张失败,另一张成功。

第一个是失败的:

<CGImage 0x1701de3c0>
<<CGColorSpace 0x174a325c0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Display P3)>
    width = 750, height = 1334, bpc = 16, bpp = 64, row bytes = 6000 
    kCGImageAlphaLast | kCGImageByteOrder16Little 
    is mask? No, has mask? No, has matte? No, should interpolate? Yes

这里是错误:

<Error>: CGBitmapContextCreate: unsupported parameter combination:
     16 integer bits/component;
     64 bits/pixel;
    RGB color space model; kCGImageAlphaLast;
    3840 bytes/row.
Valid parameters for RGB color space model are:
    16  bits per pixel,         5  bits per component,         kCGImageAlphaNoneSkipFirst
    32  bits per pixel,         8  bits per component,         kCGImageAlphaNoneSkipFirst
    32  bits per pixel,         8  bits per component,         kCGImageAlphaNoneSkipLast
    32  bits per pixel,         8  bits per component,         kCGImageAlphaPremultipliedFirst
    32  bits per pixel,         8  bits per component,         kCGImageAlphaPremultipliedLast
    64  bits per pixel,         16 bits per component,         kCGImageAlphaPremultipliedLast
    64  bits per pixel,         16 bits per component,         kCGImageAlphaNoneSkipLast
    64  bits per pixel,         16 bits per component,         kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    64  bits per pixel,         16 bits per component,         kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
    128 bits per pixel,         32 bits per component,         kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    128 bits per pixel,         32 bits per component,         kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
See Quartz 2D Programming Guide (available online) for more information.

第二个是成功的:

<CGImage 0x1705c0a50>
<<CGColorSpace 0x17402b7c0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1)>
    width = 750, height = 1334, bpc = 8, bpp = 32, row bytes = 3000 
    kCGImageAlphaPremultipliedLast | 0 (default byte order) 
    is mask? No, has mask? No, has matte? No, should interpolate? Yes

关于这种特殊情况,我找不到任何明确的信息。所以,我想知道是否有人对此问题有任何见解以及可能的修复建议。我在这里完全感到困惑。

我的崩溃日志表明这个问题只出现在我的 iPhone 7 和 iPhone 7 Plus 用户身上。

提前致谢。

最佳答案

我希望有人找到更好的解决方案,因为这是一个 hack,但这是我的解决方法:

kCGImageAlphaLast 参数是该位图信息中不受支持的部分。对于图像完全不透明的情况,您可以使用 kCGImageAlphaPremultipliedLast 并获得相同的结果,因为在完全不透明的情况下,alpha 预乘本质上是一个空操作(每个像素都乘以 1 ).

但是警告,如果图像有任何半透明像素,它们的颜色将是错误的。在我的例子中,我希望照片完全不透明,否则用户没有正确使用我的应用程序,所以我现在可以忍受这个。

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

// first try
CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                        newRect.size.width,
                                        newRect.size.height,
                                        CGImageGetBitsPerComponent(imageRef),
                                        0,
                                        CGImageGetColorSpace(imageRef),
                                        bitmapInfo);

if (!bitmap && (bitmapInfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaLast) {

    // WARNING - only do this if you expect a fully opaque image

    // try again with pre-multiply alpha

    // clear alpha bits
    bitmapInfo &= ~kCGBitmapAlphaInfoMask;
    // set pre-multiply last
    bitmapInfo |= kCGImageAlphaPremultipliedLast & kCGBitmapAlphaInfoMask;

    CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                        newRect.size.width,
                                        newRect.size.height,
                                        CGImageGetBitsPerComponent(imageRef),
                                        0,
                                        CGImageGetColorSpace(imageRef),
                                        bitmapInfo);

}

if (!bitmap) {
    // fail gracefully
}

关于ios - 为什么 iPhone 7 和 iPhone 7 Plus 屏幕截图会发送与 RGB 色彩空间图像不兼容的 alpha?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42494745/

相关文章:

ios - iOS 7 的 UIToolbar 中 UIBarButtonItems 的垂直位置不正确

objective-c - 哪个类最适合读取和表示 HTML 文件?

ios - 如何在我的 Objective-C iOS 项目中使用 C 库?

iphone -/n 在来自 XML 解析的数组中

iphone - 从 iPhone 应用程序访问现有语音笔记

iphone - NSFetchedResultsController sectionNameKeyPath 等效于 EKEventStore 从 iPhone 日历中获取的事件

ios - 如何在iOS中清除CGContext中的圆圈

ios - 为 JPEG 图像提供文件名中的 .PNG 扩展名? (X代码)

iphone - 可以限制 NSArray FilteredArrayUsingPredicate 返回的结果

iphone - UIActionSheet出现两次