2017-03-17 3 views
1

ios에서 photoshop의 마술 지팡이 도구와 유사한 색상 선택 도구를 구현하고 있습니다.실험실 색상 공간에서 픽셀 버퍼 만들기

나는 이미 RGB로 작업하고 있지만 더 정확하게 만들기 위해 LAB 색상 공간에서 작동하게하고 싶습니다.

현재 작동하는 방식은 UIImage를 사용하여 해당 이미지의 CGImage 버전을 만드는 것입니다. 그런 다음 RGB 색상 공간에 CGContext를 만들고 해당 컨텍스트에서 CGImage를 그린 다음 컨텍스트 데이터를 가져온 다음 RGBA32 구조체를 사용하는 픽셀 버퍼에 바인딩합니다.

let colorSpace  = CGColorSpaceCreateDeviceRGB() 
let width   = inputCGImage.width 
let height   = inputCGImage.height 
let bytesPerPixel = 4 
let bitsPerComponent = 8 
let bytesPerRow  = bytesPerPixel * width 
let bitmapInfo  = RGBA32.bitmapInfo 

guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colspace, bitmapInfo: bitmapInfo) else { 
      print("unable to create context") 
      return nil 
     } 
    context.draw(inputCGImage, in: CGRect(x: 0, y: 0, width: width, height: height)) 

    guard let buffer = context.data else { 
      print("unable to get context data") 
      return nil 
     } 

    let pixelBuffer = buffer.bindMemory(to: RGBA32.self, capacity: width * height) 


struct RGBA32: Equatable { 

    var color: UInt32 

    var redComponent: UInt8 { 
     return UInt8((color >> 24) & 255) 
    } 

    var greenComponent: UInt8 { 
     return UInt8((color >> 16) & 255) 
    } 

    var blueComponent: UInt8 { 
     return UInt8((color >> 8) & 255) 
    } 

    var alphaComponent: UInt8 { 
     return UInt8((color >> 0) & 255) 
    } 


    init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) { 
     color = (UInt32(red) << 24) | (UInt32(green) << 16) | (UInt32(blue) << 8) | (UInt32(alpha) << 0) 

    } 
    static let clear = RGBA32(red: 0, green: 0, blue: 0, alpha: 0) 

    static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 

    static func ==(lhs: RGBA32, rhs: RGBA32) -> Bool { 
     return lhs.color == rhs.color 
    } 
} 

그것은 신속 여기에서 설명하는대로 매우 단순한 유 클리 디안 거리를 사용하여 선택된 화소의 컬러 값을 비교하는 픽셀 버퍼를 사용한다.

https://en.wikipedia.org/wiki/Color_difference

나는 그것이 작동하지만 내가 작업 할 더 정확한 결과를 CIE 랩 색 공간입니다 말했듯이.

처음에는 위의 색상 차이 링크에서 자세히 설명한대로 CIE94 비교를 사용하여 각 픽셀을 LAB 색상으로 변환 해 보았습니다. 그것은 효과가 있었지만 매우 느린 것 같았습니다. 확인하기 전에 백만 픽셀 (또는 그 이상)을 LAB 컬러로 변환해야했기 때문입니다.

그런 다음 신속하게 작동하게하려면 LAB 색 공간에 픽셀 버퍼를 저장하는 것이 좋습니다 (다른 용도로는 사용되지 않습니다).

그래서 나는 유사한 구조체 LABA32

struct LABA32:Equatable { 


    var colour: UInt32 

    var lComponent: UInt8 { 
     return UInt8((colour >> 24) & 255) 
    } 
    var aComponent: UInt8 { 
     return UInt8((colour >> 16) & 255) 
    } 
    var bComponent: UInt8 { 
     return UInt8((colour >> 8) & 255) 
    } 
    var alphaComponent: UInt8 { 
     return UInt8((colour >> 0) & 255) 
    } 

    init(lComponent: UInt8, aComponent: UInt8, bComponent: UInt8, alphaComponent: UInt8) { 
     colour = (UInt32(lComponent) << 24) | (UInt32(aComponent) << 16) | (UInt32(bComponent) << 8) | (UInt32(alphaComponent) << 0) 

    } 

    static let clear = LABA32(lComponent: 0, aComponent: 0, bComponent: 0, alphaComponent: 0) 
    static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 

    static func ==(lhs: LABA32, rhs: LAB32) -> Bool { 
     return lhs.colour == rhs.colour 
    } 

내가이 새로운 구조체에 데이터를 매핑해야하는 대신 장치 RGB의 실험실 colourspace과 맥락에서의 CGImage을 그리면 내가 잘못하지만 이론에있을 수 있습니다 생성 .

내가 겪고있는 문제는 실제로이 이론이 실제로 작동하는지 테스트하자.

나는이 생성자 사과 문서에 따르면

CGColorSpace(labWhitePoint: <UnsafePointer<CGFloat>!>, blackPoint: <UnsafePointer<CGFloat>!>, range: <UnsafePointer<CGFloat>!>) 

를 사용하는 것을 시도하고있다 실험실 colourspace를 만들려면

흰색 포인트 :에, 을 자극 값을 지정하는 3 개 개의 숫자의 배열 확산 백색 점의 CIE 1931 XYZ 공간. 검은 색 점 : 확산 검은 색 점의 CIE 1931 XYZ- 공간에있는 삼자 극치를 지정하는 숫자 3 개로 구성된 배열입니다. 범위 : 색 공간이 인 a * 및 b * 구성 요소의 유효한 값 범위를 지정하는 네 개의 숫자 의 배열입니다. a * 구성 요소는 녹색 에서 빨간색으로 실행되는 값을 나타내며 b * 구성 요소는 파란색에서 노란색까지 실행되는 값을 나타냅니다.CGFloats

그래서 만든 3 개 배열

var whitePoint:[CGFloat] = [0.95947,1,1.08883] 
var blackPoint:[CGFloat] = [0,0,0] 
var range:[CGFloat] = [-127,127,-127,127] 

나는 그 색 공간

let colorSpace = CGColorSpace(labWhitePoint: &whitePoint, blackPoint: &blackPoint, range: &range) 
를 구성하려고 문제는 내가 오류 "지원되지 않는 색 공간을"점점 계속 것입니다

그래서 나는 완전히 잘못된 것을해야 할 것입니다. 나는 LAB 색 공간을 만들려고 노력하는 사람들을 찾기 위해 많은 시간을 보냈지 만 객관적인 C 버전을 찾으려는 시도조차도 관련성이없는 것으로 보입니다.

그래서 실제로 어떻게 LAB 색 공간을 올바르게 만들 수 있습니까?

감사합니다.

답변

0

documentation는 말한다 :

중요 : 아이폰 OS 장치 독립적 또는 일반 색 공간을 지원하지 않습니다. iOS 응용 프로그램은 대신 장치 색 공간을 사용해야합니다.

그래서 내가 LAB에서 작업하고 싶다면 수동으로 변환해야 할 것 같습니다.