Swift - 比较CGPoint的颜色

时间:2016-01-28 16:13:59

标签: ios swift uiimage pixels

我想要比较两张图片,如果像素颜色相同则保存它。 我通过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的像素颜色与2个图像相同?

更新: 我更新了getPixelColor以返回我&#34;(pos)(r)(g)(b)(a)&#34;然后我创建了这个函数,只留下了重复项目(在使用这个功能之前,你需要使用这个功能。)#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
    }
}

这会给我这样的回报: &#34;(609.0,47.0)1.01.01.01.0&#34;我知道此时颜色是黑色的我做x-536以适应iPhone 5屏幕,当我再次尝试绘制它时会出现错误...也许我无法正确地做到这一点..帮助?

2 个答案:

答案 0 :(得分:4)

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

为简单起见,我findMatchingPixels()要求图像大小相同,但允许不同尺寸的图像不会花费太多。

<强>更新

如果你只想要匹配的像素,我会返回一个像这样的元组:

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
}

答案 1 :(得分:0)

为什么不尝试不同的方法?

如果传递两个相同的图像,则核心图像滤镜static void Main(string[] args) { Parallel.For(0, fileCount, i => { dxmtId = Convert.ToInt32(dxmtIds[i]); iflId = Convert.ToInt32(iflIds[i]); islId = Convert.ToInt32(islIds[i]); fileName = fileNames[i].ToString(); LoadFileIntoDatabase(monitorId, islId, dxmtId, iflId, fileName); }); } private static void LoadFileIntoDatabase (int procId, int islId, int dxmtId, iflId, fileName ) { string fileNameDone = fileName + ".done"; if (File.Exists(fileName)) { // code for successfully loading file myCommand = @"CMD.EXE"; ProcessStartInfo startInfo = new ProcessStartInfo(myCommand) { WorkingDirectory = ConfigurationManager.AppSettings["ExportPath"].ToString(), Arguments = @"/c SQLLDR CONTROL=" + controlFileWithPath + " PARFILE=" + parFileWithPath, //RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; Process process = new Process(); process.StartInfo = startInfo; process.Start(); process.WaitForExit(); exitCode = process.ExitCode; try { File.Copy(fileName, fileNameDone, true); //rename file to .done File.Delete(fileName); //delete original file } catch (exception ex) { File.AppendAllText(@"c:\temp\fileerrors.txt", ex.Message + " " + " on copying or deleting file name: " + fileName + Environment.NewLine); } } } 将返回全黑图像,而如果两个图像不同,则将返回非黑色区域的图像。将其传递到CIDifferenceBlendMode将返回包含最大像素的1x1图像:如果最大值为0,则表示您有两个相同的图像,如果最大值大于零,则两个图像不同。 / p>

鉴于两个CIAreaMaximum个实例,CIImageimageA,代码如下:

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] redgreen不为零,您就知道图片不同了!