浏览代码

【Bug修复】编辑 - 特殊图片添加得10秒左右才能添加成功 修复

lizhe 1 年之前
父节点
当前提交
4926626914

+ 19 - 3
PDF Office/PDF Master.xcodeproj/project.pbxproj

@@ -1186,6 +1186,9 @@
 		AD53B70529ACC65500D61E81 /* KMMailHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AD53B70429ACC65500D61E81 /* KMMailHelper.m */; };
 		AD53B70629ACC65500D61E81 /* KMMailHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AD53B70429ACC65500D61E81 /* KMMailHelper.m */; };
 		AD53B70729ACC65500D61E81 /* KMMailHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AD53B70429ACC65500D61E81 /* KMMailHelper.m */; };
+		AD58C0F82A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD58C0F72A1F2D3600F911A0 /* KMImageOptimization.swift */; };
+		AD58C0F92A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD58C0F72A1F2D3600F911A0 /* KMImageOptimization.swift */; };
+		AD58C0FA2A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD58C0F72A1F2D3600F911A0 /* KMImageOptimization.swift */; };
 		AD68782129A5FADC005B5210 /* KMLightMemberCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD68782029A5FADC005B5210 /* KMLightMemberCache.swift */; };
 		AD68782229A5FADC005B5210 /* KMLightMemberCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD68782029A5FADC005B5210 /* KMLightMemberCache.swift */; };
 		AD68782329A5FADC005B5210 /* KMLightMemberCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD68782029A5FADC005B5210 /* KMLightMemberCache.swift */; };
