|
@@ -8,6 +8,7 @@
|
|
|
import Foundation
|
|
|
import AppKit
|
|
|
import CoreImage
|
|
|
+import CryptoKit
|
|
|
|
|
|
class ImageProcess : NSObject {
|
|
|
|
|
@@ -219,8 +220,13 @@ class ImageProcess : NSObject {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if (ImageProcess.checkEqualFor(resultPath, checkPath: checkPath)) {
|
|
|
+ complention(1)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
let resultImage = rImage!
|
|
|
- var checkImage = cImage!
|
|
|
+ let checkImage = cImage!
|
|
|
|
|
|
var 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)!)
|
|
@@ -351,29 +357,31 @@ class ImageProcess : NSObject {
|
|
|
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!)
|
|
|
+ autoreleasepool {
|
|
|
+ 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)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -401,6 +409,10 @@ class ImageProcess : NSObject {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+ if (ImageProcess.checkEqualFor(resultPath, checkPath: checkPath)) {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
let resultImage = rImage as! NSImage
|
|
|
let checkImage = cImage as! NSImage
|
|
|
|
|
@@ -525,4 +537,40 @@ class ImageProcess : NSObject {
|
|
|
return nil
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ class func checkEqualFor(_ resultPath:String, checkPath:String) -> Bool {
|
|
|
+ // 先通过文件属性 + MD5 码进行快速对比,排除大部分,已经相同的文件
|
|
|
+ let rfs = try! FileManager.default.attributesOfItem(atPath: resultPath)[FileAttributeKey.size] as! NSNumber
|
|
|
+ let cfs = try! FileManager.default.attributesOfItem(atPath: checkPath)[FileAttributeKey.size] as! NSNumber
|
|
|
+ if rfs.int64Value != cfs.int64Value {
|
|
|
+ //文件大小不一致,反回不一致
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ let rmd5 = ImageProcess.md5StringOfPath(resultPath);
|
|
|
+ let cmd5 = ImageProcess.md5StringOfPath(checkPath);
|
|
|
+
|
|
|
+ if (nil != rmd5 && nil != cmd5 &&
|
|
|
+ NSString(string: rmd5!).isEqual(to: cmd5!)) {
|
|
|
+ // 文件大小一致,且文件 MD5码完全一致
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ class func md5StringOfPath(_ path:String) -> String? {
|
|
|
+ if FileManager.default.fileExists(atPath: path) {
|
|
|
+ let data = NSData(contentsOfFile: path);
|
|
|
+
|
|
|
+ if (nil == data) {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ return String(format: "%x", data.hashValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+
|
|
|
}
|