A máscara CGImage não funciona em visores Wide Color Gamut

7

Eu tenho uma subclasse UIView que renderiza uma imagem com uma máscara aplicada. Ele funciona perfeitamente em todos os dispositivos (somente iPad), exceto aqueles com uma exibição Wide Color Gamut (os mais novos iPad Pros), onde a máscara é completamente transparente (parece para o usuário que a exibição não está lá). O código init / drawRect relevante se parece com isto:

init(image: UIImage) {
    scratchable = image.cgImage!
    imageWidth = scratchable.width
    imageHeight = scratchable.height

    let colorspace = CGColorSpaceCreateDeviceGray()

    let pixels = CFDataCreateMutable(nil, imageWidth * imageHeight)!

    alphaPixels = CGContext(
        data: CFDataGetMutableBytePtr(pixels),
        width: imageWidth,
        height: imageHeight,
        bitsPerComponent: 8,
        bytesPerRow: imageWidth,
        space: colorspace,
        bitmapInfo: CGImageAlphaInfo.none.rawValue
    )!
    provider = CGDataProvider(data: pixels)!

    alphaPixels.setFillColor(UIColor.black.cgColor)

    let mask = CGImage(
        maskWidth: imageWidth,
        height: imageHeight,
        bitsPerComponent: 8,
        bitsPerPixel: 8,
        bytesPerRow: imageWidth,
        provider: provider,
        decode: nil,
        shouldInterpolate: false
    )!

    scratched = scratchable.masking(mask)!

    super.init(frame: CGRect(x: 0, y: 0, width: imageWidth/2, height: imageHeight/2))

    alphaPixels.fill(imageRect)

    isOpaque = false
}

override func draw(_ rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()!
    context.saveGState()
    context.translateBy(x: 0, y: bounds.size.height)
    context.scaleBy(x: 1.0, y: -1.0)
    context.draw(scratched, in: rect)
    context.restoreGState()
}

(Para o contexto, o motivo pixels , alphaPixels , etc. é necessário devido a outro código na classe que atrai o contexto para afetar a máscara).

Alguma ideia do motivo pelo qual a exibição ampla da gama de cores afetaria isso ou o que poderia ser feito para corrigir isso? Eu pensei que poderia ter algo a ver com o espaço de cor, mas os documentos afirmam claramente que as máscaras devem usar CGColorSpaceCreateDeviceGray para que ele funcione corretamente (o que é realmente verdade).

Veja um exemplo de projeto que demonstra o problema: link

    
por pwightman 18.10.2017 в 21:32
fonte

1 resposta

2

Atualizado após discussão:

O problema parece estar no tratamento do CFData.

CFDataCreateMutable(CFAllocatorRef allocator, CFIndex capacity)

O parâmetro capacity é "O número máximo de bytes que o objeto CFData pode conter." Ainda temos que lidar com a propriedade length, anexando bytes ou

CFDataSetLength(pixels, imageWidth * imageHeight)

Resposta original:

Tente não usar cores nomeadas, como UIColor.black . Compor cores de componentes em vez disso. Espaços de cores mistos podem não ser manipulados corretamente pelo Core Graphics.

    
por paiv 01.11.2017 / 18:30
fonte