2016-01-28 12 views
12

Ho 2 foto che voglio confrontare, se il colore dei pixel è lo stesso per salvarlo. rilevo il colore del pixel da questa funzione UIImage estensione:Swift - Confronta i colori su 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 ??? 
} 

Per esempio, ho eseguito lo scanner sulla foto 1 e salvarlo in un array? O dizionario? E dopo eseguo lo scanner sull'immagine 2 e quando ho le informazioni da 2 immagini per confrontarlo con quale funzione?

Voglio vedere in quale CGPoint i colori dei pixel sono identici a partire da 2 immagini?

UPDATE: aggiorno getPixelColor per me tornare "(pos) (r) (g) (b) (a)" e dopo che ho creato questa funzione che ha lasciato solo duplicati (PRIMA DI UTILIZZARE QUESTA FUNZIONE DOVETE. sort() la matrice)

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

questo mi torna qualcosa di simile: "(609,0, 47,0) 1.01.01.01.0" so che il colore è nero, a questo punto faccio x-536 a in forma lo schermo di iPhone 5 e quando faccio un tentativo di disegnarlo di nuovo disegna qualcosa di sbagliato ... forse non riesco a farlo correttamente .. aiuto?

+0

ritorno un 'UIColor', e verificare se sono uguali? Si noti che la differenza tra i colori è un argomento discusso con un approccio molto diverso. – Larme

+0

anche - stai controllando ogni singolo pixel? Se stai eseguendo la scansione di queste immagini, non penso che tu abbia molte possibilità di renderle allineate pixel-perfette, anche prima di iniziare a preoccuparti di scandire ogni colore corretto a 1/255 in ogni dimensione. – Russell

+0

UIColor non è conforme al protocollo lavabile ... Alcuni pixel sono identici al 100%, voglio vedere su quali CGPoint sono identici ... –

risposta

3

avere l'estensione UIImage restituisce un colore UIC. utilizzare questo metodo per confrontare ciascun pixel delle due immagini. se entrambi i pixel corrispondono, aggiungi il colore a una matrice di matrici.

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 
} 

usato così:

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

per semplicità i fatti findMatchingPixels() richiedono le immagini siano della stessa dimensione, ma non ci vuole molto per consentire immagini di dimensioni diverse.

UPDATE

se desideri solo i pixel che corrispondono, mi piacerebbe tornare una tupla come questo:

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

Perché non provare un approccio diverso?

Il filtro Immagine core CIDifferenceBlendMode restituirà un'immagine completamente nera se ha trasmesso due immagini identiche e un'immagine con aree non nere in cui due immagini differiscono. Passa a un numero CIAreaMaximum che restituirà un'immagine 1x1 contenente il pixel massimo: se il valore massimo è 0, sai di avere due immagini identiche, se il massimo è maggiore di zero, le due immagini sono diverse.

Dati due CIImage casi, imageA e imageB, ecco il codice:

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] 

Se red, green o blue non sono pari a zero, si conoscono le immagini sono diverse!

+0

Alcuni pixel sono identici al 100%, voglio vedere su quale CGPoint sono identici ... –

+0

Ah, OK, ho frainteso "Ho 2 foto che voglio confrontare, se il colore dei pixel è lo stesso per salvarlo.". Pensavo volessi salvare un'immagine solo se le due immagini fossero identiche. –