Цвет пикселя в ARSCNView

Я пытаюсь получить цвет пикселя в CGPoint, определяемый местоположением касания. Я пробовал следующий код, но значение цвета неверно.

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = event?.allTouches?.first {
        let loc:CGPoint = touch.location(in: touch.view)
        // in debugger, the image is correct
        let image = sceneView.snapshot()
        guard let color = image[Int(loc.x), Int(loc.y)] else{
            return
        }
        print(color)

    }
}
....

extension UIImage {

subscript (x: Int, y: Int) -> [UInt8]? {
    if x < 0 || x > Int(size.width) || y < 0 || y > Int(size.height) {
        return nil
    }
    let provider = self.cgImage!.dataProvider
    let providerData = provider!.data
    let data = CFDataGetBytePtr(providerData)

    let numberOfComponents = 4
    let pixelData = ((Int(size.width) * y) + x) * numberOfComponents

    let r = data![pixelData]
    let g = data![pixelData + 1]
    let b = data![pixelData + 2]
    return [r, g, b]

}
}

Запуск этого и касание пятна на экране, которое является очень большим постоянным ярко-оранжевым цветом, дает широкий диапазон значений RGB, и просмотр цвета, который они фактически производят, дает совершенно другой цвет (темно-синий в случае оранжевого цвета).

Я предполагаю, что, возможно, системы координат разные, и я на самом деле получаю другую точку на изображении, возможно?

РЕДАКТИРОВАТЬ: Также я должен упомянуть, что часть, на которой я касаюсь, - это 3D-модель, на которую не влияет освещение, поэтому цвет должен быть и, по-видимому, постоянным во время выполнения.

1 ответ

Ну, это было проще, чем я думал. Сначала я настроил некоторые вещи, например, чтобы касание было зарегистрировано в моем виде:

 let loc:CGPoint = touch.location(in: sceneView)

Затем я перераспределил свою точку cgpoint, чтобы приспособиться к виду изображения, выполнив следующие действия:

let image = sceneView.snapshot()
let x = image.size.width / sceneView.frame.size.width
let y = image.size.height / sceneView.frame.size.height
guard let color = image[Int(x * loc.x), Int(y * loc.y)] else{
   return
}

Это позволило мне, наконец, иметь постоянные значения RGB (не только числа, которые менялись при каждом касании, даже если я был одного цвета). Но значения все еще были выключены. По какой-то причине мой возвращенный массив был обратным, поэтому я изменил это с помощью:

let b = data![pixelData]
let g = data![pixelData + 1]
let r = data![pixelData + 2]

Я не уверен, почему я должен был сделать эту последнюю часть, поэтому любое понимание этого будет оценено!

Другие вопросы по тегам