Forráskód Böngészése

Demo - 对照图片差异覆盖对比

zhudongyong 2 éve
szülő
commit
c33393c996

+ 32 - 4
KdanAutoTest/KdanAuto.xcodeproj/project.pbxproj

@@ -12,12 +12,13 @@
 		240509B529433CDE00B501B2 /* QuickLookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 240509B229433CDE00B501B2 /* QuickLookUI.framework */; };
 		240509B72943479800B501B2 /* ProcessThumbnal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240509B62943479800B501B2 /* ProcessThumbnal.swift */; };
 		240550FF2952F42F00B95E0B /* ComPDFKit_Conversion.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2451F58A2952E4E50049FA9C /* ComPDFKit_Conversion.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		240934B42992735200839CC8 /* FileConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240934B32992735200839CC8 /* FileConverter.swift */; };
+		240934B72992737200839CC8 /* ImageProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240934B62992737200839CC8 /* ImageProcess.swift */; };
 		242F966D298BAE2200CFF56C /* Toggle_off.png in Resources */ = {isa = PBXBuildFile; fileRef = 242F966A298BAE2200CFF56C /* Toggle_off.png */; };
 		242F966E298BAE2200CFF56C /* Toggle_on.png in Resources */ = {isa = PBXBuildFile; fileRef = 242F966B298BAE2200CFF56C /* Toggle_on.png */; };
 		242F966F298BAE2200CFF56C /* Toggle_half.png in Resources */ = {isa = PBXBuildFile; fileRef = 242F966C298BAE2200CFF56C /* Toggle_half.png */; };
 		243DACD32940C6E8008A8AA6 /* ActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243DACD22940C6E8008A8AA6 /* ActivityView.swift */; };
 		2451F58B2952E4E50049FA9C /* ComPDFKit_Conversion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2451F58A2952E4E50049FA9C /* ComPDFKit_Conversion.framework */; };
-		2451F58D2952E5850049FA9C /* FileConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2451F58C2952E5850049FA9C /* FileConverter.swift */; };
 		24A6FF49293091E000B34F2E /* AutoTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6FF48293091E000B34F2E /* AutoTest.swift */; };
 		24A6FF4B2930939D00B34F2E /* TextColorAutoTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6FF4A2930939D00B34F2E /* TextColorAutoTest.swift */; };
 		24A6FF4F2930A1E100B34F2E /* FontAutoTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A6FF4E2930A1E100B34F2E /* FontAutoTest.swift */; };
