浏览代码

【2025】【Edit】首页获取缩图优化, 裁剪补充

niehaoyu 4 天之前
父节点
当前提交
8f479c5274

+ 1 - 1
PDF Office/PDF Master/KMClass/KMHomeViewController/Views/KMHomeRightView/HistoryFile.swift

@@ -62,7 +62,7 @@ class HistoryFile: NSObject {
                 string.setString(fileUrl.path.deletingLastPathComponent)
             }
             
-            let image = NSImage.previewForFile(path: fileUrl, ofSize: self.iconSize, asIcon: true) ?? NSImage()
+            let image = KMFileThumbManager.manager.getFileThumb(fileUrl) ?? NSImage()
             
             self.image = image
             self.name = fileUrl.path.lastPathComponent

PDF Office/PDF Master/KMClass/KMHomeViewController/Views/KMHomeRightView/HistoryFilesManager.swift → PDF Office/PDF Master/KMClass/KMHomeViewController/HistoryFilesManager/HistoryFilesManager.swift


+ 117 - 0
PDF Office/PDF Master/KMClass/KMHomeViewController/HistoryFilesManager/KMFileThumbManager.swift

@@ -0,0 +1,117 @@
+//
+//  KMFileThumbManager.swift
+//  PDF Reader Pro
+//
+//  Created by Niehaoyu on 2024/11/22.
+//
+
+import Cocoa
+import CryptoKit
+
+class KMFileThumbManager: NSObject {
+    
+    let thumbFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("thumb")
+    
+    @objc public static let manager = KMFileThumbManager()
+    
+    private var iconSize: CGSize = CGSizeMake(126*3, 168*3)
+    
+    override init() {
+        super.init()
+        
+        if (!FileManager.default.fileExists(atPath: thumbFolderPath!)) {
+            try?FileManager.default.createDirectory(atPath: thumbFolderPath!, withIntermediateDirectories: true, attributes: nil)
+        }
+        
+        refreshData()
+    }
+    
+    private func refreshData() {
+        let urls: Array<URL> = NSDocumentController.shared.recentDocumentURLs
+        
+        var fileNames: [String] = []
+        for url in urls {
+            let filePath = url.path
+            let fileName = filePath.getLastComponentDeleteExtension
+            
+            let resultPath = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png"))
+            if (!FileManager.default.fileExists(atPath: resultPath!)) {
+                updateFile(url, iconSize)
+            }
+            fileNames.append((fileName + ".png"))
+        }
+        
+        if let contents = try?FileManager.default.contentsOfDirectory(atPath: thumbFolderPath!) {
+            for name in contents {
+                if name != ".DS_Store" {
+                    if let index = fileNames.firstIndex(of: name) {
+                        
+                    } else {
+                        if let path = thumbFolderPath?.stringByAppendingPathComponent(name) {
+                            try?FileManager.default.removeItem(atPath: path)
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    private func generateThumbnail(for pdfURL: URL, _ size: NSSize) -> NSImage? {
+        guard let pdfDocument = CGPDFDocument(pdfURL as CFURL),
+              let pdfPage = pdfDocument.page(at: 1) else {
+            
+            return nil
+        }
+        
+        let pageRect = pdfPage.getBoxRect(.mediaBox)
+        
+        // 创建图形上下文
+        let bitsPerComponent = 8
+        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
+        let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: bitsPerComponent, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo)
+        
+        // 绘制PDF页面
+        //        context?.saveGState()
+        //        context?.translateBy(x: 0, y: size.height)
+        //        context?.scaleBy(x: 1.0, y: -1.0) // 反转坐标系
+        context?.scaleBy(x: size.width / pageRect.width, y: size.height / pageRect.height) // 缩放
+        context?.drawPDFPage(pdfPage)
+        context?.restoreGState()
+        
+        // 创建NSImage
+        if let cgImage = context?.makeImage() {
+            return NSImage(cgImage: cgImage, size: NSSize(width: size.width, height: size.height))
+        }
+        return nil
+    }
+    
+    public func updateFile(_ fileURL: URL, _ iconSize: CGSize) {
+        let filePath = fileURL.path
+        let fileName = filePath.getLastComponentDeleteExtension
+        
+        if let resultPath: String = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png")) {
+            if let image = generateThumbnail(for: fileURL, iconSize) {
+                guard let data = image.tiffRepresentation else {
+                    return
+                }
+                let imageRep = NSBitmapImageRep(data: data)
+                imageRep?.size = image.size
+                if let imageData = imageRep?.representation(using: .png, properties: [:]) {
+                    try?imageData.write(to: URL(fileURLWithPath: resultPath))
+                }
+            }
+        }
+    }
+    
+    public func getFileThumb(_ fileURL: URL) -> NSImage? {
+        let filePath = fileURL.path
+        let fileName = filePath.getLastComponentDeleteExtension
+        
+        if let resultPath: String = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png")) {
+            return NSImage(contentsOf: URL(fileURLWithPath: resultPath))
+        }
+        return nil
+    } 
+    
+    
+}

+ 1 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/EditTool/Crop/KMCropController.swift

@@ -69,6 +69,7 @@ class KMCropController: NSViewController {
         
         documentPreview.pdfView.toolMode = .selectToolMode
         documentPreview.pdfView.selectionRect = bounds
+        documentPreview.pdfView.setNeedsDisplayForVisiblePages()
      
         propertyController.pdfView = documentPreview.pdfView
         propertyController.reloadData()

+ 40 - 5
PDF Office/PDF Master/KMClass/KMPDFViewController/EditTool/Crop/Views/KMCropPropertyController.swift

@@ -149,8 +149,7 @@ class KMCropPropertyController: NSViewController {
         pageRangeLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
         pageRangeLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
         
-        
-        
+         
         cropButton.properties = ComponentButtonProperty(type: .primary, size: .m, buttonText: KMLocalizedString("Apply"), keepPressState: false)
         
     }
@@ -197,8 +196,7 @@ class KMCropPropertyController: NSViewController {
         pageBottomInput.reloadData()
         
         //PageRange
-        
-        print(selectionRect)
+         
         
     }
     
@@ -214,11 +212,48 @@ class KMCropPropertyController: NSViewController {
         sizeSyncButton.reloadData()
     }
     
+    @objc func cropButtonClicked(_ sender: ComponentButton) {
+        
+    }
+    
 }
 
 //MARK: - ComponentInputNumberDelegate
 extension KMCropPropertyController: ComponentInputNumberDelegate {
-    
+    func componentInputNumberDidValueChanged(inputNumber: ComponentInputNumber?) {
+        guard let pdfView = self.pdfView else {
+            return
+        }
+        
+        guard let page = pdfView.currentSelectionPage() else {
+            return
+        }
+        let pageBounds = page.bounds
+        
+        var value: CGFloat = 0
+        if let text = inputNumber?.properties.text {
+            value = text.stringToCGFloat()
+        }
+  
+        var rect = pdfView.selectionRect
+        if inputNumber == sizeWidthInput {
+            rect.size.width = value
+        } else if inputNumber == sizeHeightInput {
+            rect.size.height = value
+        } else if inputNumber == pageLeftInput {
+            rect.origin.x = value
+        } else if inputNumber == pageRightInput {
+            rect.size.width = pageBounds.size.width - rect.origin.x - value
+        } else if inputNumber == pageTopInput {
+            rect.size.height = pageBounds.size.height - rect.origin.y - value
+        } else if inputNumber == pageBottomInput {
+            rect.origin.y = value
+        }
+        pdfView.selectionRect = rect
+        pdfView.setNeedsDisplayForVisiblePages()
+        
+        reloadData()
+    }
 }
 
 //MARK: - ComponentSelectDelegate

+ 18 - 2
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -3933,6 +3933,9 @@
 		BB7929F52CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
 		BB7929F62CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
 		BB7929F72CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
+		BB792A042CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
+		BB792A052CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
+		BB792A062CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
 		BB79E7192CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
 		BB79E71A2CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
 		BB79E71B2CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
@@ -7333,6 +7336,7 @@
 		BB77C85E2BD506BE0065AFF2 /* CPDFAnnotation+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFAnnotation+KMExtension.swift"; sourceTree = "<group>"; };
 		BB78EAA92B561F9700121691 /* KMFullScreenWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMFullScreenWindow.swift; sourceTree = "<group>"; };
 		BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPageRangeSelectView.swift; sourceTree = "<group>"; };
+		BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMFileThumbManager.swift; sourceTree = "<group>"; };
 		BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMEditImageController.swift; sourceTree = "<group>"; };
 		BB79E7182CE617CB0052CAD5 /* KMEditImageController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMEditImageController.xib; sourceTree = "<group>"; };
 		BB79FAB02CDC65BA00BF7B39 /* KMBGTemplateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBGTemplateController.swift; sourceTree = "<group>"; };
@@ -12802,6 +12806,7 @@
 				BB5A9D292CB6520100F64C1F /* home.xcassets */,
 				BB5A9D2E2CB6520100F64C1F /* KMNHomeViewController.swift */,
 				BB5A9D282CB6520100F64C1F /* KMNHomeViewController.xib */,
+				BB792A012CF027C1006FFD5D /* HistoryFilesManager */,
 				BBB2A99A2CB65C580066560B /* KMURLCreatePDFWindowController */,
 				BBB2A9992CB65C440066560B /* Views */,
 			);
@@ -12811,8 +12816,6 @@
 		BB5A9D272CB6520100F64C1F /* KMHomeRightView */ = {
 			isa = PBXGroup;
 			children = (
-				BB19A7492CB7C2C6008204DC /* HistoryFilesManager.swift */,
-				BBE3709C2CB8BD3700390884 /* HistoryFile.swift */,
 				BB19A7392CB7B4C9008204DC /* KMHomeRightView.swift */,
 				BB19A73D2CB7B4D1008204DC /* KMHomeRightView.xib */,
 				9F1F82C2292F113A0092C4B4 /* KMHomeDragView.swift */,
@@ -13189,6 +13192,16 @@
 			path = CustomViews;
 			sourceTree = "<group>";
 		};
+		BB792A012CF027C1006FFD5D /* HistoryFilesManager */ = {
+			isa = PBXGroup;
+			children = (
+				BB19A7492CB7C2C6008204DC /* HistoryFilesManager.swift */,
+				BBE3709C2CB8BD3700390884 /* HistoryFile.swift */,
+				BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */,
+			);
+			path = HistoryFilesManager;
+			sourceTree = "<group>";
+		};
 		BB7F7BFD29AA585E00A3E4E7 /* images */ = {
 			isa = PBXGroup;
 			children = (
@@ -17800,6 +17813,7 @@
 				ADE86AE62B0AF50B00414DFA /* KMCompareCoveringSettingWindowController.swift in Sources */,
 				BB1B0AF22B4FC6E900889528 /* KMFunctionGuideNameItemView.swift in Sources */,
 				BBBC08832B2AC863009B237F /* KMSnapshotModel.swift in Sources */,
+				BB792A042CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				BB4F7E792B0C45BB0077EC8C /* KMNoteOutlineFilterViewController.swift in Sources */,
 				ADD1B6C72942E83000C3FFF7 /* KMPrintBottomView.swift in Sources */,
 				9F0CB4D12986550B00007028 /* KMDesignToken+Width.swift in Sources */,
@@ -18628,6 +18642,7 @@
 				ADDF83362B391A5C00A81A4E /* CPDFListViewConfig.m in Sources */,
 				AD867FB429DFBB2700F00440 /* KMAnnotationOutlineSectionView.swift in Sources */,
 				BBEC00A9295BDECF00A26C98 /* KMHeaderFooterContentInfoView.swift in Sources */,
+				BB792A052CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				9F8539BF2943085A00DF644E /* KMBrowser.swift in Sources */,
 				9F0CB4E62986557F00007028 /* KMDesignToken+PaddingRight.swift in Sources */,
 				BB7FF5082A60E84400901C2D /* KMEnumExtensions.swift in Sources */,
@@ -20259,6 +20274,7 @@
 				BBFE6E89293210AB00142C01 /* KMCompressCellView.swift in Sources */,
 				ADDEEA702AD3E16100EF675D /* KMSigntureViewItem.swift in Sources */,
 				9FF0D0552B6A3EE40018A732 /* CPDFListView+Form.swift in Sources */,
+				BB792A062CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				BB853C7F2AF8B5D6009C20C1 /* KMBatchOperateAddPasswordViewController.swift in Sources */,
 				AD3AAD252B0B6F9E00DE5FE7 /* KMCompareContentView.swift in Sources */,
 				BB147040299DC0D200784A6A /* OIDEndSessionResponse.m in Sources */,