2017-10-18 61 views
9

Mam podklasę UIView, która renderuje obraz z zastosowaną maską. Działa doskonale na wszystkich urządzeniach (tylko iPad), z wyjątkiem tych z ekranem Wide Color Gamut (najnowszy iPad Pros), w którym maska ​​jest całkowicie przezroczysta (wygląda na to, że użytkownik nie ma widoku). Odpowiedni startowych/code drawRect wygląda następująco:Maska CGImage nie działa na wyświetlaczach Wide Color Gamut

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() 
} 

(Dla kontekstu, przyczyny pixels, alphaPixels itp są konieczne ze względu na inny kod w klasie, która wciąga w kontekście wpływu na maskę).

Każdy pomysł, dlaczego szeroki zakres wyświetlania kolorów wpłynie na to, lub co można zrobić, aby to naprawić? Pomyślałem, że może to mieć coś wspólnego z przestrzenią kolorów, ale doktorzy jasno stwierdzają, że maski muszą używać CGColorSpaceCreateDeviceGray, aby działała prawidłowo (co jest prawdą).

Oto przykładowy projekt wykazania problem: http://d.pr/f/IS4SEF

+0

Czy to problem na iPhoneX (ma również szeroką gamę kolorów)? Czy można go odtworzyć w symulatorze? – paiv

+0

Czy możesz połączyć dobre i złe obrazy wyników? – paiv

+0

@paiv To aplikacja przeznaczona tylko dla iPada, a także nie mamy iPhone'a X, więc nie jestem pewien. Zakładam, że to nie zadziała. Nie można go odtworzyć w symulatorze, tylko w urządzeniu. Właśnie zredagowałem moje pytanie z linkiem do przykładowego projektu. Dzięki za pomoc! – pwightman

Odpowiedz

2

zaktualizowany po dyskusji:

Problem wydaje się być w obsłudze CFData przez interfejs API.

CFDataCreateMutable(CFAllocatorRef allocator, CFIndex capacity) 

Parametr capacity to „maksymalną ilość bajtów, które mogą zawierać obiekt CFData przez interfejs API”. Nadal mamy do obsługi właściwości length, albo przez dodanie bajtów lub

CFDataSetLength(pixels, imageWidth * imageHeight) 

odpowiedź oryginalny:

Staraj się nie za pomocą nazwanych kolorów, jak UIColor.black. Zamiast tego komponuj kolory z komponentów. Mieszane przestrzenie kolorów mogą nie być obsługiwane poprawnie przez Core Graphics.

+0

Próbowałem już każdej odmiany tworzenia kolorów, o której wiem, niestety, nie ma kości. Czy istnieje konkretna forma tworzenia, która działa? – pwightman

+0

Hej, @paiv. Zgadnij, co ... masz to działa dla nas. W widelcu przykładowego projektu dodano ten wiersz kodu: https://github.com/paiv/MaskBugWideColorDisplays/blob/1f133ce49b326de4ba3b4937a7d778ae60d442da/MaskBugWideColorDisplays/MaskView.swift#L31 –

+0

Od czasu zakończenia drugiej nagrody, otworzyłem nową więc mogę cię nagrodzić. Na szczęście, nowa nagroda musi być większa niż ostatnia, więc podwajasz poprzednią. Dziękuję za pomoc! Jeśli nie miałbyś nic przeciwko aktualizacji odpowiedzi, więc odzwierciedla to poprawne rozwiązanie, nagrodzę cię nagrodą! –