iOS - UIImage с альфа имеет размытые цвета в MKOverlayRenderer на iOS13 - PullRequest
0 голосов
/ 06 октября 2019

У меня MKOverlayRenderer с RGBA UIImage, загруженным из PNG. Изображение имеет альфа-значения 0 для прозрачных частей и 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);
}

Я пытался вручную удалить предварительно умноженную альфа (установить альфа на 255 вместо 160) из изображения, создав его копию и обработав пиксели RGBA вручную по следующей формуле:

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)];

Затем я установил CGContextSetAlpha(context, 0.6); в drawMapRect.

Это частично решило проблему, но в старых версиях iOS изображение менее прозрачно, чем в iOS 13, плюс весь процесс занимает время.

1 Ответ

2 голосов
/ 17 октября 2019

Натолкнулся на ту же проблему:

Ответ от Apple состоит в том, что это связано с изменением цветового пространства CGContext в рендере. В iOS 12 использовалось цветовое пространство RGB, но iOS 13 теперь использует линейное цветовое пространство sRGB.

Мне удалось преобразовать мои исходные изображения для использования Linear sRGB с ImageMagick, и теперь они отображают правильный оттенок, когда отображаются прозрачными. Я не уверен, что вы владеете исходными изображениями и можете конвертировать их, но если это возможно, это должно решить вашу проблему.

...