简体   繁体   English

Swift - 比较CGPoint的颜色

[英]Swift - Compare colors at CGPoint

I have 2 pictures which I want to compare, if pixel color is the same to save it. 我想要比较两张图片,如果像素颜色相同则保存它。 I detect the color of the pixel by this UIImage extension function: 我通过这个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 ???
}

For example, I run the scanner on picture 1 and save it in an array? 例如,我在图片1上运行扫描仪并将其保存在一个数组中? Or dictionary? 还是字典? And after that I run the scanner on picture 2 and when I have the information from 2 pictures to compare it with what function? 然后我在图片2上运行扫描仪,当我从2张图片中获取信息时,将它与什么功能进行比较?

I want to see on which CGPoint the pixels colors are identical from 2 images? 我想看看哪个CGPoint的像素颜色从2个图像中相同?

UPDATE: I update getPixelColor to return me "(pos)(r)(g)(b)(a)" and after that I created this function which left only duplicates (BEFORE USING THIS FUNCTION YOU HAVE TO .sort() THE ARRAY!) 更新:我更新了getPixelColor以返回“(pos)(r)(g)(b)(a)”之后我创建了这个只留下重复的函数(在使用这个功能之前,你需要排序)。 !)

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

This returns me something like this: "(609.0, 47.0)1.01.01.01.0" I know that the color is black at this point I do x-536 to fit iPhone 5 screen and when I make an attempt to draw it again it draws something wrong... maybe I can't do it properly.. help? 这回复给我这样的东西:“(609.0,47.0)1.01.01.01.0”我知道此时颜色是黑色我做x-536以适应iPhone 5屏幕,当我试图再次绘制它时画错了......也许我不能正确地做..帮助?

have the UIImage extension return a UIColor. 让UIImage扩展返回一个UIColor。 use this method to compare each pixel of the two images. 使用此方法比较两个图像的每个像素。 if both pixels match, add the color to an array of arrays. 如果两个像素都匹配,则将颜色添加到数组数组中。

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
}

used like this: 像这样使用:

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

for simplicity i made findMatchingPixels() require the images be the same size, but it wouldn't take much to allow different sized images. 为简单起见,我使findMatchingPixels()要求图像大小相同,但允许不同大小的图像并不需要太多。

UPDATE UPDATE

if you want ONLY the pixels that match, i'd return a tuple like this: 如果你只想匹配的像素,我会返回这样的元组:

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
}

Why not try a different approach? 为什么不尝试不同的方法?

The Core Image filter CIDifferenceBlendMode will return an all black image if passed two identical images and an image with areas of non black where two images differ. 如果传递两个相同的图像,则核心图像滤镜CIDifferenceBlendMode将返回全黑图像,而如果两个图像不同,则返回非黑色区域的图像。 Pass that into a CIAreaMaximum which will return a 1x1 image containing the maximum pixel: if the maximum value is 0, you know you have two identical images, if the maximum is greater than zero, the two images are different. 将其传递到CIAreaMaximum ,它将返回包含最大像素的1x1图像:如果最大值为0,则表示您有两个相同的图像,如果最大值大于零,则两个图像不同。

Given two CIImage instances, imageA and imageB , here's the code: 给定两个CIImage实例, imageAimageB ,这里是代码:

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]

If red , green or blue are not zero, you know the images are different! 如果redgreenblue不为零,则表示图像不同!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM