Sfoglia il codice sorgente

综合优化 - 上一轮自测功能优化;

zhudongyong 2 anni fa
parent
commit
9818995d16

+ 18 - 5
KdanAutoTest/KdanAuto/Base.lproj/Main.storyboard

@@ -351,7 +351,7 @@
                                             <button toolTip="Replace refrence images for current file type" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l8v-HO-kqi">
                                                 <rect key="frame" x="422" y="464" width="96" height="32"/>
                                                 <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
-                                                <buttonCell key="cell" type="push" title="Replace" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="wpE-O5-DBX">
+                                                <buttonCell key="cell" type="push" title="更新对照图" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="wpE-O5-DBX">
                                                     <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                     <font key="font" metaFont="system"/>
                                                 </buttonCell>
@@ -458,9 +458,9 @@
                                 </connections>
                             </button>
                             <button verticalHuggingPriority="750" id="Scu-90-mL7">
-                                <rect key="frame" x="810" y="2" width="77" height="32"/>
+                                <rect key="frame" x="813" y="2" width="72" height="32"/>
                                 <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
-                                <buttonCell key="cell" type="push" title="More..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8SI-7D-XJg">
+                                <buttonCell key="cell" type="push" title="更多..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8SI-7D-XJg">
                                     <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                     <font key="font" metaFont="system"/>
                                 </buttonCell>
@@ -469,9 +469,9 @@
                                 </connections>
                             </button>
                             <button toolTip="Replace refrence images for all file type" verticalHuggingPriority="750" id="NYu-z2-pHZ">
-                                <rect key="frame" x="711" y="2" width="101" height="32"/>
+                                <rect key="frame" x="721" y="2" width="88" height="32"/>
                                 <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
-                                <buttonCell key="cell" type="push" title="Replace All" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nOD-cy-PsK">
+                                <buttonCell key="cell" type="push" title="全部更新" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nOD-cy-PsK">
                                     <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                     <font key="font" metaFont="system"/>
                                 </buttonCell>
@@ -479,11 +479,24 @@
                                     <action selector="relpaceAllAction:" target="XfG-lQ-9wD" id="xkx-u7-X4c"/>
                                 </connections>
                             </button>
+                            <button toolTip="Replace refrence images for all file type" verticalHuggingPriority="750" id="KSs-7p-lxT">
+                                <rect key="frame" x="631" y="2" width="88" height="32"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                <buttonCell key="cell" type="push" title="显示对照" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="hXm-vn-hip">
+                                    <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                    <font key="font" metaFont="system"/>
+                                </buttonCell>
+                                <connections>
+                                    <action selector="showCompareReportAction:" target="XfG-lQ-9wD" id="3LT-OL-5xV"/>
+                                </connections>
+                            </button>
                         </subviews>
                     </view>
                     <connections>
+                        <outlet property="advanceBtn" destination="Scu-90-mL7" id="Us3-Fn-XdE"/>
                         <outlet property="advanceView" destination="Kjq-VU-WrU" id="ecC-8J-SWn"/>
                         <outlet property="customView" destination="WFX-nZ-eg1" id="Qum-9S-ko1"/>
+                        <outlet property="exportReportBtn" destination="KSs-7p-lxT" id="1N0-GT-3nS"/>
                         <outlet property="itemsList" destination="4NA-ss-yPX" id="uIe-KN-SjY"/>
                         <outlet property="replaceAllBtn" destination="NYu-z2-pHZ" id="ad4-9q-UWw"/>
                         <outlet property="startBtn" destination="CUw-Wo-mUO" id="mGh-eH-Fbj"/>

+ 95 - 73
KdanAutoTest/KdanAuto/Class/AutoTestCase/AutoTest.swift

