iOS - 带有 alpha 的 UIImage 在 iOS13 上的 MKOverlayRenderer 中有褪色的颜色

iOS - UIImage with alpha has washed-out colors in MKOverlayRenderer on iOS13

我有 MKOverlayRenderer 和从 PNG 加载的 RGBA UIImage。图像的透明部分的 alpha 值为 0,半透明部分的 alpha 值为 160。

但是,当我在地图上渲染图像时,颜色有点褪色,整个图像看起来像是在雾中。此问题在更新到 iOS 13 后发生,旧版本按预期工作。

我通过[UIImage imageNamed:@"some_img"];

加载图片

我已经扩展了 MKOverlayRenderer,并覆盖了 drawMapRect 方法:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { 
    UIImage * img = [UIImage imageNamed:@"some_img"];

    MKMapRect theMapRect = self.overlay.boundingMapRect;
    CGRect theRect = [self rectForMapRect:theMapRect];

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextTranslateCTM(context, 0.0, -theRect.size.height);
    CGContextDrawImage(context, theRect, img.CGImage);
}

我尝试通过创建副本并使用以下公式手动处理 RGBA 像素,从图像中手动删除预乘 alpha(将 alpha 设置为 255 而不是 160):

CGImageRef sourceImage = img.CGImage;

CFDataRef theData;
theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));

UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(theData);

int dataLength = CFDataGetLength(theData);

for (int i = 0; i < dataLength; i += 4){
   uint8_t aHalf = pixelData[i + 3] / 2;
   pixelData[i + 0] = (pixelData[i + 0] * 255 + aHalf) / pixelData[i + 3];
   pixelData[i + 1] = (pixelData[i + 1] * 255 + aHalf) / pixelData[i + 3];
   pixelData[i + 2] = (pixelData[i + 2] * 255 + aHalf) / pixelData[i + 3];        
   pixelData[i + 3] = (pixelData[i + 3] == 0) ? 0 : 255;
}

CGContextRef context;
context = CGBitmapContextCreate(pixelData,
                                CGImageGetWidth(sourceImage),
                                CGImageGetHeight(sourceImage),
                                8,
                                CGImageGetBytesPerRow(sourceImage),
                                CGImageGetColorSpace(sourceImage),
                                kCGImageAlphaPremultipliedLast);

UIImage *newImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];

然后我在drawMapRect中设置了CGContextSetAlpha(context, 0.6);

这部分解决了这个问题,但在旧的 iOS 版本中,图像的透明度不如 iOS 13,而且整个过程需要时间。

运行 进入同一问题:

Apple 的回应是,这是由于渲染器中 CGContext 的颜色 space 发生了变化。在 iOS 12 中使用了 RGB 颜色 space,但是 iOS 13 现在使用的是线性 sRGB 颜色 space。

我能够将我的源图像转换为使用带有 ImageMagick 的线性 sRGB,并且它们现在在呈现透明时显示正确的阴影。我不确定您是否拥有源图像,是否可以转换它们,但如果可以,那应该可以解决您的问题。