Подтвердить что ты не робот

Swift - Сравнить цвета в CGPoint

У меня есть 2 картинки, которые я хочу сравнить, если цвет пикселей одинаковый, чтобы сохранить его. Я обнаруживаю цвет пикселя этой функцией расширения UIImage:

func getPixelColor(pos: CGPoint) -> ??? {

    let pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage))
    let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

    let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

    let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
    let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
    let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
    let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

    return ???
}

Например, я запускаю сканер на картинке 1 и сохраняю его в массиве? Или словарь? И после этого я запускаю сканер на картинке 2, и когда у меня есть информация из 2-х фотографий, чтобы сравнить ее с какой функцией?

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

UPDATE: Я обновляю getPixelColor, чтобы вернуть меня "(pos) (r) (g) (b) (a)", и после этого я создал эту функцию, которая оставила только дубликаты (ПЕРЕД ИСПОЛЬЗОВАНИЕМ ЭТОЙ ФУНКЦИИ, ВЫ ИМЕЛИСЬ .sort() ARRAY!)

extension Array where Element : Equatable {
    var duplicates: [Element] {
        var arr:[Element] = []
        var start = 0
        var start2 = 1
        for _ in 0...self.count{
            if(start2<self.count){
                if(self[start] == self[start2]){
                    if(arr.contains(self[start])==false){
                        arr.append(self[start])
                    }
                }
                start+=1
                start2+=1
            }
        }
        return arr
    }
}

Это возвращает мне что-то вроде этого: "(609.0, 47.0) 1.01.01.01.0" Я знаю, что цвет черный на данный момент. Я делаю x-536, чтобы соответствовать экрану iPhone 5, и когда я делаю попытку сделать его снова, он рисует что-то неправильно... возможно Я не могу сделать это правильно.. помочь?

4b9b3361

Ответ 1

расширение UIImage возвращает UIColor. используйте этот метод для сравнения каждого пикселя двух изображений. если оба пикселя совпадают, добавьте цвет в массив массивов.

extension UIImage {
    func getPixelColor(pos: CGPoint) -> UIColor {

        let pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage))
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

        let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}


func findMatchingPixels(aImage: UIImage, _ bImage: UIImage) -> [[UIColor?]] {
    guard aImage.size == bImage.size else { fatalError("images must be the same size") }

    var matchingColors: [[UIColor?]] = []
    for y in 0..<Int(aImage.size.height) {
        var currentRow = [UIColor?]()
        for x in 0..<Int(aImage.size.width) {
            let aColor = aImage.getPixelColor(CGPoint(x: x, y: y))
            let colorsMatch = bImage.getPixelColor(CGPoint(x: x, y: y)) == aColor
            currentRow.append(colorsMatch ? aColor : nil)
        }
        matchingColors.append(currentRow)
    }
    return matchingColors
}

используется следующим образом:

let matchingPixels = findMatchingPixels(UIImage(named: "imageA.png")!, UIImage(named: "imageB.png")!)
if let colorForOrigin = matchingPixels[0][0] {
   print("the images have the same color, it is: \(colorForOrigin)")
} else {
   print("the images do not have the same color at (0,0)")
}

для простоты i, сделанной findMatchingPixels(), требуется, чтобы изображения были одного размера, но для изображений различного размера не потребовалось бы много.

UPDATE

если вы хотите ТОЛЬКО пиксели, которые соответствуют, я бы вернул кортеж следующим образом:

func findMatchingPixels(aImage: UIImage, _ bImage: UIImage) -> [(CGPoint, UIColor)] {
    guard aImage.size == bImage.size else { fatalError("images must be the same size") }

    var matchingColors = [(CGPoint, UIColor)]()
    for y in 0..<Int(aImage.size.height) {
        for x in 0..<Int(aImage.size.width) {
            let aColor = aImage.getPixelColor(CGPoint(x: x, y: y))
            guard bImage.getPixelColor(CGPoint(x: x, y: y)) == aColor else { continue }

            matchingColors.append((CGPoint(x: x, y: y), aColor))
        }
    }
    return matchingColors
}

Ответ 2

Почему бы не попробовать другой подход?

Фильтр основного изображения CIDifferenceBlendMode вернет все черные изображения, если пройдет два одинаковых изображения и изображение с областями не черного цвета, где два изображения отличаются. Передайте это в CIAreaMaximum, который вернет изображение 1x1, содержащее максимальный пиксель: если максимальное значение равно 0, вы знаете, что у вас есть два одинаковых изображения, если максимум больше нуля, эти два изображения отличаются.

Учитывая два экземпляра CIImage, imageA и imageB, здесь код:

let ciContext = CIContext()

let difference = imageA
    .imageByApplyingFilter("CIDifferenceBlendMode",
        withInputParameters: [
            kCIInputBackgroundImageKey: imageB])
    .imageByApplyingFilter("CIAreaMaximum",
        withInputParameters: [
            kCIInputExtentKey: CIVector(CGRect: imageA.extent)])

let totalBytes = 4
let bitmap = calloc(totalBytes, sizeof(UInt8))

ciContext.render(difference,
    toBitmap: bitmap,
    rowBytes: totalBytes,
    bounds: difference.extent,
    format: kCIFormatRGBA8,
    colorSpace: nil)

let rgba = UnsafeBufferPointer<UInt8>(
    start: UnsafePointer<UInt8>(bitmap),
    count: totalBytes)

let red = rgba[0]
let green = rgba[1]
let blue = rgba[2]

Если red, green или blue не равны нулю, вы знаете, что изображения разные!