@@ -18,6 +18,7 @@ class AutoTest : NSObject, AutoTestProtocal {
     var _fileType : String = "RTF"
     var _type : String = "Others"
     var _extention : String = "rtf"
+    var _name : String = "对照测试"
     
     class func autoTestFor(_ fileType:NSString ,type:NSString) -> AutoTest? {
         let key = String(fileType) + "." + String(type)
@@ -41,14 +42,16 @@ class AutoTest : NSObject, AutoTestProtocal {
             
             let cType = cItem["Type"] as! NSString
             let cExtention = cItem["Extention"] as! NSString
+            let cName = cItem["Name"] as! NSString
             if (cType.isEqual(to: type)) {
-                let className = String((clsname )+"."+(cItem["Class"] as! String)) as! String
+                let className = String((clsname )+"."+(cItem["Class"] as! String))
                 let cl = NSClassFromString(className) as! AutoTest.Type
                 
                 let object = cl.shared()
-                object?._fileType = fileType as! String
+                object?._fileType = fileType as String
                 object?._type = String(cType)
                 object?._extention = String(cExtention)
+                object?._name = String(cName)
                 cacheObjects.setValue(object, forKey: key)
                 
                 return object
@@ -60,6 +63,7 @@ class AutoTest : NSObject, AutoTestProtocal {
         object?._fileType = fileType as String
         object?._type = String(cType)
         object?._extention = ""
+        object?._name = "对照测试"
         cacheObjects.setValue(object, forKey: key)
         
         return object
@@ -78,7 +82,7 @@ class AutoTest : NSObject, AutoTestProtocal {
     }
     
     func name() -> String {
-        return "对照测试"
+        return _name
     }
     
     func keys() -> NSArray {
@@ -138,6 +142,11 @@ class AutoTest : NSObject, AutoTestProtocal {
             let originDirectory = self.originFileDirectory()
             let resultDirectory = self.resultFileDirectory()
             
+            if (files.count > 0) {
+                try? FileManager.default.createDirectory(atPath: checkDirectory, withIntermediateDirectories: true);
+                try? FileManager.default.createDirectory(atPath: resultDirectory, withIntermediateDirectories: true);
+            }
+            
             var tDegree = Double(0);
             var tCount = Int(0)
             
@@ -177,40 +186,66 @@ class AutoTest : NSObject, AutoTestProtocal {
                         var subCount = Int(0)
                         
                         for item in items {
-                            let subFileName = item as! String
-                            let subResultPath = NSString(string: resultDirectory).appendingPathComponent(subFileName+"."+_extention)
-                            
-                            reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subFileName+".\(_extention)")\"快照生成中\n",
-                                                                                attributes:[.foregroundColor : NSColor.black]))
-                            let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
-                            let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
-                            
-                            
-                            let processThumbSemaphore = DispatchSemaphore(value: 0)
-                            var processSuccess = false
-                            let thumbnailQueue = DispatchQueue.global()
-                            thumbnailQueue.async {
-                                processSuccess = ProcessThumbnal.process(subResultPath, desPath: rComparePath, outputSize: CGSize.init(width: 2048, height: 2048))
+                            autoreleasepool {
+                                let subFileName = item as! String
+                                let subResultPath = NSString(string: resultDirectory).appendingPathComponent(subFileName+"."+_extention)
                                 
-                                if ( processSuccess &&
-                                     FileManager.default.fileExists(atPath: rComparePath)) {
+                                reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subFileName+".\(_extention)")\"快照生成中\n",
+                                                                                    attributes:[.foregroundColor : NSColor.black]))
+                                let rComparePath = NSString(string: resultDirectory).appendingPathComponent(subFileName+".jpg")
+                                let cComparePath = NSString(string: checkDirectory).appendingPathComponent(subFileName+".jpg")
+                                
+                                
+                                let processThumbSemaphore = DispatchSemaphore(value: 0)
+                                var processSuccess = false
+                                let thumbnailQueue = DispatchQueue.global()
+                                thumbnailQueue.async {
+                                    processSuccess = ProcessThumbnal.process(subResultPath, desPath: rComparePath, outputSize: CGSize.init(width: 2048, height: 2048))
                                     
-                                    var isDirectory = ObjCBool(false)
-                                    if FileManager.default.fileExists(atPath: rComparePath, isDirectory: &isDirectory) && isDirectory.boolValue {
-                                        // 单个文件生成批量快照目录情形
-                                        let subImages = try! FileManager.default.contentsOfDirectory(atPath: rComparePath)
-                                        for subImageName in subImages {
-                                            let pathCompotent = "/"+subImageName
-                                            let degree = ImageProcess.compareJPEG(String(rComparePath+pathCompotent), checkPath: String(cComparePath+pathCompotent), processCover: true)
+                                    if ( processSuccess &&
+                                         FileManager.default.fileExists(atPath: rComparePath)) {
+                                        
+                                        var isDirectory = ObjCBool(false)
+                                        if FileManager.default.fileExists(atPath: rComparePath, isDirectory: &isDirectory) && isDirectory.boolValue {
+                                            // 单个文件生成批量快照目录情形
+                                            let subImages = try! FileManager.default.contentsOfDirectory(atPath: rComparePath)
+                                            for subImageName in subImages {
+                                                let pathCompotent = "/"+subImageName
+                                                let degree = ImageProcess.compareJPEG(String(rComparePath+pathCompotent), checkPath: String(cComparePath+pathCompotent), processCover: true)
+                                                
+                                                
+                                                NSLog(String("文件夹,\(subFileName+".jpg"+pathCompotent)"))
+                                                
+                                                TestDegreeManager.shared().set(degree, fileType: self.fileType(), type: self.type(),
+                                                                               fileName: fileName, refFilePath: subFileName+".jpg"+pathCompotent)
+                                                
+                                                if degree == -1 {
+                                                    self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比失败,生成快照失败或无比对文件\n",
+                                                                                                             attributes:[.foregroundColor : NSColor.red]))
+                                                }else {
+                                                    var color = NSColor.black
+                                                    if fabs(degree-100.0) >= 0.01 {
+                                                        color = NSColor.red
+                                                    }
+                                                    subDegree += degree
+                                                    subCount += 1
+                                                    
+                                                    self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比完成,图像相似度 \(degree)%\n",
+                                                                                                             attributes:[.foregroundColor : color]))
+                                                }
+                                            }
+                                        }else {
+                                            // 单个文件生成单个快照文件情形
                                             
+                                            let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath, processCover: true)
                                             
-                                            NSLog(String("文件夹\(subFileName+".jpg"+pathCompotent)"))
+                                            NSLog(String("文件夹\(subFileName+".jpg")"))
                                             
                                             TestDegreeManager.shared().set(degree, fileType: self.fileType(), type: self.type(),
-                                                                           fileName: fileName, refFilePath: subFileName+".jpg"+pathCompotent)
+                                                                           fileName: fileName, refFilePath: subFileName+".jpg")
                                             
                                             if degree == -1 {
-                                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比失败,生成快照失败或无比对文件\n",
+                                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比失败,生成快照失败或无比对文件\n",
                                                                                                          attributes:[.foregroundColor : NSColor.red]))
                                             }else {
                                                 var color = NSColor.black
@@ -220,44 +255,19 @@ class AutoTest : NSObject, AutoTestProtocal {
                                                 subDegree += degree
                                                 subCount += 1
                                                 
-                                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath+pathCompotent)\"快照对比完成,图像相似度 \(degree)%\n",
+                                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比完成,图像相似度 \(degree)%\n",
                                                                                                          attributes:[.foregroundColor : color]))
                                             }
                                         }
                                     }else {
-                                        // 单个文件生成单个快照文件情形
-                                        
-                                        let degree = ImageProcess.compareJPEG(rComparePath, checkPath: cComparePath, processCover: true)
-                                        
-                                        NSLog(String("非文件夹\(subFileName+".jpg")"))
-                                        
-                                        TestDegreeManager.shared().set(degree, fileType: self.fileType(), type: self.type(),
-                                                                       fileName: fileName, refFilePath: subFileName+".jpg")
-                                        
-                                        if degree == -1 {
-                                            self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比失败,生成快照失败或无比对文件\n",
-                                                                                                     attributes:[.foregroundColor : NSColor.red]))
-                                        }else {
-                                            var color = NSColor.black
-                                            if fabs(degree-100.0) >= 0.01 {
-                                                color = NSColor.red
-                                            }
-                                            subDegree += degree
-                                            subCount += 1
-                                            
-                                            self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照对比完成,图像相似度 \(degree)%\n",
-                                                                                                     attributes:[.foregroundColor : color]))
-                                        }
+                                        self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照生成失败\n",
+                                                                                                 attributes:[.foregroundColor : NSColor.red]))
                                     }
-                                }else {
-                                    self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(subResultPath)\"快照生成失败\n",
-                                                                                        attributes:[.foregroundColor : NSColor.red]))
+                                    
+                                    processThumbSemaphore.signal()
                                 }
-                                
-                                processThumbSemaphore.signal()
+                                processThumbSemaphore.wait()
                             }