@@ -3864,6 +3867,7 @@
 		AD53B6FD29AC5FCD00D61E81 /* KMLightMemberToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMLightMemberToken.swift; sourceTree = "<group>"; };
 		AD53B70329ACC65500D61E81 /* KMMailHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMMailHelper.h; sourceTree = "<group>"; };
 		AD53B70429ACC65500D61E81 /* KMMailHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMMailHelper.m; sourceTree = "<group>"; };
+		AD58C0F72A1F2D3600F911A0 /* KMImageOptimization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMImageOptimization.swift; sourceTree = "<group>"; };
 		AD68782029A5FADC005B5210 /* KMLightMemberCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMLightMemberCache.swift; sourceTree = "<group>"; };
 		AD68783229A60FA7005B5210 /* KMLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMLoginView.swift; sourceTree = "<group>"; };
 		AD68783729A60FC0005B5210 /* KMLoginView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMLoginView.xib; sourceTree = "<group>"; };
@@ -4997,6 +5001,7 @@
 		8996CFE4295BE15800D32783 /* EditPDF */ = {
 			isa = PBXGroup;
 			children = (
+				AD58C0FB2A1F2D3C00F911A0 /* Category */,
 				AD3C6DFA2A1C48600010B1A7 /* Manager */,
 				ADC31FA92A0E0C1E00ED44A2 /* View */,
 				89D2D306295A83B500BFF5FE /* KMEditPDFTextPropertyViewController.swift */,
@@ -5955,12 +5960,20 @@
 			path = Email;
 			sourceTree = "<group>";
 		};
-		AD68781F29A5FADC005B5210 /* KMLightMemberCache */ = {
+		AD58C0FB2A1F2D3C00F911A0 /* Category */ = {
+			isa = PBXGroup;
+			children = (
+				AD58C0F72A1F2D3600F911A0 /* KMImageOptimization.swift */,
+			);
+			path = Category;
+			sourceTree = "<group>";
+		};
+		AD68781F29A5FADC005B5210 /* Cache */ = {
 			isa = PBXGroup;
 			children = (
 				AD68782029A5FADC005B5210 /* KMLightMemberCache.swift */,
 			);
-			path = KMLightMemberCache;
+			path = Cache;
 			sourceTree = "<group>";
 		};
 		AD68782829A60130005B5210 /* Login&Register */ = {
@@ -6940,7 +6953,7 @@
 				AD53B70129ACC63D00D61E81 /* Tools */,
 				AD015FB529AB483200A57062 /* Config */,
 				ADF1569A29A63CAB001D1018 /* Source */,
-				AD68781F29A5FADC005B5210 /* KMLightMemberCache */,
+				AD68781F29A5FADC005B5210 /* Cache */,
 				ADE3C1F029A5B3B600793B13 /* Extension */,
 				ADE3C1E129A5AB8B00793B13 /* Controller */,
 				ADE3C1D729A5A9AB00793B13 /* KMRequestServer */,
@@ -10529,6 +10542,7 @@
 				BB162E92294FFE020088E9D1 /* KMWatermarkModel.swift in Sources */,
 				9FDD0F842952FC9C000C4DAD /* KMAliasLightParser.swift in Sources */,
 				BBFE6E5D2930809A00142C01 /* KMMergeCollectionPageViewItem.swift in Sources */,
+				AD58C0F82A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */,
 				89E4E7132963D7FF002DBA6F /* NSFont_SKExtensions.m in Sources */,
 				89316849296E436B0073EA59 /* KMSignatureManager.m in Sources */,
 				BB147005299DC0D100784A6A /* OIDFieldMapping.m in Sources */,
@@ -11620,6 +11634,7 @@
 				9F1FE49A29406E4700E952CA /* NewTabButton.m in Sources */,
 				BB146FEE299DC0D100784A6A /* GTLRBatchResult.m in Sources */,
 				ADCB98E22924776F00B51A03 /* KMBatchProcessingSizeTableCell.swift in Sources */,
+				AD58C0F92A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */,
 				ADE8BC3C29F9458700570F89 /* KMRecommondManager.m in Sources */,
 				BB897272294DB6BE0045787C /* KMWatermarkAdjectivePlainView.swift in Sources */,
 				9F0CB49829683E1000007028 /* KMPropertiesPanelTextSubVC.swift in Sources */,
@@ -11890,6 +11905,7 @@
 				9F0CB523298656AA00007028 /* KMDesignToken+BorderRadiusBottomLeft.swift in Sources */,
 				9F0CB4DF2986554D00007028 /* KMDesignToken+HorizontalPadding.swift in Sources */,
 				AD44D654292C9E7900A94554 /* KMImageToPDFChooseView.swift in Sources */,
+				AD58C0FA2A1F2D3600F911A0 /* KMImageOptimization.swift in Sources */,
 				BBB9B318299A5D6D004F3235 /* KMDropboxManager.m in Sources */,
 				BB8F4559295AA1270037EA22 /* KMHeaderFooterPropertyInfoController.swift in Sources */,
 				89752DBA2936F9B9003FF08E /* NSButton+TitleColor.m in Sources */,

PDF Office/PDF Master/Class/KMLightMember/KMLightMemberCache/KMLightMemberCache.swift → PDF Office/PDF Master/Class/KMLightMember/Cache/KMLightMemberCache.swift


+ 131 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/RightSide/EditPDF/Category/KMImageOptimization.swift

@@ -0,0 +1,131 @@
+//
+//  KMImageOptimization.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/5/25.
+//
+
+import AppKit
+import CoreGraphics
+import CoreImage
+
+class KMImageOptimization: NSObject {
+    static func compressImageLosslessly(image: NSImage, targetSize: CGSize, maxSizeInBytes: Int, targetCompression: CGFloat) -> Data? {
+        guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
+            return nil
+        }
+        
+        //宽高自适应
+        let newSize: CGSize
+        let widthRatio = targetSize.width / image.size.width
+        let heightRatio = targetSize.height / image.size.height
+        
+        if widthRatio > heightRatio {
+            newSize = CGSize(width: targetSize.height * image.size.width / image.size.height, height: targetSize.height)
+        } else {
+            newSize = CGSize(width: targetSize.width, height: targetSize.width * image.size.height / image.size.width)
+        }
+        
+        let options: [CFString: Any] = [
+            kCGImageSourceThumbnailMaxPixelSize: max(newSize.width, newSize.height),
+            kCGImageSourceCreateThumbnailFromImageAlways: true,
+            kCGImageDestinationLossyCompressionQuality: 1.0
+        ]
+        
+        guard var imageData = CFDataCreateMutable(nil, 0) else {
+            return nil
+        }
+        
+        guard let destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, nil) else {
+            return nil
+        }
+        
+        CGImageDestinationAddImage(destination, cgImage, options as CFDictionary)
+        CGImageDestinationFinalize(destination)
+        
+        var dataSize = CFDataGetLength(imageData)
+        let targetSizeInBytes = Int(CGFloat(maxSizeInBytes) * targetCompression)
+        
+        if dataSize <= targetSizeInBytes {
+            return imageData as Data
+        }
+        
+        var compressedData: Data?
+        
+        let optionsLow: [CFString: Any] = [
+            kCGImageSourceThumbnailMaxPixelSize: max(newSize.width, newSize.height) / 2,
+            kCGImageSourceCreateThumbnailFromImageAlways: true,
+            kCGImageDestinationLossyCompressionQuality: targetCompression
+        ]
+        
+        let optionsHigh: [CFString: Any] = [
+            kCGImageSourceThumbnailMaxPixelSize: max(newSize.width, newSize.height),
+            kCGImageSourceCreateThumbnailFromImageAlways: true,
+            kCGImageDestinationLossyCompressionQuality: targetCompression
+        ]
+        
+        while compressedData == nil {
+            autoreleasepool {
+                if targetSizeInBytes > 0 {
+                    if dataSize <= targetSizeInBytes {
+                        compressedData = imageData as Data
+                    } else {
+                        let resizedImageData = NSMutableData()
+                        
+                        guard let resizedDestination = CGImageDestinationCreateWithData(resizedImageData as CFMutableData, kUTTypeJPEG, 1, nil) else {
+                            return
+                        }
+                        
+                        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
+                        let contextBounds = CGRect(origin: .zero, size: newSize)
+                        
+                        if let context = CGContext(data: nil, width: Int(newSize.width), height: Int(newSize.height), bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo) {
+                            context.interpolationQuality = .high
+                            context.draw(cgImage, in: contextBounds)
+                            let resizedCGImage = context.makeImage()
+                            
+                            if let resizedCGImage = resizedCGImage {
+                                CGImageDestinationAddImage(resizedDestination, resizedCGImage, optionsLow as CFDictionary)
+                                CGImageDestinationFinalize(resizedDestination)
+                                
+                                imageData = resizedImageData
+                                dataSize = CFDataGetLength(imageData)
+                            } else {
+                                compressedData = imageData as Data
+                            }
+                        }
+                    }
+                } else {
+                    compressedData = imageData as Data
+                }
+            }
+        }
+        
+        return compressedData
+    }
+    
+    static func needCompressImageLosslessly(image: NSImage, targetSize: CGSize, maxSizeInBytes: Int, targetCompression: CGFloat) -> String {
+        let kFilePath: NSString = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.path + "KMImageOptimizationCache" as NSString
+        let string: NSString = (kFilePath as String) + "/" + "optimization.png" as NSString
+        if (!FileManager.default.fileExists(atPath: string.deletingLastPathComponent as String)) {
+            try?FileManager.default.createDirectory(atPath: string.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
+        }
+        
+        if (!FileManager.default.fileExists(atPath: string as String)) {
+            FileManager.default.createFile(atPath: string as String, contents: nil)
+        }
+        
+        // 示例用法
+        if let compressedData = KMImageOptimization.compressImageLosslessly(image: image, targetSize: targetSize, maxSizeInBytes: maxSizeInBytes, targetCompression: targetCompression) {
+            let saveURL = URL(fileURLWithPath: string as String)//URL(fileURLWithPath: "/path/to/save/compressed_image.png")
+            do {
+                try compressedData.write(to: saveURL)
+                // 图像已成功保存在指定路径中
+                print("保存图像成功:\(string)")
+            } catch {
+                print("保存图像失败:\(error)")
+            }
+        }
+        return string as String
+    }
+}

+ 12 - 4
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift

@@ -1390,8 +1390,8 @@ import Cocoa
             panel.allowedFileTypes = ["png","jpg"]
             panel.beginSheetModal(for: NSApp.mainWindow!) { response in
                 if response == .OK {
-                    let openPath = panel.url?.path
-                    let image = NSImage.init(contentsOf: panel.url!)
+                    var filePath = panel.url?.path
+                    var image = NSImage.init(contentsOf: panel.url!)
                     //图片自适应范围
                     if image != nil {
                         var imageRect = rect
@@ -1416,8 +1416,16 @@ import Cocoa
                         
                         imageRect.size = newSize
                         
-                        self.listView.createImagePath(openPath!, rect: imageRect, page: pdfView.currentPage())
-                        self.isPDFTextImageEdited = true
+                        if imageSize.width > 1080 || imageSize.height > 1080 {
+                            filePath = KMImageOptimization.needCompressImageLosslessly(image: image!,
+                                                                                       targetSize: CGSize(width: 1080, height: 1080),
+                                                                                       maxSizeInBytes: 1024 * 1024 * 5,
+                                                                                       targetCompression: 1.0)
+                        }
+                        DispatchQueue.main.async {
+                            self.listView.createImagePath(filePath, rect: imageRect, page: pdfView.currentPage())
+                            self.isPDFTextImageEdited = true
+                        }
                     }
                 }
             }