@@ -108,12 +109,13 @@
 		240509B129433CDE00B501B2 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; };
 		240509B229433CDE00B501B2 /* QuickLookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLookUI.framework; path = System/Library/Frameworks/QuickLookUI.framework; sourceTree = SDKROOT; };
 		240509B62943479800B501B2 /* ProcessThumbnal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessThumbnal.swift; sourceTree = "<group>"; };
+		240934B32992735200839CC8 /* FileConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileConverter.swift; sourceTree = "<group>"; };
+		240934B62992737200839CC8 /* ImageProcess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProcess.swift; sourceTree = "<group>"; };
 		242F966A298BAE2200CFF56C /* Toggle_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Toggle_off.png; sourceTree = "<group>"; };
 		242F966B298BAE2200CFF56C /* Toggle_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Toggle_on.png; sourceTree = "<group>"; };
 		242F966C298BAE2200CFF56C /* Toggle_half.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Toggle_half.png; sourceTree = "<group>"; };
 		243DACD22940C6E8008A8AA6 /* ActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityView.swift; sourceTree = "<group>"; };
 		2451F58A2952E4E50049FA9C /* ComPDFKit_Conversion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ComPDFKit_Conversion.framework; sourceTree = "<group>"; };
-		2451F58C2952E5850049FA9C /* FileConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FileConverter.swift; path = FileConveter/FileConverter.swift; sourceTree = "<group>"; };
 		24A6FF48293091E000B34F2E /* AutoTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoTest.swift; sourceTree = "<group>"; };
 		24A6FF4A2930939D00B34F2E /* TextColorAutoTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextColorAutoTest.swift; sourceTree = "<group>"; };
 		24A6FF4E2930A1E100B34F2E /* FontAutoTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontAutoTest.swift; sourceTree = "<group>"; };
@@ -224,6 +226,31 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
+		240934B12992735200839CC8 /* Tools */ = {
+			isa = PBXGroup;
+			children = (
+				240934B52992736600839CC8 /* ImageProcess */,
+				240934B22992735200839CC8 /* FileConveter */,
+			);
+			path = Tools;
+			sourceTree = "<group>";
+		};
+		240934B22992735200839CC8 /* FileConveter */ = {
+			isa = PBXGroup;
+			children = (
+				240934B32992735200839CC8 /* FileConverter.swift */,
+			);
+			path = FileConveter;
+			sourceTree = "<group>";
+		};
+		240934B52992736600839CC8 /* ImageProcess */ = {
+			isa = PBXGroup;
+			children = (
+				240934B62992737200839CC8 /* ImageProcess.swift */,
+			);
+			path = ImageProcess;
+			sourceTree = "<group>";
+		};
 		242F9669298BAE2200CFF56C /* Images */ = {
 			isa = PBXGroup;
 			children = (
@@ -382,11 +409,11 @@
 		24D7FFF8292B4FDB00DAB5EE /* Class */ = {
 			isa = PBXGroup;
 			children = (
+				240934B12992735200839CC8 /* Tools */,
 				24D70007292D141A00DAB5EE /* AutoTestCase */,
 				24D70002292B94A100DAB5EE /* Norrmal */,
 				24D7FFFC292B508600DAB5EE /* DataModel */,
 				24D7FFF9292B4FF500DAB5EE /* Setting */,
-				2451F58C2952E5850049FA9C /* FileConverter.swift */,
 				24AE7B4B298BD97300462BD3 /* CompareViewController */,
 			);
 			path = Class;
@@ -675,13 +702,14 @@
 				24D7FF9B29261A6400DAB5EE /* AppDelegate.swift in Sources */,
 				243DACD32940C6E8008A8AA6 /* ActivityView.swift in Sources */,
 				24AE7B4D298BD98300462BD3 /* CompareViewController.swift in Sources */,
+				240934B42992735200839CC8 /* FileConverter.swift in Sources */,
 				24D7000B292D16BB00DAB5EE /* StringAutoTest.swift in Sources */,
 				24DCE8A9295046A5004EBA35 /* TestCaseCellView.swift in Sources */,
 				24D7FFFB292B501100DAB5EE /* SettingViewController.swift in Sources */,
 				24DCE8A429504430004EBA35 /* AutoTestTypes.swift in Sources */,
 				24DCE8B32950543C004EBA35 /* AutoTestCellInfo.swift in Sources */,
+				240934B72992737200839CC8 /* ImageProcess.swift in Sources */,
 				24DCE8B1295047D8004EBA35 /* TestFileCellView.swift in Sources */,
-				2451F58D2952E5850049FA9C /* FileConverter.swift in Sources */,
 				24A6FF4B2930939D00B34F2E /* TextColorAutoTest.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

BIN
KdanAutoTest/KdanAuto.xcodeproj/project.xcworkspace/xcuserdata/zhudongyong.xcuserdatad/UserInterfaceState.xcuserstate


+ 2 - 2
KdanAutoTest/KdanAuto.xcodeproj/xcuserdata/zhudongyong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -14,8 +14,8 @@
             filePath = "KdanAuto/Class/AutoTestCase/AutoTest.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "671"
-            endingLineNumber = "671"
+            startingLineNumber = "575"
+            endingLineNumber = "575"
             landmarkName = "stringToImage(_:)"
             landmarkType = "7">
          </BreakpointContent>

+ 1 - 97
KdanAutoTest/KdanAuto/Class/AutoTestCase/AutoTest.swift

@@ -205,7 +205,7 @@ class AutoTest : NSObject, AutoTestProtocal {
                                 if ( processSuccess &&
                                      FileManager.default.fileExists(atPath: rComparePath)) {
                                     
-                                    let degree = self.compareJPEG(rComparePath, checkPath: cComparePath)
+                                    let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath)
                                     
                                     if degree == -1 {
                                         self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比失败,生成快照失败或无比对文件\n",
@@ -281,102 +281,6 @@ class AutoTest : NSObject, AutoTestProtocal {
         }
     }
     
-    //  Image compare
-    func compareJPEG(_ resultPath:String, checkPath:String) -> Double {
-        if !FileManager.default.fileExists(atPath: resultPath) || !FileManager.default.fileExists(atPath: checkPath) {
-            return -1
-        }
-        
-        let rImage = NSImage.init(contentsOfFile: resultPath) ?? nil
-        let cImage = NSImage.init(contentsOfFile: checkPath) ?? nil
-        
-        if nil == rImage || nil == cImage {
-            return -1
-        }
-        
-        let resultImage = rImage as! NSImage
-        let checkImage = cImage as! NSImage
-        
-        let resultImageRep = NSBitmapImageRep.init(cgImage: resultImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-        let checkImageRep = NSBitmapImageRep.init(cgImage: checkImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-        
-        let rWidth = resultImageRep.pixelsWide
-        let rHeight = resultImageRep.pixelsHigh
-        let rBitPerPixel = resultImageRep.bitsPerPixel / 8
-        let rBytePerRow = resultImageRep.bytesPerRow
-        
-        let cWidth = checkImageRep.pixelsWide
-        let cHeight = checkImageRep.pixelsHigh
-        let cBitPerPixel = checkImageRep.bitsPerPixel / 8
-        let cBytePerRow = checkImageRep.bytesPerRow
-        
-        let maxWidth = min(rWidth, cWidth) - 1
-        let maxHeight = min(rHeight, cHeight) - 1
-        
-        // check background color
-        // 挑选图片 对角斜线 上的相素进行识别
-        var markInfo = NSMutableDictionary.init()
-        for w in 0...maxWidth {
-            let x = Int(w)
-            for mark in 0...1 {
-                let color = checkImageRep.colorAt(x: min(x, cWidth-1), y: min(mark == 0 ? x : (maxWidth - x), (cHeight-1))) as! NSColor
-                
-                let r = Int(color.redComponent*255)
-                let g = Int(color.greenComponent*255)
-                let b = Int(color.blueComponent*255)
-                
-                if (markInfo[color] != nil) {
-                    let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
-                    
-                    markInfo[color] = NSNumber.init(value: count + 1)
-                }else {
-                    markInfo[color] = NSNumber.init(value: 1)
-                }
-            }
-        }
-        
-        var maxCount = Int(0);
-        var bgColor : NSColor? = nil
-        for color in markInfo.allKeys {
-            let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
-                         
-            if count > maxCount {
-                maxCount = count
-                bgColor = color as! NSColor
-            }
-        }
-        
-        if nil != bgColor {
-            NSLog(String("识别到背景色\(bgColor)"))
-        }
-        
-        // Compare
-        var equalCount = 0 as Double
-        var bgCount = 0 as Double
-        for w in 0...maxWidth {
-            let x = Int(w)
-            
-            for h in 0...maxHeight {
-                let y = Int(h)
-                
-                let cColor = checkImageRep.colorAt(x: x, y: y) as! NSColor
-                let rColor = resultImageRep.colorAt(x: x, y: y) as! NSColor
-                
-                if (cColor.isEqual(to: rColor)) {
-                    equalCount = equalCount + 1
-                    
-                    if bgColor != nil &&
-                        cColor.isEqual(to: bgColor) {
-                        bgCount += 1
-                    }
-                }
-            }
-        }
-        
-        NSLog(String("过滤点数目\(bgCount)"))
-        
-        return Double(max(equalCount-bgCount, 1)/(max(Double(cWidth) * Double(cHeight)-bgCount, 1)) * 100.0)
-    }
     
     // Update Refrence image
     func canUpdateRefImage() -> Bool {

+ 1 - 1
KdanAutoTest/KdanAuto/Class/AutoTestCase/StringAutoTest.swift

@@ -241,7 +241,7 @@ class CharacterAutoTest : AutoTest {
                         if (processSuccess &&
                             FileManager.default.fileExists(atPath: rComparePath)) {
                             
-                            let degree = self.compareJPEG(rComparePath, checkPath: cComparePath)
+                            let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath)
                             
                             if degree == -1 {
                                 self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照对比失败,生成快照失败或无比对文件\n",

+ 1 - 1
KdanAutoTest/KdanAuto/Class/AutoTestCase/TextColorAutoTest.swift

@@ -280,7 +280,7 @@ class TextColorAutoTest : AutoTest {
                         if (ProcessThumbnal.process(resultPath, desPath: rComparePath, outputSize: CGSize.init(width: 2048, height: 2048)) &&
                             FileManager.default.fileExists(atPath: rComparePath)) {
                             
-                            let degree = self.compareJPEG(rComparePath, checkPath: cComparePath)
+                            let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath)
                             
                             if degree == -1 {
                                 self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照对比失败,生成快照失败或无比对文件\n",

+ 1 - 122
KdanAutoTest/KdanAuto/Class/CompareViewController/ImageCompareCellView.swift

@@ -117,7 +117,7 @@ class ImageCompareCellView : NSTableCellView {
 //            let image2 = NSImage.init(contentsOfFile: resultPath)
 //            _imageView04.image = image2;
             DispatchQueue.global().async {
-                let image2 = self.processImage(resultPath, checkPath: comparePath)
+                let image2 = ImageProcess.processImage(resultPath, checkPath: comparePath)
 
                 DispatchQueue.main.sync {
                     self._imageView04.image = image2
@@ -136,125 +136,4 @@ class ImageCompareCellView : NSTableCellView {
         _imageView04.isHidden = _showCoverBtn.state == .off || _segmentedControl.indexOfSelectedItem != 1
     }
     
-    
-    //Genera Image
-    func processImage(_ resultPath:String, checkPath:String) -> NSImage? {
-        if !FileManager.default.fileExists(atPath: resultPath) || !FileManager.default.fileExists(atPath: checkPath) {
-            return nil
-        }
-        
-        let rImage = NSImage.init(contentsOfFile: resultPath) ?? nil
-        let cImage = NSImage.init(contentsOfFile: checkPath) ?? nil
-        
-        if nil == rImage || nil == cImage {
-            return nil
-        }
-        
-        let resultImage = rImage as! NSImage
-        let checkImage = cImage as! NSImage
-        
-        let resultImageRep = NSBitmapImageRep.init(cgImage: resultImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-        let checkImageRep = NSBitmapImageRep.init(cgImage: checkImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-        
-        let rWidth = resultImageRep.pixelsWide
-        let rHeight = resultImageRep.pixelsHigh
-        let rBitPerPixel = resultImageRep.bitsPerPixel / 8
-        let rBytePerRow = resultImageRep.bytesPerRow
-        
-        let cWidth = checkImageRep.pixelsWide
-        let cHeight = checkImageRep.pixelsHigh
-        let cBitPerPixel = checkImageRep.bitsPerPixel / 8
-        let cBytePerRow = checkImageRep.bytesPerRow
-        let data = NSMutableData.init(length: cWidth * cHeight * 4)
-        if nil == data {
-            return nil
-        }
-        
-        let maxWidth = min(rWidth, cWidth) - 1
-        let maxHeight = min(rHeight, cHeight) - 1
-        
-        // check background color
-        // 挑选图片 对角斜线 上的相素进行识别
-        var markInfo = NSMutableDictionary.init()
-        for w in 0...maxWidth {
-            let x = Int(w)
-            for mark in 0...1 {
-                let color = checkImageRep.colorAt(x: min(x, cWidth-1), y: min(mark == 0 ? x : (maxWidth - x), (cHeight-1))) as! NSColor
-                
-                if (markInfo[color] != nil) {
-                    let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
-                    
-                    markInfo[color] = NSNumber.init(value: count + 1)
-                }else {
-                    markInfo[color] = NSNumber.init(value: 1)
-                }
-            }
-        }
-        
-        var maxCount = Int(0);
-        var bgColor : NSColor? = nil
-        for color in markInfo.allKeys {
-            let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
-            
-            if count > maxCount {
-                maxCount = count
-                bgColor = color as! NSColor
-            }
-        }
-        
-        if nil != bgColor {
-            NSLog(String("识别到背景色\(bgColor)"))
-        }
-        
-        // Compare
-        for w in 0...maxWidth {
-            let x = Int(w)
-            
-            for h in 0...maxHeight {
-                let y = Int(h)
-                
-                let cColor = checkImageRep.colorAt(x: x, y: y) as! NSColor
-                let rColor = resultImageRep.colorAt(x: x, y: y) as! NSColor
-                
-                if (cColor.isEqual(to: rColor)) {
-                    if bgColor != nil &&
-                        cColor.isEqual(to: bgColor) {
-                    }
-                }else {
-                    let addr = cWidth * 4 * y + x * 4
-                    
-                    var r = uint8(255)
-                    data!.replaceBytes(in: NSRange.init(location: addr+0, length: 1), withBytes: &r)
-                    var g = uint8(255 * rColor.greenComponent)
-                    data!.replaceBytes(in: NSRange.init(location: addr+1, length: 1), withBytes: &g)
-                    var b = uint8(255 * rColor.blueComponent)
-                    data!.replaceBytes(in: NSRange.init(location: addr+2, length: 1), withBytes: &b)
-                    var a = uint8(255 * rColor.alphaComponent * 0.7)
-                    data!.replaceBytes(in: NSRange.init(location: addr+3, length: 1), withBytes: &a)
-                }
-            }
-        }
-        
-        let cfData = CFDataCreate(kCFAllocatorDefault, data?.bytes, data!.length)
-        let dataProvider = CGDataProvider.init(data: cfData!)
-        
-        let colorSpace = CGColorSpaceCreateDeviceRGB()
-        let cgImage = CGImage.init(width: cWidth,
-                                   height: cHeight,
-                                   bitsPerComponent: 8,
-                                   bitsPerPixel: 8 * 4,
-                                   bytesPerRow: cWidth * 4,
-                                   space: colorSpace,
-                                   bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrderDefault.rawValue) ?? CGBitmapInfo.byteOrderDefault,
-                                   provider: dataProvider!,
-                                   decode: nil,
-                                   shouldInterpolate: true,
-                                   intent: CGColorRenderingIntent.defaultIntent)
-        
-        if nil != cgImage {
-            return NSImage.init(cgImage: cgImage!, size: NSSize.init(width: cWidth, height: cHeight))
-        }
-        
-        return nil
-    }
 }

+ 19 - 0
KdanAutoTest/KdanAuto/Class/DataModel/DataModel.swift

@@ -14,6 +14,9 @@ let kResultPathComponent : String = "Result Files"
 let kCheckPathComponent : String = "Check Files"
 
 let kLatestReportIDKey : String = "LatestReportID"
+
+let kComparativeDifferenceKey : String = "ComparativeDifference"
+
     
 class DataModel : NSObject {
     static var shared : DataModel = DataModel()
@@ -91,6 +94,22 @@ class DataModel : NSObject {
         return userDefaults.value(forKey: kLatestReportIDKey) as? String
     }
     
+    public func comparativeDifference() -> Int {
+        let userDefaults = UserDefaults.standard
+        
+        if (userDefaults.value(forKey: kComparativeDifferenceKey) != nil) {
+            return userDefaults.value(forKey: kComparativeDifferenceKey) as? Int ?? Int(255 * 0.03)
+        }
+        
+        return Int(255 * 0.03)
+    }
+    
+    public func setComparativeDifference(_ comparativeDifference:Int) {
+        let userDefaults = UserDefaults.standard
+        userDefaults.set(comparativeDifference, forKey: kComparativeDifferenceKey)
+        userDefaults.synchronize()
+    }
+    
     /// Save Data
     
 }

KdanAutoTest/KdanAuto/Class/FileConveter/FileConverter.swift → KdanAutoTest/KdanAuto/Class/Tools/FileConveter/FileConverter.swift


+ 257 - 0
KdanAutoTest/KdanAuto/Class/Tools/ImageProcess/ImageProcess.swift

@@ -0,0 +1,257 @@
+//
+//  ImageProcess.swift
+//  KdanAuto
+//
+//  Created by 朱东勇 on 2023/2/7.
+//
+
+import Foundation
+import AppKit
+
+class ImageProcess : NSObject {
+    
+    //  Image compare
+    class func compareJPEG(_ resultPath:String, checkPath:String) -> Double {
+        if !FileManager.default.fileExists(atPath: resultPath) || !FileManager.default.fileExists(atPath: checkPath) {
+            return -1
+        }
+        
+        let rImage = NSImage.init(contentsOfFile: resultPath) ?? nil
+        let cImage = NSImage.init(contentsOfFile: checkPath) ?? nil
+        
+        if nil == rImage || nil == cImage {
+            return -1
+        }
+        
+        let resultImage = rImage as! NSImage
+        let checkImage = cImage as! NSImage
+        
+        let resultImageRep = NSBitmapImageRep.init(cgImage: resultImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+        let checkImageRep = NSBitmapImageRep.init(cgImage: checkImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+        
+        let rWidth = resultImageRep.pixelsWide
+        let rHeight = resultImageRep.pixelsHigh
+        let rBitPerPixel = resultImageRep.bitsPerPixel / 8
+        let rBytePerRow = resultImageRep.bytesPerRow
+        
+        let cWidth = checkImageRep.pixelsWide
+        let cHeight = checkImageRep.pixelsHigh
+        let cBitPerPixel = checkImageRep.bitsPerPixel / 8
+        let cBytePerRow = checkImageRep.bytesPerRow
+        
+        let maxWidth = min(rWidth, cWidth) - 1
+        let maxHeight = min(rHeight, cHeight) - 1
+        
+        // check background color
+        // 挑选图片 对角斜线 上的相素进行识别
+        var markInfo = NSMutableDictionary.init()
+        for w in 0...maxWidth {
+            let x = Int(w)
+            for mark in 0...1 {
+                let color = checkImageRep.colorAt(x: min(x, cWidth-1), y: min(mark == 0 ? x : (maxWidth - x), (cHeight-1))) as! NSColor
+                
+                if (markInfo[color] != nil) {
+                    let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
+                    
+                    markInfo[color] = NSNumber.init(value: count + 1)
+                }else {
+                    markInfo[color] = NSNumber.init(value: 1)
+                }
+            }
+        }
+        
+        var maxCount = Int(0);
+        var bgColor : NSColor? = nil
+        for color in markInfo.allKeys {
+            let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
+            
+            if count > maxCount {
+                maxCount = count
+                bgColor = color as! NSColor
+            }
+        }
+        
+        if nil != bgColor {
+            NSLog(String("识别到背景色\(bgColor)"))
+        }
+        
+        // Compare
+        let compareDifValue = DataModel.shared.comparativeDifference()
+        var equalCount = 0 as Double
+        var bgCount = 0 as Double
+        for w in 0...maxWidth {
+            let x = Int(w)
+            
+            for h in 0...maxHeight {
+                let y = Int(h)
+                
+                let cColor = checkImageRep.colorAt(x: x, y: y) as! NSColor
+                let rColor = resultImageRep.colorAt(x: x, y: y) as! NSColor
+                
+                let cr = Int(cColor.redComponent*255)
+                let cg = Int(cColor.greenComponent*255)
+                let cb = Int(cColor.blueComponent*255)
+                let ca = Int(cColor.blueComponent*255)
+                
+                let rr = Int(rColor.redComponent*255)
+                let rg = Int(rColor.greenComponent*255)
+                let rb = Int(rColor.blueComponent*255)
+                let ra = Int(rColor.blueComponent*255)
+                
+//                if (cColor.isEqual(to: rColor)) {
+                if (abs(cr - rr) <= compareDifValue &&
+                    abs(cg - rg) <= compareDifValue &&
+                    abs(cb - rb) <= compareDifValue &&
+                    abs(ca - ra) <= compareDifValue) {
+                    equalCount = equalCount + 1
+                    
+                    if bgColor != nil &&
+                        cColor.isEqual(to: bgColor) {
+                        bgCount += 1
+                    }
+                }
+            }
+        }
+        
+        NSLog(String("过滤点数目\(bgCount)"))
+        
+        return Double(max(equalCount-bgCount, 1)/(max(Double(cWidth) * Double(cHeight)-bgCount, 1)) * 100.0)
+    }
+    
+    //Genera Image
+    class func processImage(_ resultPath:String, checkPath:String) -> NSImage? {
+        if !FileManager.default.fileExists(atPath: resultPath) || !FileManager.default.fileExists(atPath: checkPath) {
+            return nil
+        }
+        
+        let rImage = NSImage.init(contentsOfFile: resultPath) ?? nil
+        let cImage = NSImage.init(contentsOfFile: checkPath) ?? nil
+        
+        if nil == rImage || nil == cImage {
+            return nil
+        }
+        
+        let resultImage = rImage as! NSImage
+        let checkImage = cImage as! NSImage
+        
+        let resultImageRep = NSBitmapImageRep.init(cgImage: resultImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+        let checkImageRep = NSBitmapImageRep.init(cgImage: checkImage.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+        
+        let rWidth = resultImageRep.pixelsWide
+        let rHeight = resultImageRep.pixelsHigh
+        let rBitPerPixel = resultImageRep.bitsPerPixel / 8
+        let rBytePerRow = resultImageRep.bytesPerRow
+        
+        let cWidth = checkImageRep.pixelsWide
+        let cHeight = checkImageRep.pixelsHigh
+        let cBitPerPixel = checkImageRep.bitsPerPixel / 8
+        let cBytePerRow = checkImageRep.bytesPerRow
+        let data = NSMutableData.init(length: cWidth * cHeight * 4)
+        if nil == data {
+            return nil
+        }
+        
+        let maxWidth = min(rWidth, cWidth) - 1
+        let maxHeight = min(rHeight, cHeight) - 1
+        
+        // check background color
+        // 挑选图片 对角斜线 上的相素进行识别
+        var markInfo = NSMutableDictionary.init()
+        for w in 0...maxWidth {
+            let x = Int(w)
+            for mark in 0...1 {
+                let color = checkImageRep.colorAt(x: min(x, cWidth-1), y: min(mark == 0 ? x : (maxWidth - x), (cHeight-1))) as! NSColor
+                
+                if (markInfo[color] != nil) {
+                    let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
+                    
+                    markInfo[color] = NSNumber.init(value: count + 1)
+                }else {
+                    markInfo[color] = NSNumber.init(value: 1)
+                }
+            }
+        }
+        
+        var maxCount = Int(0);
+        var bgColor : NSColor? = nil
+        for color in markInfo.allKeys {
+            let count = (markInfo[color] as? NSNumber)!.intValue ?? 0
+            
+            if count > maxCount {
+                maxCount = count
+                bgColor = color as! NSColor
+            }
+        }
+        
+        if nil != bgColor {
+            NSLog(String("识别到背景色\(bgColor)"))
+        }
+        
+        // Compare
+        let compareDifValue = DataModel.shared.comparativeDifference()
+        for w in 0...maxWidth {
+            let x = Int(w)
+            
+            for h in 0...maxHeight {
+                let y = Int(h)
+                
+                let cColor = checkImageRep.colorAt(x: x, y: y) as! NSColor
+                let rColor = resultImageRep.colorAt(x: x, y: y) as! NSColor
+                
+                let cr = Int(cColor.redComponent*255)
+                let cg = Int(cColor.greenComponent*255)
+                let cb = Int(cColor.blueComponent*255)
+                let ca = Int(cColor.blueComponent*255)
+                
+                let rr = Int(rColor.redComponent*255)
+                let rg = Int(rColor.greenComponent*255)
+                let rb = Int(rColor.blueComponent*255)
+                let ra = Int(rColor.blueComponent*255)
+                
+                //                if (cColor.isEqual(to: rColor)) {
+                if (abs(cr - rr) <= compareDifValue &&
+                    abs(cg - rg) <= compareDifValue &&
+                    abs(cb - rb) <= compareDifValue &&
+                    abs(ca - ra) <= compareDifValue) {
+                    if bgColor != nil &&
+                        cColor.isEqual(to: bgColor) {
+                    }
+                }else {
+//                    NSLog("(\(cr),\(cg),\(cb),\(cr))=(\(rr),\(rg),\(rb),\(rr))")
+                    let addr = cWidth * 4 * y + x * 4
+                    
+                    var r = uint8(255)
+                    data!.replaceBytes(in: NSRange.init(location: addr+0, length: 1), withBytes: &r)
+                    var g = uint8(255 * rColor.greenComponent/2)
+                    data!.replaceBytes(in: NSRange.init(location: addr+1, length: 1), withBytes: &g)
+                    var b = uint8(255 * rColor.blueComponent/2)
+                    data!.replaceBytes(in: NSRange.init(location: addr+2, length: 1), withBytes: &b)
+                    var a = uint8(255 * rColor.alphaComponent * 0.7)
+                    data!.replaceBytes(in: NSRange.init(location: addr+3, length: 1), withBytes: &a)
+                }
+            }
+        }
+        
+        let cfData = CFDataCreate(kCFAllocatorDefault, data?.bytes, data!.length)
+        let dataProvider = CGDataProvider.init(data: cfData!)
+        
+        let colorSpace = CGColorSpaceCreateDeviceRGB()
+        let cgImage = CGImage.init(width: cWidth,
+                                   height: cHeight,
+                                   bitsPerComponent: 8,
+                                   bitsPerPixel: 8 * 4,
+                                   bytesPerRow: cWidth * 4,
+                                   space: colorSpace,
+                                   bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrderDefault.rawValue) ?? CGBitmapInfo.byteOrderDefault,
+                                   provider: dataProvider!,
+                                   decode: nil,
+                                   shouldInterpolate: true,
+                                   intent: CGColorRenderingIntent.defaultIntent)
+        
+        if nil != cgImage {
+            return NSImage.init(cgImage: cgImage!, size: NSSize.init(width: cWidth, height: cHeight))
+        }
+        
+        return nil
+    }
+}