2016-01-28 9 views
12

Ich habe 2 Bilder, die ich vergleichen möchte, wenn Pixelfarbe die gleiche ist, um es zu speichern. ich erkennen, die Farbe des Pixels durch diese UIImage Erweiterungsfunktion:Swift - Vergleichen Sie Farben bei CGPoint

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 ??? 
} 

Zum Beispiel führe ich den Scanner auf Bild 1 und es in einem Array speichern? Oder ein Wörterbuch? Und dann laufe ich den Scanner auf Bild 2 und wenn ich die Informationen von 2 Bildern habe um sie mit welcher Funktion zu vergleichen?

Ich möchte sehen, auf welchem ​​CGPoint die Pixelfarben aus 2 Bildern identisch sind?

UPDATE: Ich aktualisiere getPixelColor, um mir "(Pos) (r) (g) (b) (a)" und danach habe ich diese Funktion erstellt, die nur Duplikate (vor der Verwendung dieser Funktion Sie haben). (sortiert) dIE 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 
    } 
} 

das gibt mir so etwas wie diese: „(609,0, 47,0) 1.01.01.01.0“ ich weiß, dass die Farbe an dieser Stelle schwarz ich x-536 zu fit iPhone 5 Bildschirm und wenn ich versuche, es wieder zu zeichnen es zieht etwas falsch ... vielleicht kann ich es nicht richtig machen .. Hilfe?

+0

Rückkehr ein 'UIColor', und überprüfen, ob sie Gleichen sind? Beachten Sie, dass der Unterschied zwischen den Farben ein viel diskutiertes Thema ist. – Larme

+0

auch - überprüfen Sie jedes einzelne Pixel? Wenn Sie diese Bilder einscannen, haben Sie kaum eine Chance, dass sie pixelgenau aneinandergereiht werden, noch bevor Sie anfangen, sich darum zu kümmern, dass jede Farbe in jeder Dimension korrekt auf 1/255 gescannt wird. – Russell

+0

UIColor ist nicht konform zu Protokoll hashable ... Einige der Pixel sind 100% identisch, ich möchte sehen, auf welche CGPoint sind identisch ... –

Antwort

3

haben die UIImage Erweiterung eine UIColor zurückgeben. Verwenden Sie diese Methode, um jedes Pixel der beiden Bilder zu vergleichen. Wenn beide Pixel übereinstimmen, fügen Sie die Farbe zu einem Array von Arrays hinzu.

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 
} 

wie folgt verwendet:

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

der Einfachheit halber erfordern i gemacht findMatchingPixels() die Bilder gleich groß sein, aber es wäre unterschiedlich große Bilder zu ermöglichen, nicht viel.

UPDATE

, wenn Sie nur die Pixel möchten, das Spiel, i ein Tupel wie folgt zurückkehren würde:

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 
} 
0

Warum nicht einen anderen Ansatz versuchen?

Der Core-Image-Filter CIDifferenceBlendMode gibt ein vollständig schwarzes Bild zurück, wenn zwei identische Bilder und ein Bild mit nicht schwarzen Bereichen, in denen sich zwei Bilder unterscheiden, übergeben werden. Übergeben Sie das in eine CIAreaMaximum, die ein 1x1 Bild mit dem maximalen Pixel zurückgibt: Wenn der maximale Wert 0 ist, wissen Sie, dass Sie zwei identische Bilder haben. Wenn das Maximum größer als Null ist, sind die beiden Bilder unterschiedlich.

Gegeben zwei CIImage Fällen imageA und imageB, hier ist der Code:

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] 

Wenn red, green oder blue nicht Null sind, wissen Sie, die Bilder unterschiedlich sind!

+0

Einige der Pixel sind 100% identisch, ich möchte auf welchen CGPoint sehen sind identisch ... –

+0

Ah, OK, ich missverstanden "Ich habe 2 Bilder, die ich vergleichen möchte, wenn die Pixelfarbe gleich ist, um es zu speichern.". Ich dachte, du willst ein Bild nur speichern, wenn die beiden Bilder identisch sind. –