-                            processThumbSemaphore.wait()
-                            
                         }
                         
                         if subCount != 0 {
@@ -296,22 +306,24 @@ class AutoTest : NSObject, AutoTestProtocal {
         var success = false
         let convertQueue = DispatchQueue.global()
         convertQueue.async {
-            success = FileConverter.shared().converter(originPath, inDesPath: resultPath)
-            
-            // 修复转 PNG 实际图片为 JPG 问题, 导致无法匹配问题
-            if (NSArray(array: ["png", "PNG"]).contains(NSString(string: resultPath).pathExtension)) {
-                let items = FileManager.default.subpaths(atPath: resultPath)! as [String]
-                for item in items {
-                    if NSArray(array: ["jpg", "JPG"]).contains(NSString(string:item).pathExtension) {
-                        let path = NSString(string: resultPath).appendingPathComponent(item);
-                        
-                        try? FileManager.default.moveItem(atPath: path,
-                                                          toPath: NSString(string: path).deletingPathExtension+".png");
+            autoreleasepool {
+                success = FileConverter.shared().converter(originPath, inDesPath: resultPath)
+                
+                // 修复转 PNG 实际图片为 JPG 问题, 导致无法匹配问题
+                if (NSArray(array: ["png", "PNG"]).contains(NSString(string: resultPath).pathExtension)) {
+                    let items = FileManager.default.subpaths(atPath: resultPath)! as [String]
+                    for item in items {
+                        if NSArray(array: ["jpg", "JPG"]).contains(NSString(string:item).pathExtension) {
+                            let path = NSString(string: resultPath).appendingPathComponent(item);
+                            
+                            try? FileManager.default.moveItem(atPath: path,
+                                                              toPath: NSString(string: path).deletingPathExtension+".png");
+                        }
                     }
                 }
+                
+                convertSemaphore.signal()
             }
-            
-            convertSemaphore.signal()
         }
         convertSemaphore.wait()
         
@@ -673,3 +685,13 @@ extension AutoTest {
         return UInt8(0)
     }
 }
+
+
+extension AutoTest {
+    func isEqual(to object: AutoTest) -> Bool {
+        return (NSString(string: self.className).isEqual(to: object.className) &&
+                NSString(string: self.fileType()).isEqual(to: object.fileType()) &&
+                NSString(string: self.type()).isEqual(to: object.type()) &&
+                NSString(string: _extention).isEqual(to: object._extention))
+    }
+}

+ 65 - 0
KdanAutoTest/KdanAuto/Class/AutoTestCase/AutoTestProperty.plist

@@ -7,6 +7,8 @@
 		<dict>
 			<key>Type</key>
 			<string>Others</string>
+			<key>Name</key>
+			<string>命令行结果对比</string>
 			<key>Extention</key>
 			<string>pdf</string>
 			<key>Class</key>
@@ -20,6 +22,8 @@
 			<string>Fonts</string>
 			<key>Extention</key>
 			<string>rtf</string>
+			<key>Name</key>
+			<string>字体转换准确率测试</string>
 			<key>Class</key>
 			<string>FontAutoTest</string>
 		</dict>
@@ -28,6 +32,8 @@
 			<string>Colors</string>
 			<key>Extention</key>
 			<string>rtf</string>
+			<key>Name</key>
+			<string>字符颜色值转换测试</string>
 			<key>Class</key>
 			<string>TextColorAutoTest</string>
 		</dict>
@@ -36,6 +42,8 @@
 			<string>Characters</string>
 			<key>Extention</key>
 			<string>rtf</string>
+			<key>Name</key>
+			<string>字符转换准确率测试</string>
 			<key>Class</key>
 			<string>CharacterAutoTest</string>
 		</dict>
@@ -44,6 +52,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>rtf</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -53,6 +63,8 @@
 		<dict>
 			<key>Type</key>
 			<string>Others</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Extention</key>
 			<string>docx</string>
 			<key>Class</key>
@@ -66,6 +78,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>pptx</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -75,6 +89,8 @@
 		<dict>
 			<key>Type</key>
 			<string>Others</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Extention</key>
 			<string>xlsx</string>
 			<key>Class</key>
@@ -90,6 +106,22 @@
 			<string>csv</string>
 			<key>Class</key>
 			<string>AutoTest</string>
+			<key>Name</key>
+			<string>快照对比</string>
+			<key>Params</key>
+			<string></string>
+		</dict>
+		<dict>
+			<key>Type</key>
+			<string>合并导出</string>
+			<key>Name</key>
+			<string>合并导出快照对比</string>
+			<key>Extention</key>
+			<string>csv</string>
+			<key>Class</key>
+			<string>AutoTest</string>
+			<key>Params</key>
+			<string></string>
 		</dict>
 	</array>
 	<key>HTML</key>
@@ -97,6 +129,8 @@
 		<dict>
 			<key>Type</key>
 			<string>Others</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Extention</key>
 			<string>html</string>
 			<key>Class</key>
@@ -110,6 +144,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>txt</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -121,8 +157,25 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>jpg</string>
+			<key>Name</key>
+			<string>快照对比</string>
+			<key>Class</key>
+			<string>AutoTest</string>
+		</dict>
+		<dict>
+			<key>Type</key>
+			<string>DPI-300</string>
+			<key>Name</key>
+			<string>DPI-300 快照对比</string>
+			<key>Extention</key>
+			<string>jpg</string>
 			<key>Class</key>
 			<string>AutoTest</string>
+			<key>Params</key>
+			<dict>
+				<key>DPI</key>
+				<string>300</string>
+			</dict>
 		</dict>
 	</array>
 	<key>PNG</key>
@@ -132,6 +185,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>png</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -143,6 +198,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>gif</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -154,6 +211,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>tiff</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -165,6 +224,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>tga</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -176,6 +237,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>bmp</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>
@@ -187,6 +250,8 @@
 			<string>Others</string>
 			<key>Extention</key>
 			<string>jpg</string>
+			<key>Name</key>
+			<string>快照对比</string>
 			<key>Class</key>
 			<string>AutoTest</string>
 		</dict>

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

@@ -14,7 +14,7 @@ class FontAutoTest : AutoTest {
 //    }
     
     override func name() -> String {
-        return "字体转换准确率测试"
+        return _name
     }
     
     override func keys() -> NSArray {

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

@@ -15,7 +15,7 @@ class CharacterAutoTest : AutoTest {
 //    }
     
     override func name() -> String {
-        return "字符转换准确率测试"
+        return _name
     }
     
     override func keys() -> NSArray {
@@ -49,6 +49,11 @@ class CharacterAutoTest : AutoTest {
         let originDirectory = self.originFileDirectory()
         let resultDirectory = self.resultFileDirectory()
         
+        if (files.count > 0) {
+            try? FileManager.default.createDirectory(atPath: checkDirectory, withIntermediateDirectories: true);
+            try? FileManager.default.createDirectory(atPath: resultDirectory, withIntermediateDirectories: true);
+        }
+        
         var tDegree = Double(0);
         var tCount = Int(0)
         

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

@@ -15,7 +15,7 @@ class TextColorAutoTest : AutoTest {
 //    }
     
     override func name() -> String {
-        return "字符颜色值转换测试"
+        return _name
     }
     
     override func keys() -> NSArray {
@@ -69,6 +69,11 @@ class TextColorAutoTest : AutoTest {
         let originDirectory = self.originFileDirectory()
         let resultDirectory = self.resultFileDirectory()
         
+        if (files.count > 0) {
+            try? FileManager.default.createDirectory(atPath: checkDirectory, withIntermediateDirectories: true);
+            try? FileManager.default.createDirectory(atPath: resultDirectory, withIntermediateDirectories: true);
+        }
+        
         var tDegree = Double(0);
         var tCount = Int(0)
         

+ 120 - 45
KdanAutoTest/KdanAuto/Class/CompareViewController/CompareViewController.swift

@@ -13,7 +13,12 @@ class CompareViewController: NSViewController, NSTableViewDataSource, NSTableVie
     
     @IBOutlet var listView : NSTableView!
     
+    @IBOutlet var filterBtn : NSButton!
+    
+    @IBOutlet var progressIndicator : NSProgressIndicator!
+    
     var _files : NSArray!
+    var _showFiles : NSMutableArray!
     var _popover: NSPopover!
     
     static var sharedCViewController : CompareViewController? = nil
@@ -34,72 +39,122 @@ class CompareViewController: NSViewController, NSTableViewDataSource, NSTableVie
     }
     
     // IBAction
+    @IBAction func filterSimilarItemAction(_ sender:NSButton) {
+        self.setFiles(_files);
+    }
+    
     @IBAction func exportAction(_ sender:NSButton) {
+        if (_files.count == 0) {
+            let alert = NSAlert.init()
+            alert.messageText = "无测试对比项导出";
+            alert.runModal();
+            
+            return
+        }else if (_showFiles.count == 0) {
+            let alert = NSAlert.init()
+            alert.messageText = "所有对比项均无差异";
+            alert.runModal();
+            
+            return
+        }
+        
         let savePanel = NSSavePanel.init();
         let checkBox = NSButton(checkboxWithTitle: "过滤无差异项", target: self, action: nil);
+        checkBox.state = self.filterBtn.state;
         checkBox.frame = CGRectMake(0, 0, 150, 45);
         
         savePanel.allowedContentTypes = [.pdf]
         savePanel.accessoryView = checkBox
         
         if (savePanel.runModal() == .OK) {
+            var exportFiles = NSMutableArray()
+            
+            if (checkBox.state == .on) {
+                
+                for tfile in _files {
+                    let file = tfile as! NSMutableDictionary;
+                    
+                    let degree = file.degree()
+                    if (fabs(degree - 100) > 0) {
+                        exportFiles.add(file);
+                    }
+                }
+                if (exportFiles.count == 0) {
+                    let alert = NSAlert.init()
+                    alert.messageText = "所有对比项均无差异";
+                    alert.runModal();
+                    
+                    return
+                }
+            }else {
+                exportFiles = NSMutableArray(array: _files)
+            }
+            
             let url = savePanel.url!;
             NSLog("\(url)")
             let pdf = PDFDocument.init();
             let needFilter = checkBox.state == .on
             
-            processNextImages(pdf, index: 0, url: url, needFilter: needFilter)
+            self.progressIndicator.isHidden = false;
+            self.progressIndicator.doubleValue = 0;
+            processNextImages(pdf, index: 0, files:exportFiles, url: url, needFilter: needFilter)
         }
     }
     
     // Save PDF
-    func processNextImages(_ pdf:PDFDocument, index:Int32, url:URL, needFilter:Bool) -> Void {
-        let file = _files[0] as! NSMutableDictionary
+    func processNextImages(_ pdf:PDFDocument, index:Int32, files:NSMutableArray, url:URL, needFilter:Bool) -> Void {
+        let file = files[Int(index)] as! NSMutableDictionary
         
         NSLog("处理第\(index)页")
-        if (!needFilter) {
-            let cell = ImageCompareCellView.shared()
-            cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900);
-            cell?.setFileInfo(file);
-            
-            let image = cell?.processCompareImage()
-            if (image != nil) {
-                let page = PDFPage.init(image: image!)
-                let nPage = page?.copy() as! PDFPage
-                pdf.insert(nPage, at: pdf.pageCount)
-            }
-            
-            let degree = file.degree()
-            if (abs(degree - 100) > 0) {
-                let image = cell?.processCoverImage()
+        
+        // 所有文档均导出
+        let cell = ImageCompareCellView.shared()
+        cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900);
+        cell?.setFileInfo(file);
+        
+        DispatchQueue.global().async {
+            autoreleasepool {
+                let image = cell?.processCompareImage()
                 if (image != nil) {
                     let page = PDFPage.init(image: image!)
                     let nPage = page?.copy() as! PDFPage
                     pdf.insert(nPage, at: pdf.pageCount)
                 }
             }
-        }else {
-            let cell = ImageCompareCellView.shared()
-            cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900);
-            cell?.setFileInfo(file);
+            
             
             let degree = file.degree()
             if (abs(degree - 100) > 0) {
-                let image = cell?.processCoverImage()
-                if (image != nil) {
-                    let page = PDFPage.init(image: image!)
-                    let nPage = page?.copy() as! PDFPage
-                    pdf.insert(nPage, at: pdf.pageCount)
+                autoreleasepool {
+                    let image = cell?.processCoverImage()
+                    if (image != nil) {
+                        let page = PDFPage.init(image: image!)
+                        let nPage = page?.copy() as! PDFPage
+                        pdf.insert(nPage, at: pdf.pageCount)
+                    }
+                }
+            }
+            
+            if ((index+1) < files.count) {
+                DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) {
+                    
+                    self.progressIndicator.doubleValue = Double(Int(index) * 100/files.count);
+                    self.processNextImages(pdf, index: index+1, files: files, url: url, needFilter: needFilter);
+                };
+            }else {
+                DispatchQueue.global().async {
+                    autoreleasepool {
+                        pdf.write(to: url)
+                        
+                        DispatchQueue.main.async {
+                            self.progressIndicator.isHidden = true;
+                            self.progressIndicator.doubleValue = 100.0;
+                            
+                            NSWorkspace.shared.activateFileViewerSelecting([url])
+                        }
+                    }
                 }
             }
-        }
-        
-        if ((index+1) < _files.count) {
-            DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) {
-                self.processNextImages(pdf, index: index+1, url: url, needFilter: needFilter);
-            };
-        }else {
-            pdf.write(to: url);
         }
     }
     
@@ -121,6 +176,21 @@ class CompareViewController: NSViewController, NSTableViewDataSource, NSTableVie
     func setFiles(_ files:NSArray) {
         _files = files
         
+        if (self.filterBtn.state == .on) {
+            _showFiles = NSMutableArray()
+            
+            for tfile in _files {
+                let file = tfile as! NSMutableDictionary;
+                
+                let degree = file.degree()
+                if (fabs(degree - 100) > 0) {
+                    _showFiles.add(file);
+                }
+            }
+        }else {
+            _showFiles = NSMutableArray (array: _files);
+        }
+        
         listView.reloadData()
     }
     
@@ -133,15 +203,20 @@ class CompareViewController: NSViewController, NSTableViewDataSource, NSTableVie
     
     // TableView Delegate
     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
-        let cellView = ImageCompareCellView.shared()
-        
-        if (_files.count >= row) {
-            let fileInfo = _files[row] as! NSMutableDictionary
-
-            cellView?.setFileInfo(fileInfo)
+        return autoreleasepool {
+            var cellView = tableView.makeView(withIdentifier: .init("ImageCompareCellView"), owner: nil) as! ImageCompareCellView?
+            if (nil != cellView) {
+                cellView = ImageCompareCellView.shared() ?? nil
+            }
+            
+            if (_showFiles.count >= row) {
+                let fileInfo = _showFiles[row] as! NSMutableDictionary
+                
+                cellView?.setFileInfo(fileInfo)
+            }
+            
+            return cellView
         }
-        
-        return cellView
     }
     
     func selectionShouldChange(in tableView: NSTableView) -> Bool {
@@ -193,11 +268,11 @@ class CompareViewController: NSViewController, NSTableViewDataSource, NSTableVie
     
     // TableView Data Source
     func numberOfRows(in tableView: NSTableView) -> Int {
-        if nil == _files {
+        if nil == _showFiles {
             return 0
         }
         
-        return _files.count
+        return _showFiles.count
     }
     
     //

+ 18 - 1
KdanAutoTest/KdanAuto/Class/CompareViewController/CompareViewController.xib

@@ -11,7 +11,9 @@
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
         <viewController id="YBj-nQ-WgX" customClass="CompareViewController" customModule="KdanAuto" customModuleProvider="target">
             <connections>
+                <outlet property="filterBtn" destination="qCC-xr-5ZS" id="Q7X-Ey-WUr"/>
                 <outlet property="listView" destination="45n-iP-sYg" id="FnW-Nj-Hop"/>
+                <outlet property="progressIndicator" destination="865-rk-Lp5" id="9x5-cL-1Ca"/>
                 <outlet property="view" destination="cCo-Bc-PDG" id="UFV-zt-z4Q"/>
             </connections>
         </viewController>
@@ -93,7 +95,7 @@
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
                 </scrollView>
-                <button verticalHuggingPriority="750" fixedFrame="YES" id="dci-WZ-4sM">
+                <button verticalHuggingPriority="750" id="dci-WZ-4sM">
                     <rect key="frame" x="926" y="918" width="74" height="32"/>
                     <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
                     <buttonCell key="cell" type="push" title="Export" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="xfM-sn-1wh">
@@ -104,6 +106,21 @@
                         <action selector="exportAction:" target="YBj-nQ-WgX" id="wx5-cS-nds"/>
                     </connections>
                 </button>
+                <button verticalHuggingPriority="750" id="qCC-xr-5ZS">
+                    <rect key="frame" x="819" y="926" width="106" height="18"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                    <buttonCell key="cell" type="check" title="过滤无差异项" bezelStyle="regularSquare" imagePosition="left" inset="2" id="7qM-Dj-di2">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                    <connections>
+                        <action selector="filterSimilarItemAction:" target="YBj-nQ-WgX" id="RbW-XC-vmp"/>
+                    </connections>
+                </button>
+                <progressIndicator hidden="YES" fixedFrame="YES" maxValue="100" doubleValue="50" style="bar" id="865-rk-Lp5">
+                    <rect key="frame" x="709" y="925" width="100" height="20"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                </progressIndicator>
             </subviews>
             <point key="canvasLocation" x="-213" y="678"/>
         </customView>

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

@@ -47,6 +47,13 @@ class ImageCompareCellView : NSTableCellView {
     override func awakeFromNib() {
         _sepLine.wantsLayer = true;
         _sepLine.layer?.backgroundColor = NSColor.lightGray.cgColor
+        
+        _imageView01.wantsLayer = true;
+        _imageView02.wantsLayer = true;
+        _imageView01.layer?.borderColor = NSColor.lightGray.cgColor;
+        _imageView02.layer?.borderColor = NSColor.lightGray.cgColor;
+        _imageView01.layer?.borderWidth = 0.5;
+        _imageView02.layer?.borderWidth = 0.5;
     }
     
     // Setter & Getter
@@ -64,33 +71,42 @@ class ImageCompareCellView : NSTableCellView {
         _fileInfo = fileInfo;
         
         if nil != _fileInfo {
-            let comparePath = _fileInfo.comparePath()
-            let resultPath = _fileInfo.resultPath()
-            
-            let image = NSImage.init(contentsOfFile: comparePath)
-            _imageView01.image = image;
-            
-            let image2 = NSImage.init(contentsOfFile: resultPath)
-            _imageView02.image = image2;
-            
-            if (nil == _fileInfo.refFilePath()) {
-                setTitle(String("[\(_fileInfo.objc().fileType()):\(_fileInfo.objc().name())]\(_fileInfo.fileName())"))
-            }else {
-                let lastPathComponent = NSString(string: _fileInfo.refFilePath()!).lastPathComponent
-                setTitle(String("[\(_fileInfo.objc().fileType()):\(_fileInfo.objc().name())]\(_fileInfo.fileName())/\(lastPathComponent)"))
-            }
-            
-            let degree = _fileInfo.degree()
-            if degree == -1 {
-                _degreeInfoLbl.stringValue = "文件不存在"
-                _degreeInfoLbl.textColor = NSColor.red
-            } else {
-                if abs(degree - 100) > 0 {
-                    _degreeInfoLbl.textColor = NSColor.red
+            autoreleasepool {
+                let comparePath = _fileInfo.comparePath()
+                let resultPath = _fileInfo.resultPath()
+                
+                DispatchQueue.global().async {
+                    let image = NSImage.init(contentsOfFile: comparePath)
+                    
+                    let image2 = NSImage.init(contentsOfFile: resultPath)
+                    
+                    DispatchQueue.main.async {
+                        autoreleasepool {
+                            self._imageView01.image = image;
+                            self._imageView02.image = image2;
+                        }
+                    }
+                }
+                
+                if (nil == _fileInfo.refFilePath()) {
+                    setTitle(String("[\(_fileInfo.objc().fileType()):\(_fileInfo.objc().name())]\(_fileInfo.fileName())"))
                 }else {
-                    _degreeInfoLbl.textColor = NSColor.blue
+                    let lastPathComponent = NSString(string: _fileInfo.refFilePath()!).lastPathComponent
+                    setTitle(String("[\(_fileInfo.objc().fileType()):\(_fileInfo.objc().name())]\(_fileInfo.fileName())/\(lastPathComponent)"))
+                }
+                
+                let degree = _fileInfo.degree()
+                if degree == -1 {
+                    _degreeInfoLbl.stringValue = "文件不存在"
+                    _degreeInfoLbl.textColor = NSColor.red
+                } else {
+                    if abs(degree - 100) > 0 {
+                        _degreeInfoLbl.textColor = NSColor.red
+                    }else {
+                        _degreeInfoLbl.textColor = NSColor.blue
+                    }
+                    _degreeInfoLbl.stringValue = NSString(format: "相似度:%.2f%%", degree) as String
                 }
-                _degreeInfoLbl.stringValue = NSString(format: "相似度:%.2f%%", degree) as String
             }
         }else {
             setTitle("")
@@ -121,60 +137,68 @@ class ImageCompareCellView : NSTableCellView {
         
         _showCoverBtn.isHidden = sender.indexOfSelectedItem == 0
         if sender.indexOfSelectedItem == 0 {
-            _imageView03.image = nil;
-            _imageView04.image = nil;
-            
-            let comparePath = _fileInfo.comparePath()
-            let resultPath = _fileInfo.resultPath()
-            
-            let image = NSImage.init(contentsOfFile: comparePath)
-            _imageView01.image = image;
-            
-            let image2 = NSImage.init(contentsOfFile: resultPath)
-            _imageView02.image = image2;
+            autoreleasepool {
+                _imageView03.image = nil;
+                _imageView04.image = nil;
+                
+                let comparePath = _fileInfo.comparePath()
+                let resultPath = _fileInfo.resultPath()
+                
+                let image = NSImage.init(contentsOfFile: comparePath)
+                _imageView01.image = image;
+                
+                let image2 = NSImage.init(contentsOfFile: resultPath)
+                _imageView02.image = image2;
+            }
         }else {
-            _imageView01.image = nil;
-            _imageView02.image = nil;
-            _showCoverBtn.state = .on
-            
-            let comparePath = _fileInfo.comparePath()
-            let resultPath = _fileInfo.resultPath()
-            
-            
-            let image = NSImage.init(contentsOfFile: comparePath)
-            _imageView03.image = image;
-            self._imageView04.image = nil;
-            _imageView04.isHidden = _showCoverBtn.state == .off || _segmentedControl.indexOfSelectedItem != 1
-            
-            //            let image2 = NSImage.init(contentsOfFile: resultPath)
-            //            _imageView04.image = image2;
-            let degree = _fileInfo.degree()
-            if (abs(degree - 100) > 0) {
-                _activityView.isHidden = false
-                _activityView.startAnimation(sender)
-                DispatchQueue.global().async {
-                    var image2 = nil as NSImage?
-                    
-                    let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
-                    
-                    if FileManager.default.fileExists(atPath: coverPath) {
-                        image2 = NSImage.init(contentsOfFile: coverPath)
-                    }else {
-                        image2 = ImageProcess.processImage(resultPath, checkPath: comparePath)
+            autoreleasepool {
+                _imageView01.image = nil;
+                _imageView02.image = nil;
+                _showCoverBtn.state = .on
+                
+                let comparePath = _fileInfo.comparePath()
+                let resultPath = _fileInfo.resultPath()
+                
+                
+                let image = NSImage.init(contentsOfFile: comparePath)
+                _imageView03.image = image;
+                self._imageView04.image = nil;
+                _imageView04.isHidden = _showCoverBtn.state == .off || _segmentedControl.indexOfSelectedItem != 1
+                
+                //            let image2 = NSImage.init(contentsOfFile: resultPath)
+                //            _imageView04.image = image2;
+                let degree = _fileInfo.degree()
+                if (abs(degree - 100) > 0) {
+                    _activityView.isHidden = false
+                    _activityView.startAnimation(sender)
+                    DispatchQueue.global().async {
+                        var image2 = nil as NSImage?
                         
-                        if nil != image2 {
-                            let rep = NSBitmapImageRep.init(cgImage: image2!.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-                            let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                        autoreleasepool {
+                            let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
                             
-                            let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
-                            try? data!.write(to: url)
+                            if FileManager.default.fileExists(atPath: coverPath) {
+                                image2 = NSImage.init(contentsOfFile: coverPath)
+                            }else {
+                                image2 = ImageProcess.processImage(resultPath, checkPath: comparePath)
+                                
+                                if nil != image2 {
+                                    let rep = NSBitmapImageRep.init(cgImage: image2!.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+                                    let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                                    
+                                    let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
+                                    try? data!.write(to: url)
+                                }
+                            }
+                        }
+                        
+                        DispatchQueue.main.sync {
+                            autoreleasepool {
+                                self._imageView04.image = image2
+                                self._activityView.isHidden = true
+                                self._activityView.stopAnimation(sender)
+                            }
                         }
-                    }
-                    
-                    DispatchQueue.main.sync {
-                        self._imageView04.image = image2
-                        self._activityView.isHidden = true
-                        self._activityView.stopAnimation(sender)
                     }
                 }
             }
@@ -185,64 +209,75 @@ class ImageCompareCellView : NSTableCellView {
         _imageView03.image = nil;
         _imageView04.image = nil;
         
-        let comparePath = _fileInfo.comparePath()
-        let resultPath = _fileInfo.resultPath()
-        
-        let image = NSImage.init(contentsOfFile: comparePath)
-        _imageView01.image = image;
-        
-        let image2 = NSImage.init(contentsOfFile: resultPath)
-        _imageView02.image = image2;
-        
-        _showCoverBtn.isHidden = true;
-        _segmentedControl.isHidden = true;
-        _degreeInfoLbl.isHidden = true;
-        
-        let nimage = self.imageFroView(self)
-        return nimage
+        return autoreleasepool {
+            let comparePath = _fileInfo.comparePath()
+            let resultPath = _fileInfo.resultPath()
+            
+            let image = NSImage.init(contentsOfFile: comparePath)
+            _imageView01.image = image;
+            
+            let image2 = NSImage.init(contentsOfFile: resultPath)
+            _imageView02.image = image2;
+            
+            _showCoverBtn.isHidden = true;
+            _segmentedControl.isHidden = true;
+            _degreeInfoLbl.isHidden = true;
+            
+            let nimage = self.imageFroView(self)
+            return nimage
+        }
     }
     
     func processCoverImage() -> NSImage? {
-        let comparePath = _fileInfo.comparePath()
-        let resultPath = _fileInfo.resultPath()
-        
-        let image = NSImage.init(contentsOfFile: comparePath)
-        _imageView03.image = image;
-        self._imageView04.image = nil;
-        _imageView04.isHidden = false
-        
-        var image2 = nil as NSImage?
+        _imageView01.image = nil;
+        _imageView02.image = nil;
         
-        let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
-        
-        if FileManager.default.fileExists(atPath: coverPath) {
-            image2 = NSImage.init(contentsOfFile: coverPath)
-        }else {
-            image2 = ImageProcess.processImage(resultPath, checkPath: comparePath)
+        return autoreleasepool {
+            let comparePath = _fileInfo.comparePath()
+            let resultPath = _fileInfo.resultPath()
+            
+            let image = NSImage.init(contentsOfFile: comparePath)
+            _imageView03.image = image;
+            self._imageView04.image = nil;
+            _imageView04.isHidden = false
+            
+            var image2 = nil as NSImage?
             
-            if nil != image2 {
-                let rep = NSBitmapImageRep.init(cgImage: image2!.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-                let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+            let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
+            
+            if FileManager.default.fileExists(atPath: coverPath) {
+                image2 = NSImage.init(contentsOfFile: coverPath)
+            }else {
+                image2 = ImageProcess.processImage(resultPath, checkPath: comparePath)
                 
-                let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
-                try? data!.write(to: url)
+                if nil != image2 {
+                    let rep = NSBitmapImageRep.init(cgImage: image2!.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+                    let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                    
+                    let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
+                    try? data!.write(to: url)
+                }
             }
+            
+            self._imageView04.image = image2
+            self._activityView.isHidden = true
+            
+            self._showCoverBtn.isHidden = true;
+            self._segmentedControl.isHidden = true;
+            self._degreeInfoLbl.isHidden = true;
+            
+            let nimage = self.imageFroView(self)
+            return nimage
         }
-        
-        self._imageView04.image = image2
-        self._activityView.isHidden = true
-        
-        self._showCoverBtn.isHidden = true;
-        self._segmentedControl.isHidden = true;
-        self._degreeInfoLbl.isHidden = true;
-        
-        let nimage = self.imageFroView(self)
-        return nimage
     }
     
     func imageFroView(_ view:NSView) -> NSImage? {
-        let data = view.dataWithPDF(inside: view.frame)
-        let image = NSImage.init(data: data);
+        var image = nil as NSImage?;
+        
+        autoreleasepool {
+            let data = view.dataWithPDF(inside: view.frame)
+            image = NSImage.init(data: data);
+        }
         
         return image ?? nil;
     }

+ 1 - 1
KdanAutoTest/KdanAuto/Class/CompareViewController/ImageCompareCellView.xib

@@ -9,7 +9,7 @@
         <customObject id="-2" userLabel="File's Owner"/>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <tableCellView id="Ob6-j8-aNh" customClass="ImageCompareCellView" customModule="KdanAuto" customModuleProvider="target">
+        <tableCellView identifier="ImageCompareCellView" id="Ob6-j8-aNh" customClass="ImageCompareCellView" customModule="KdanAuto" customModuleProvider="target">
             <rect key="frame" x="0.0" y="0.0" width="1000" height="800"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>

+ 11 - 1
KdanAutoTest/KdanAuto/Class/Norrmal/AutoTestAdvanceSettingView.swift

@@ -67,6 +67,10 @@ class AutoTestAdvanceSettingView : NSView, NSTableViewDataSource, NSTableViewDel
     
     // Setter
     let kCheckBtnDefaultHeight = 25.0
+    public func getAutoTestObj() -> AutoTest? {
+        return _autoTestObj
+    }
+    
     public func setAutoTestObj(_ obj:AutoTest?) {
         _autoTestObj = obj;
         
@@ -76,7 +80,7 @@ class AutoTestAdvanceSettingView : NSView, NSTableViewDataSource, NSTableViewDel
         
         _addBtn.isHidden = nil == _autoTestObj;
         if nil != _autoTestObj {
-            _titleLbl.stringValue = String("[\(_autoTestObj?.fileType() as! String)]\(_autoTestObj?.name() as! String)")
+            _titleLbl.stringValue = String("[\(_autoTestObj?.fileType())]\(_autoTestObj?.name())")
             let checkKeys = _autoTestObj?.keys() as! NSArray
             let selectKeys = _autoTestObj?.selectedKeys() as! NSArray
             
@@ -179,6 +183,9 @@ class AutoTestAdvanceSettingView : NSView, NSTableViewDataSource, NSTableViewDel
         if nil != _autoTestObj {
             _autoTestObj?.updateRefImage()
         }
+        _fileList.reloadData();
+        
+        _replaceAllBtn.isEnabled = _autoTestObj!.canUpdateRefImage()
     }
     
     @IBAction func addFileAction(_ sender:NSButton) {
@@ -394,6 +401,9 @@ class AutoTestAdvanceSettingView : NSView, NSTableViewDataSource, NSTableViewDel
         if (_autoTestObj != nil) {
             _autoTestObj?.updateRefImage(fileName)
         }
+        
+        _replaceAllBtn.isEnabled = _autoTestObj!.canUpdateRefImage()
+        
         _fileList.reloadData()
     }
     

+ 8 - 8
KdanAutoTest/KdanAuto/Class/Norrmal/Cell/TestFileCellView.xib

@@ -13,9 +13,9 @@
             <rect key="frame" x="0.0" y="0.0" width="339" height="30"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EgA-BQ-X23">
-                    <rect key="frame" x="-2" y="9" width="335" height="16"/>
-                    <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="EgA-BQ-X23">
+                    <rect key="frame" x="-2" y="9" width="219" height="16"/>
+                    <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
                     <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="4yb-fM-clL">
                         <font key="font" metaFont="smallSystem"/>
                         <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@@ -27,22 +27,22 @@
                     <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
                 </customView>
                 <button verticalHuggingPriority="750" id="1iY-9V-oMo">
-                    <rect key="frame" x="227" y="-2" width="61" height="32"/>
+                    <rect key="frame" x="204" y="-2" width="96" height="32"/>
                     <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
-                    <buttonCell key="cell" type="push" title="替换" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fG4-an-Nhx">
+                    <buttonCell key="cell" type="push" title="更新对照图" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fG4-an-Nhx">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
+                        <font key="font" metaFont="cellTitle"/>
                     </buttonCell>
                     <connections>
                         <action selector="replaceAction:" target="Ob6-j8-aNh" id="Biy-Jl-sf8"/>
                     </connections>
                 </button>
                 <button verticalHuggingPriority="750" id="k7x-WS-SBq">
-                    <rect key="frame" x="285" y="-1" width="54" height="32"/>
+                    <rect key="frame" x="291" y="-1" width="48" height="32"/>
                     <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
                     <buttonCell key="cell" type="bevel" title="100%" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="3nC-F1-RVr">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
+                        <font key="font" metaFont="smallSystem"/>
                     </buttonCell>
                     <connections>
                         <action selector="showReportAction:" target="Ob6-j8-aNh" id="m1v-7B-LUA"/>

+ 44 - 38
KdanAutoTest/KdanAuto/Class/Tools/FileConveter/FileConverter.swift

@@ -129,15 +129,17 @@ class FileConverter : NSObject, CPDFConverterDelegate, CPDFConverterFPDelegate {
                 //                let allInOneSheetKey = String(CPDFConvertOptionsKey.allInOneSheet)
                 
                 //            Task.init {
-                self.fpConverter?.convertPDF(atPath: self.srcPath,
-                                             pdfPassword: nil,
-                                             pdfPageIndexs: self.pages,
-                                             destDocType: self.pathExtension,
-                                             destDocPath: self.desPath,
-                                             moreOptions: [
-                                                "KMPDFConvertOptionsKeyImageDPI" : "72",
-                                                "CPDFConvertOptionsKeyAllInOneSheet":NSNumber(booleanLiteral: needMerge)
-                                             ])
+                autoreleasepool {
+                    self.fpConverter?.convertPDF(atPath: self.srcPath,
+                                                 pdfPassword: nil,
+                                                 pdfPageIndexs: self.pages,
+                                                 destDocType: self.pathExtension,
+                                                 destDocPath: self.desPath,
+                                                 moreOptions: [
+                                                    "KMPDFConvertOptionsKeyImageDPI" : "72",
+                                                    "CPDFConvertOptionsKeyAllInOneSheet":NSNumber(booleanLiteral: needMerge)
+                                                 ])
+                }
                 //            }
                 //            }
             }
@@ -157,26 +159,28 @@ class FileConverter : NSObject, CPDFConverterDelegate, CPDFConverterFPDelegate {
     func converter(_ converter: CPDFConverter!, didEndConvert error: Error!) {
         didSuccess = nil == error
         
-        sleep(2)
-        
-        let cachePath = NSString(string: self.desPath).deletingPathExtension+".zip"
-//        try? FileManager.default.createDirectory(atPath: self.desPath, withIntermediateDirectories: true)
-        
-        let zip = ZipArchive.init()
-        
-        zip.unzipOpenFile(cachePath)
-        zip.unzipFile(to: self.desPath, overWrite: true)
-        
-        try? FileManager.default.removeItem(atPath: cachePath)
-        
-        sleep(1)
-        
-        if self.pdfConverter?.isConverting == true {
-            self.pdfConverter?.cancel()
+        autoreleasepool {
+            sleep(2)
+            
+            let cachePath = NSString(string: self.desPath).deletingPathExtension+".zip"
+            //        try? FileManager.default.createDirectory(atPath: self.desPath, withIntermediateDirectories: true)
+            
+            let zip = ZipArchive.init()
+            
+            zip.unzipOpenFile(cachePath)
+            zip.unzipFile(to: self.desPath, overWrite: true)
+            
+            try? FileManager.default.removeItem(atPath: cachePath)
+            
+            sleep(1)
+            
+            if self.pdfConverter?.isConverting == true {
+                self.pdfConverter?.cancel()
+            }
+            self.pdfConverter?.delegate = nil
+            self.pdfConverter = nil
+            semaphore?.signal()
         }
-        self.pdfConverter?.delegate = nil
-        self.pdfConverter = nil
-        semaphore?.signal()
     }
     
     func converter(_ converter: CPDFConverter!, pageIndex index: UInt, pageCount count: UInt) {
@@ -185,16 +189,18 @@ class FileConverter : NSObject, CPDFConverterDelegate, CPDFConverterFPDelegate {
     
     /// CPDFConverterFPDelegate
     func fppdfConverter(_ converter: Any!, didEndConversion error: Error!) {
-        didSuccess = nil == error
-        self.fpConverter?.stopConvertsionIfNeed()
-        
-        sleep(2)
-        
-//        self.fpConverter?.stopConvertsionIfNeed()
-//        self.fpConverter?.setDelegate(nil)
-//        self.fpConverter = nil
-//        
-        semaphore?.signal()
+        autoreleasepool {
+            didSuccess = nil == error
+            self.fpConverter?.stopConvertsionIfNeed()
+            
+            sleep(2)
+            
+            //        self.fpConverter?.stopConvertsionIfNeed()
+            //        self.fpConverter?.setDelegate(nil)
+            //        self.fpConverter = nil
+            //
+            semaphore?.signal()
+        }
     }
     
 }

+ 261 - 253
KdanAutoTest/KdanAuto/Class/Tools/ImageProcess/ImageProcess.swift

@@ -12,289 +12,297 @@ class ImageProcess : NSObject {
     
     //  Image compare
     class func compareJPEG(_ resultPath:String, checkPath:String, processCover:Bool) -> 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
+        autoreleasepool {
+            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!
+            let checkImage = cImage!
+            
+            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
                     
-                    markInfo[color] = NSNumber.init(value: count + 1)
-                }else {
-                    markInfo[color] = NSNumber.init(value: 1)
+                    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
+            var maxCount = Int(0);
+            var bgColor : NSColor = NSColor.clear
+            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)"))
-        }
-        
-        let data = NSMutableData.init(length: cWidth * cHeight * 4)
-        // 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 nil != bgColor {
+                NSLog(String("识别到背景色\(bgColor)"))
+            }
+            
+            let bg_r = Int(bgColor.redComponent*255);
+            let bg_g = Int(bgColor.redComponent*255);
+            let bg_b = Int(bgColor.redComponent*255);
+            let bg_a = Int(bgColor.redComponent*255);
+            
+            let data = NSMutableData.init(length: cWidth * cHeight * 4)
+            // 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)
                 
-//                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
+                for h in 0...maxHeight {
+                    let y = Int(h)
                     
-                    if bgColor != nil &&
-                        cColor.isEqual(to: bgColor) {
-                        bgCount += 1
-                    }
-                }else if (processCover && nil != data){
-                    let addr = cWidth * 4 * y + x * 4
+                    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)
                     
-                    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)
+                    //                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 cColor.isEqual(to: bgColor) {
+                            bgCount += 1
+                        }
+                    }else if (processCover && nil != data){
+                        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 outDegree = Double(max(equalCount-bgCount, 1)/(max(Double(cWidth) * Double(cHeight)-bgCount, 1)) * 100.0)
-        if (abs(outDegree - 100) > 0 && processCover && nil != data) {
-            DispatchQueue.global().async {
-                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 {
-                    let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
-                    let rep = NSBitmapImageRep.init(cgImage: cgImage!)
+            
+            let outDegree = Double(max(equalCount-bgCount, 1)/(max(Double(cWidth) * Double(cHeight)-bgCount, 1)) * 100.0)
+            if (abs(outDegree - 100) > 0 && processCover && nil != data) {
+                DispatchQueue.global().async {
+                    let cfData = CFDataCreate(kCFAllocatorDefault, data?.bytes, data!.length)
+                    let dataProvider = CGDataProvider.init(data: cfData!)
                     
-                    if let saveData = rep.representation(using: .png, properties: [:]) {
-                        let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
-                        try? saveData.write(to: url)
+                    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 {
+                        let coverPath = NSString(format: "%@_cover.png", NSString(string: resultPath).deletingPathExtension) as! String
+                        let rep = NSBitmapImageRep.init(cgImage: cgImage!)
+                        
+                        if let saveData = rep.representation(using: .png, properties: [:]) {
+                            let url = URL.init(fileURLWithPath: coverPath, isDirectory: false)
+                            try? saveData.write(to: url)
+                        }
                     }
                 }
             }
+            
+            NSLog(String("过滤点数目\(bgCount)"))
+            
+            return outDegree
         }
-        
-        NSLog(String("过滤点数目\(bgCount)"))
-        
-        return outDegree
     }
     
     //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
+        autoreleasepool {
+            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
                     
-                    markInfo[color] = NSNumber.init(value: count + 1)
-                }else {
-                    markInfo[color] = NSNumber.init(value: 1)
+                    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
                 }
             }
-        }
-        
-        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)"))
             }
-        }
-        
-        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
+            // Compare
+            let compareDifValue = DataModel.shared.comparativeDifference()
+            for w in 0...maxWidth {
+                let x = Int(w)
                 
-                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
+                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)
                     
-                    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 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
         }
-        
-        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
     }
 }

+ 0 - 4
KdanAutoTest/KdanAuto/KdanAutoDebug.entitlements

@@ -2,8 +2,6 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
-	<key>com.apple.security.app-sandbox</key>
-	<true/>
 	<key>com.apple.security.cs.allow-dyld-environment-variables</key>
 	<true/>
 	<key>com.apple.security.cs.allow-jit</key>
@@ -16,7 +14,5 @@
 	<true/>
 	<key>com.apple.security.cs.disable-library-validation</key>
 	<true/>
-	<key>com.apple.security.files.user-selected.read-write</key>
-	<true/>
 </dict>
 </plist>

+ 53 - 9
KdanAutoTest/KdanAuto/ViewController.swift

@@ -21,6 +21,9 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
     
     @IBOutlet var startBtn : NSButton!
     @IBOutlet var replaceAllBtn : NSButton!
+    @IBOutlet var exportReportBtn : NSButton!
+    @IBOutlet var advanceBtn : NSButton!
+    
     var _isProcessing : Bool!
     
     var _selectFileType : String! = ""
@@ -49,6 +52,7 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
         updateProcessStatus()
         
         self.replaceAllBtn.isEnabled = false;
+        self.exportReportBtn.isEnabled = false;
         
         DispatchQueue.global().async {
             for fileType in testFileTypes {
@@ -123,6 +127,9 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
         
         startBtn.isEnabled = false
         startBtn.title = "Doing"
+        exportReportBtn.isEnabled = false;
+        replaceAllBtn.isEnabled = false;
+        advanceBtn.isEnabled = false;
         
         DispatchQueue.global().async {
             var report = NSMutableAttributedString.init()
@@ -158,21 +165,28 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
                         self.reloadListData()
                     }
                     if nil != testObject {
-                        let queue = DispatchQueue.global()
-                        queue.async {
-                            testObject?.autoTest()
+                        autoreleasepool {
+                            let queue = DispatchQueue.global()
+                            queue.async {
+                                testObject?.autoTest()
+                                
+                                testSemaphore.signal()
+                            }
+                            testSemaphore.wait()
                             
-                            testSemaphore.signal()
-                        }
-                        testSemaphore.wait()
-                        
-                        if let cReport = testObject?.testReport() {
-                            report.append(cReport)
+                            if let cReport = testObject?.testReport() {
+                                report.append(cReport)
+                            }
                         }
                     }
                     testObject?.setStatus(.Finished)
                     DispatchQueue.main.sync {
                         self.reloadListData()
+                        
+                        if (self.advanceView.getAutoTestObj() != nil && testObject != nil &&
+                            testObject!.isEqual(to: self.advanceView.getAutoTestObj())) {
+                            self.advanceView.setAutoTestObj(self.advanceView.getAutoTestObj());
+                        }
                     }
                 }
                 
@@ -202,6 +216,8 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
                 self.startBtn.title = "Start"
                 
                 self.replaceAllBtn.isEnabled = true
+                self.exportReportBtn.isEnabled = true;
+                self.advanceBtn.isEnabled = true;
                 
                 TestDegreeManager.shared().saveInfo()
             }
@@ -271,6 +287,34 @@ class ViewController : NSViewController, SettingViewControllerDelegate, AutoTest
         }
     }
     
+    @IBAction func showCompareReportAction(_ sender:NSButton) {
+        var files = NSMutableArray()
+        for fileType in testFileTypes {
+            let types = testTypeInfo[fileType] as! NSArray
+            for typeInfo in types {
+                let ti = typeInfo as! NSDictionary
+                let type = ti["Type"] as! NSString
+                
+                let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
+                let tFiles = testObject?.compareFiles();
+                if (tFiles != nil && tFiles?.count != 0) {
+                    files.addObjects(from: tFiles as! [Any])
+                }
+            }
+        }
+        
+        if nil != files && files.count > 0 {
+            let compareVC = CompareViewController.shared()
+            compareVC.setFiles(files)
+            
+            let point = sender.convert(NSPoint.zero, to: self.view.window?.contentView)
+            compareVC.showIn(self.view.window?.contentView, rect: NSRect.init(origin: point, size: sender.frame.size))
+        }
+        return
+        
+    }
+    
+    
     // TableView Delegate
     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
         let cellInfo = AutoTestCellInfo.initWithRow(row)

+ 31 - 27
KdanAutoTest/ProcessCheckFile/Process/ProcessThumbnal.swift

@@ -34,25 +34,27 @@ class ProcessThumbnal : NSObject {
         }
         
         if NSArray(array: ["bmp", "BMP", "PNG", "png", "JPG", "jpg"]).contains(NSString(string: filePath).pathExtension) {
-            let imageSource = CGImageSourceCreateWithURL(URL.init(fileURLWithPath: filePath, isDirectory: false) as CFURL, nil)
-            
-            if nil == imageSource {
-                return false
-            }
-            
-            // Get the BMP image
-            let cgimage = CGImageSourceCreateImageAtIndex(imageSource!, 0, nil)
-            if nil == cgimage {
-                return false
+            return autoreleasepool {
+                let imageSource = CGImageSourceCreateWithURL(URL.init(fileURLWithPath: filePath, isDirectory: false) as CFURL, nil)
+                
+                if nil == imageSource {
+                    return false
+                }
+                
+                // Get the BMP image
+                let cgimage = CGImageSourceCreateImageAtIndex(imageSource!, 0, nil)
+                if nil == cgimage {
+                    return false
+                }
+                
+                let rep = NSBitmapImageRep.init(cgImage: cgimage!)
+                let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                
+                let url = URL.init(fileURLWithPath: desPath, isDirectory: false)
+                try? data!.write(to: url)
+                
+                return true
             }
-            
-            let rep = NSBitmapImageRep.init(cgImage: cgimage!)
-            let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
-            
-            let url = URL.init(fileURLWithPath: desPath, isDirectory: false)
-            try? data!.write(to: url)
-            
-            return true
         }
         
         var didFinished = false
@@ -63,16 +65,18 @@ class ProcessThumbnal : NSObject {
                                           
                                           update: { (representation, type, error) in
             if nil != representation {
-                let image = representation!.nsImage as NSImage
-                
-                if nil != image {
-                    didFinished = true
-                    
-                    let rep = NSBitmapImageRep.init(cgImage: image.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
-                    let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                autoreleasepool {
+                    let image = representation!.nsImage as NSImage
                     
-                    let url = URL.init(fileURLWithPath: desPath, isDirectory: false)
-                    try? data!.write(to: url)
+                    if nil != image {
+                        didFinished = true
+                        
+                        let rep = NSBitmapImageRep.init(cgImage: image.cgImage(forProposedRect: nil, context: nil, hints: nil)!)
+                        let data = rep.representation(using: NSBitmapImageRep.FileType.png, properties: [:]);
+                        
+                        let url = URL.init(fileURLWithPath: desPath, isDirectory: false)
+                        try? data!.write(to: url)
+                    }
                 }
             }