Ver código fonte

【2025】【转档】图片转PDF功能接入

lizhe 1 mês atrás
pai
commit
d60fbda542
14 arquivos alterados com 390 adições e 49 exclusões
  1. 19 9
      PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Manager/KMOCRManager.swift
  2. 1 0
      PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Model/KMOCRModel.swift
  3. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/KMBatchWindowController.swift
  4. 154 5
      PDF Office/PDF Master/KMClass/NewBatch/Manager/KMBatchManager.swift
  5. 1 1
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/KMBatchProcessingView.swift
  6. 47 23
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableView.swift
  7. 8 5
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableViewModel/KMBatchProcessingTableViewModel.swift
  8. 2 1
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Presenter/KMBatchProcessingTableViewPresenter.swift
  9. 10 0
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingNameTableCell.swift
  10. 17 5
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingNameTableCell.xib
  11. 62 0
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingWidthTableCell.swift
  12. 37 0
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingWidthTableCell.xib
  13. 7 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/ImageToPDF/KMBatchImageToPDFView.swift
  14. 16 0
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

+ 19 - 9
PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Manager/KMOCRManager.swift

@@ -81,7 +81,7 @@ extension KMOCRManager: KMGOCRManagerDelegate {
         self.model = model
         
         //计算需要处理的页面
-        let pages:[Int] = self.fetchPageIndex(document: document, model: model)
+        let pages:[Int] = KMOCRManager.fetchPageIndex(document: document, model: model)
         model.pageRange = pages
         
         DispatchQueue.main.async {
@@ -215,8 +215,13 @@ extension KMOCRManager: KMGOCRManagerDelegate {
                 if model.saveType == .PDF {
                     let images: [NSImage] = manager.images as? [NSImage] ?? []
                     KMGOCRManager.default().createPDFFile(manager.saveFilePath, images: images, results: resultArrays, scale: maxImageScale)
-                    NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: manager.saveFilePath ?? "")])
-                    self.OCRComplete?(nil, nil, nil)
+                    if self.OCRComplete != nil {
+                        let tempDocument = CPDFDocument(url: NSURL(fileURLWithPath: manager.saveFilePath) as URL)
+                        self.OCRComplete?(tempDocument, nil, nil)
+                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: manager.saveFilePath ?? "")])
+                    } else {
+                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: manager.saveFilePath ?? "")])
+                    }
                 } else {
                     self.saveTXT()
                 }
@@ -237,6 +242,10 @@ extension KMOCRManager: KMGOCRManagerDelegate {
             let string = self.fetchTXT(ocrDictionary: ocrDictionary)
             self.OCRComplete?(nil, string, nil)
         }
+        
+        if model.needTxT {
+            self.saveTXT(needCallBack: false)
+        }
     }
     
     func viewFileAtFinder(_ fileName: String) {
@@ -290,7 +299,7 @@ extension KMOCRManager: CPDFConverterDelegate {
         self.model = model
         
         //计算需要处理的页面
-        let pages:[Int] = self.fetchPageIndex(document: document, model: model)
+        let pages:[Int] = KMOCRManager.fetchPageIndex(document: document, model: model)
         model.pageRange = pages
         
         if model.saveAsPDF {
@@ -428,14 +437,15 @@ extension KMOCRManager {
 
 //MARK: complete
 extension KMOCRManager {
-    func saveTXT() {
+    func saveTXT(needCallBack: Bool = true) {
         let textString = self.fetchTXT(ocrDictionary: ocrDictionary)
-
-        let outputURL = URL(fileURLWithPath: self.saveAsPDFFilePath)
+        let outputURL = URL(fileURLWithPath: self.saveAsPDFFilePath.deletingPathExtension + ".txt")
         try? textString.write(to: outputURL, atomically: true, encoding: .utf8)
         self.viewFileAtFinder(outputURL.path)
         
-        self.success(document: self.document ?? CPDFDocument())
+        if needCallBack {
+            self.success(document: self.document ?? CPDFDocument())
+        }
     }
     
     func fetchTXT(ocrDictionary: [NSNumber: Any]) -> String {
@@ -504,7 +514,7 @@ extension KMOCRManager {
 
 //
 extension KMOCRManager {
-    func fetchPageIndex(document: CPDFDocument, model: KMOCRModel) -> [Int] {
+    static func fetchPageIndex(document: CPDFDocument, model: KMOCRModel) -> [Int] {
         //计算需要处理的页面
         var pages:[Int] = []
         if model.pageRangeType == .current {

+ 1 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Model/KMOCRModel.swift

@@ -28,6 +28,7 @@ class KMOCRModel: KMBatchSettingItemViewModel {
     var imageCorrection: Bool = false
     var saveAsPDF: Bool = false
     var saveType: KMOCRSaveType = .PDF
+    var needTxT: Bool = false
     
     var pageRange: [Int] = []
     var pageRangeString: String = ""

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/KMBatchWindowController.swift

@@ -79,6 +79,15 @@ class KMBatchWindowController: NSWindowController {
     
     var type: KMBatchCollectionViewType = .convertPDF {
         didSet {
+            if type == .imageToPDF {
+                var rect = self.window!.frame
+                rect.size.width = 880
+                rect.size.height = 600
+                
+                self.window?.setFrame(rect, display: true, animate: false)
+                self.window?.minSize = CGSize(width: 880, height: 600)
+            }
+            
             self.reloadData()
         }
     }

+ 154 - 5
PDF Office/PDF Master/KMClass/NewBatch/Manager/KMBatchManager.swift

@@ -76,6 +76,9 @@ class KMBatchManager: NSObject {
             case .batchRemove:
                 self.removeApplay(data: data, outputFolderPath: outputFolderPath)
                 break
+            case .imageToPDF:
+                self.imageToPDFExport(data: data, outputFolderPath: outputFolderPath)
+                break
             default:
                 KMPrint("找不到")
                 break
@@ -87,8 +90,8 @@ class KMBatchManager: NSObject {
     }
 }
 
-protocol KMBatchSettingViewExport {}
-extension KMBatchManager: KMBatchSettingViewExport {
+//MARK: 批量
+extension KMBatchManager {
     //MARK: 转档
     func convertPDFExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
         self.convertFile(outputFolderPath: outputFolderPath, data: data, filesData: self.batchFilesData)
@@ -274,9 +277,9 @@ extension KMBatchManager: KMBatchSettingViewExport {
                 }
                 let path = outputFolderPath + "/" + fileName + ".pdf"
                 
-                KMOCRManager.manager.convertBatchOCR(document: document!, saveFilePath: path, model: data, progress: { [unowned self] progress in
+                self.convertOCR(outputFolderPath: outputFolderPath, document: document!, fileName: fileName, data: data) { [unowned self] progress in
                     self.itemProgress(item: item, processValue: progress)
-                }) { [unowned self] document, text, error in
+                } complete: { [unowned self] document, text, error in
                     if error == nil {
                         self.itemSuccess(item: item)
                     } else {
@@ -291,6 +294,21 @@ extension KMBatchManager: KMBatchSettingViewExport {
         }
     }
     
+    func convertOCR(outputFolderPath: String,
+                    document: CPDFDocument,
+                    fileName: String, 
+                    data: KMOCRModel,
+                    progress: @escaping KMOCRManagerOCRProgress,
+                    complete: @escaping KMOCRManagerOCRComplete) {
+        //计算需要处理的页面
+        let path = outputFolderPath + "/" + fileName + ".pdf"
+        KMOCRManager.manager.convertBatchOCR(document: document, saveFilePath: path, model: data, progress: { [unowned self] progressValue in
+            progress(progressValue)
+        }) { [unowned self] document, text, error in
+            complete(document, text, error)
+        }
+    }
+    
     //MARK: 压缩
     func compressExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
         self.compressFile(outputFolderPath: outputFolderPath, data: (data as? KMCompressSettingModel)!, filesData: self.batchFilesData)
@@ -548,6 +566,137 @@ extension KMBatchManager: KMBatchSettingViewExport {
             }
         }
     }
+    
+    //MARK: 图片转PDF
+    func imageToPDFExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        self.imageToPDFFile(outputFolderPath: outputFolderPath, data: data as! KMBatchImageToPDFModel, filesData: self.batchFilesData)
+    }
+    
+    func imageToPDFFile(outputFolderPath: String, data: KMBatchImageToPDFModel, filesData: [KMBatchProcessingTableViewModel]) {
+        if filesData.count != 0 {
+            self.batchProgress()
+            if data.isNewPDF {
+                if data.isMergeAll {
+                    let item = filesData[0]
+                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                    let path = outputFolderPath + "/" + fileName + ".pdf"
+                    
+                    
+                    var pdfDocument = CPDFDocument()
+                    for item in filesData {
+                        pdfDocument?.km_insert(image: item.image, at: pdfDocument?.pageCount ?? 0)
+                    }
+                    
+                    if data.isOCR {
+                        let model = KMOCRModel()
+                        model.showType = .page
+                        model.saveAsPDF = true
+                        model.ocrType = data.ocrType
+                        model.languageType = data.languageType
+                        model.needTxT = data.isExtractText
+                        model.pageRangeType = .all
+                        
+                        //计算需要处理的页面
+                        let pages:[Int] = KMOCRManager.fetchPageIndex(document: pdfDocument!, model: model)
+                        model.pageRange = pages
+                        
+                        self.batchProgress()
+                        self.convertOCR(outputFolderPath: outputFolderPath, document: pdfDocument!, fileName: fileName, data: model) { progress in
+                            self.batchProgress()
+                        } complete: { document, text, error in
+                            self.batchSuccess()
+                        }
+                    } else {
+                        pdfDocument?.write(toFile: path)
+                    }
+                    self.batchSuccess()
+                } else {
+                    for i in 0..<filesData.count {
+                        let item = filesData[i]
+                        if data.isOCR {
+                            var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                            let path = outputFolderPath + "/" + fileName + ".pdf"
+                            
+                            
+                            var pdfDocument = CPDFDocument()
+                            for item in filesData {
+                                pdfDocument?.km_insert(image: item.image, at: pdfDocument?.pageCount ?? 0)
+                            }
+
+                            let model = KMOCRModel()
+                            model.showType = .page
+                            model.saveAsPDF = true
+                            model.ocrType = data.ocrType
+                            model.languageType = data.languageType
+                            model.needTxT = data.isExtractText
+                            model.pageRangeType = .all
+                            
+                            //计算需要处理的页面
+                            let pages:[Int] = KMOCRManager.fetchPageIndex(document: pdfDocument!, model: model)
+                            model.pageRange = pages
+                            
+                            self.itemProgress(item: item, processValue: 0)
+                            self.convertOCR(outputFolderPath: outputFolderPath, document: pdfDocument!, fileName: fileName, data: model) { [unowned self] progress in
+                                self.itemProgress(item: item, processValue: progress)
+                            } complete: { [unowned self] document, text, error in
+                                self.itemSuccess(item: item)
+                                
+                                if i == filesData.count - 1 {
+                                    self.batchSuccess()
+                                }
+                            }
+                        } else {
+                            var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                            let path = outputFolderPath + "/" + fileName + ".pdf"
+                            var pdfDocument = CPDFDocument()
+                            pdfDocument?.km_insert(image: item.image, at: pdfDocument?.pageCount ?? 0)
+                            let success = pdfDocument?.write(toFile: path)
+                            if success != nil {
+                                self.batchSuccess()
+                            } else {
+                                self.batchFailure()
+                            }
+                        }
+                    }
+                }
+            } else {
+                var fileName = data.selectFilePath.deletingPathExtension.lastPathComponent
+                let path = outputFolderPath + "/" + fileName + ".pdf"
+                
+                var pdfDocument = CPDFDocument(url: NSURL(fileURLWithPath: data.selectFilePath) as URL)
+                let count: Int = Int(pdfDocument?.pageCount ?? 0)
+                for item in filesData {
+                    pdfDocument?.km_insert(image: item.image, at: pdfDocument?.pageCount ?? 0)
+                }
+                
+                if data.isOCR {
+                    let model = KMOCRModel()
+                    model.showType = .page
+                    model.saveAsPDF = true
+                    model.ocrType = data.ocrType
+                    model.languageType = data.languageType
+                    model.needTxT = data.isExtractText
+                    model.pageRangeType = .all
+                    //计算需要处理的页面
+                    let pages:[Int] = KMOCRManager.fetchPageIndex(document: pdfDocument!, model: model)
+                    model.pageRange = pages
+                    
+                    self.convertOCR(outputFolderPath: outputFolderPath, document: pdfDocument!, fileName: fileName, data: model) { progress in
+                        
+                    } complete: { document, text, error in
+                        if (error != nil) {
+                            self.batchFailure()
+                        } else {
+                            self.batchSuccess()
+                        }
+                    }
+                } else {
+                    pdfDocument?.write(toFile: path)
+                }
+                self.batchSuccess()
+            }
+        }
+    }
 }
 
 //MARK: private
@@ -563,7 +712,7 @@ extension KMBatchManager {
             data.pageRangeType = model.pageRange
             data.pageRangeString = model.pageRangeString
            
-            let pages:[Int] = KMOCRManager.manager.fetchPageIndex(document: document!, model: data)
+            let pages:[Int] = KMOCRManager.fetchPageIndex(document: document!, model: data)
             
             var tempDocument = CPDFDocument()
             for i in 0..<pages.count {

+ 1 - 1
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/KMBatchProcessingView.swift

@@ -21,7 +21,7 @@ class KMBatchProcessingView: BaseXibView {
     var groupView: ComponentGroup?
     
     weak var delegate: KMBatchProcessingViewDelegate?
-    var inputType: KMBatchCollectionViewType? {
+    var inputType: KMBatchCollectionViewType = .convertPDF {
         didSet {
             self.selectedFilesView.inputType = inputType
             self.tableView.inputType = inputType

+ 47 - 23
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableView.swift

@@ -29,7 +29,7 @@ class KMBatchProcessingTableView: NSView {
     weak var delegate: KMBatchProcessingTableViewDelegate?
 
     var selectModels: [KMBatchProcessingTableViewModel] = []
-    var inputType: KMBatchCollectionViewType? {
+    var inputType: KMBatchCollectionViewType = .convertPDF {
         didSet {
             self.reloadData()
         }
@@ -48,11 +48,7 @@ class KMBatchProcessingTableView: NSView {
     
     //内部使用数据
     var data: [KMBatchProcessingTableViewModel]?
-    fileprivate var options: KMBatchProcessingTableViewOptions? {
-        didSet {
-            self.reloadData()
-        }
-    }
+    fileprivate var options: KMBatchProcessingTableViewOptions?
     
     override func draw(_ dirtyRect: NSRect) {
         super.draw(dirtyRect)
@@ -105,6 +101,12 @@ class KMBatchProcessingTableView: NSView {
             self.tableView.removeTableColumn(self.tableView.tableColumns[0])
         }
         
+        if inputType == .imageToPDF {
+            self.options = [.number, .name, .dimension, .size, .state]
+        } else {
+            self.options = [.number, .name, .size, .state]
+        }
+        
         if (options!.contains(KMBatchProcessingTableViewOptions.number)) {
             let column = NSTableColumn()
             column.headerCell = KMBatchProcessingColumnHeaderCell.init()
@@ -122,7 +124,11 @@ class KMBatchProcessingTableView: NSView {
             column.title = NSLocalizedString("File Name", comment: "")
             column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.name.rawValue))
 //            column.resizingMask = .userResizingMask
-            column.width = self.canShowOrder() ? 180 : 344
+            if self.inputType == .imageToPDF {
+                column.width = 220
+            } else {
+                column.width = self.canShowOrder() ? 180 : 344
+            }
             
             self.tableView.addTableColumn(column)
         }
@@ -137,6 +143,16 @@ class KMBatchProcessingTableView: NSView {
             self.tableView.addTableColumn(column)
         }
         
+        if (options!.contains(KMBatchProcessingTableViewOptions.dimension)) {
+            let column = NSTableColumn()
+            column.headerCell = KMBatchProcessingColumnHeaderCell.init()
+            column.title = NSLocalizedString("Dimension", comment: "")
+            column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.dimension.rawValue))
+            column.resizingMask = .userResizingMask
+            column.width = 164
+            self.tableView.addTableColumn(column)
+        }
+        
         if (options!.contains(KMBatchProcessingTableViewOptions.size)) {
             let column = NSTableColumn()
             column.headerCell = KMBatchProcessingColumnHeaderCell.init()
@@ -158,26 +174,26 @@ class KMBatchProcessingTableView: NSView {
             self.tableView.addTableColumn(column)
         }
         
-//        if (options!.contains(KMBatchProcessingTableViewOptions.delete)) {
-//            let column = NSTableColumn()
-//            column.headerCell = KMBatchProcessingColumnHeaderCell.init()
-//            column.title = NSLocalizedString("", comment: "")
-//            column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.delete.rawValue))
-//            column.resizingMask = .userResizingMask
-//            column.width = 30
-//            self.tableView.addTableColumn(column)
-//        }
+        if (options!.contains(KMBatchProcessingTableViewOptions.delete)) {
+            let column = NSTableColumn()
+            column.headerCell = KMBatchProcessingColumnHeaderCell.init()
+            column.title = NSLocalizedString("", comment: "")
+            column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.delete.rawValue))
+            column.resizingMask = .userResizingMask
+            column.width = 30
+            self.tableView.addTableColumn(column)
+        }
         
         self.tableView.reloadData()
     }
     
     func canShowOrder() -> Bool {
-        if (self.inputType != .imageToPDF &&
-            self.inputType != .security &&
-            self.inputType != .compress) {
-            return true
-        } else {
+        if (self.inputType == .imageToPDF ||
+            self.inputType == .security ||
+            self.inputType == .compress) {
             return false
+        } else {
+            return true
         }
     }
 }
@@ -200,6 +216,8 @@ extension KMBatchProcessingTableView: NSTableViewDelegate {
                     self?.orderClickRow = row
                 }
             }
+        } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.dimension.rawValue)) {
+            cell = KMBatchProcessingWidthTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
         } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.size.rawValue)) {
             cell = KMBatchProcessingSizeTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
         } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.state.rawValue)) {
@@ -212,7 +230,9 @@ extension KMBatchProcessingTableView: NSTableViewDelegate {
         }
         if(cell != nil) {
             if (self.data!.count > row) {
-                cell!.model = self.data![row]
+                let model = self.data![row]
+                model.type = self.inputType
+                cell!.model = model
             }
         }
         return cell
@@ -365,7 +385,11 @@ extension KMBatchProcessingTableView: NSTableViewDelegate {
 
 extension KMBatchProcessingTableView: NSTableViewDataSource {
     func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
-        return 40
+        if self.inputType == .imageToPDF {
+            return 80
+        } else {
+            return 40
+        }
     }
     
 //    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {

+ 8 - 5
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableViewModel/KMBatchProcessingTableViewModel.swift

@@ -16,11 +16,12 @@ struct KMBatchProcessingTableViewOptions: OptionSet {
     static let number = KMBatchProcessingTableViewOptions(rawValue: 1 << 0)
     static let name = KMBatchProcessingTableViewOptions(rawValue: 1 << 1)
     static let size = KMBatchProcessingTableViewOptions(rawValue: 1 << 2)
-    static let order = KMBatchProcessingTableViewOptions(rawValue: 1 << 3)
-    static let state = KMBatchProcessingTableViewOptions(rawValue: 1 << 4)
-    static let delete = KMBatchProcessingTableViewOptions(rawValue: 1 << 5)
+    static let dimension = KMBatchProcessingTableViewOptions(rawValue: 1 << 3)
+    static let order = KMBatchProcessingTableViewOptions(rawValue: 1 << 4)
+    static let state = KMBatchProcessingTableViewOptions(rawValue: 1 << 5)
+    static let delete = KMBatchProcessingTableViewOptions(rawValue: 1 << 6)
     
-    static let all: KMBatchProcessingTableViewOptions = [.number,.name, .size, .order, .state, .delete]
+    static let all: KMBatchProcessingTableViewOptions = [.number, .name, .size, dimension, .order, .state, .delete]
 }
 
 enum KMBatchProcessingTableFileState: String, CaseIterable {
@@ -51,13 +52,15 @@ class KMBatchProcessingTableViewModel: NSObject {
     var pageRangeString: String = ""
     private(set) var fileSize: String = ""
     private(set) var size: CGSize = NSZeroSize
-    private(set) var image: NSImage = NSImage()
+    var image: NSImage = NSImage()
     var state: KMBatchProcessingTableFileState = .clock
     var progressValue: Float = 0
     var isLock: Bool = false 
     var password: String = ""
     var permissionPassword: String = ""
     
+    var type: KMBatchCollectionViewType = .convertPDF
+    
     static func initWithFilePath(url:URL) -> KMBatchProcessingTableViewModel {
         let model = KMBatchProcessingTableViewModel.init()
         let filePath = url.path

+ 2 - 1
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Presenter/KMBatchProcessingTableViewPresenter.swift

@@ -10,7 +10,7 @@ import Cocoa
 
 class KMBatchProcessingTableViewPresenter: NSObject {
     lazy var modelData: [KMBatchProcessingTableViewModel] = []
-    var view: KMBatchProcessingView?
+    var view: KMBatchProcessingTableView?
     fileprivate weak var delegate: KMBatchProcessingTableViewPresenterDelegate?
     
     /**
@@ -35,6 +35,7 @@ extension KMBatchProcessingTableViewPresenter: KMBatchProcessingTableViewPresent
      初始化presenter
      */
     func initPresenter(view:KMBatchProcessingTableView, data: [URL]) {
+        self.view = view
         self.delegate = view
         
         self.modelData.removeAll()

+ 10 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingNameTableCell.swift

@@ -11,6 +11,8 @@ import KMComponentLibrary
 class KMBatchProcessingNameTableCell: KMBatchProcessingTableCell {
     @IBOutlet var contentView: NSView!
     @IBOutlet weak var iconButton: NSButton!
+    @IBOutlet weak var iconImageView: NSImageView!
+    @IBOutlet weak var iconImageViewWidthConstraint: NSLayoutConstraint!
     
     @IBOutlet weak var nameLabel: NSTextField!
     
@@ -63,6 +65,14 @@ class KMBatchProcessingNameTableCell: KMBatchProcessingTableCell {
         self.nameLabel.stringValue = self.model.name
         
         self.iconButton.isHidden = !self.model.isLock
+        
+        if self.model.type == .imageToPDF {
+            self.iconImageView.image = self.model.image
+            self.iconImageViewWidthConstraint.constant = 40
+        } else {
+            self.iconImageView.image = nil
+            self.iconImageViewWidthConstraint.constant = -8
+        }
     }
     
     @IBAction func iconButtonAction(_ sender: Any) {

+ 17 - 5
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingNameTableCell.xib

@@ -10,17 +10,19 @@
             <connections>
                 <outlet property="contentView" destination="c22-O7-iKe" id="H1z-Vy-z59"/>
                 <outlet property="iconButton" destination="5ya-vD-YSW" id="U9j-eG-AMc"/>
+                <outlet property="iconImageView" destination="c1u-iG-YM2" id="QSS-xq-Fva"/>
+                <outlet property="iconImageViewWidthConstraint" destination="d2u-Ci-pUM" id="xDx-cB-DPX"/>
                 <outlet property="nameLabel" destination="9BP-LK-TK6" id="dAh-4P-6ZZ"/>
             </connections>
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
         <customView id="c22-O7-iKe">
-            <rect key="frame" x="0.0" y="0.0" width="146" height="40"/>
+            <rect key="frame" x="0.0" y="0.0" width="328" height="80"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>
                 <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9BP-LK-TK6">
-                    <rect key="frame" x="6" y="10" width="71" height="20"/>
+                    <rect key="frame" x="54" y="30" width="71" height="20"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="20" id="H0s-Nl-EiE"/>
                     </constraints>
@@ -31,7 +33,7 @@
                     </textFieldCell>
                 </textField>
                 <button translatesAutoresizingMaskIntoConstraints="NO" id="5ya-vD-YSW">
-                    <rect key="frame" x="79" y="14" width="12" height="12"/>
+                    <rect key="frame" x="127" y="34" width="12" height="12"/>
                     <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_base_lock" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="Bp4-WW-FZi">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                         <font key="font" metaFont="system"/>
@@ -44,15 +46,25 @@
                         <action selector="iconButtonAction:" target="-2" id="TrL-xi-xEr"/>
                     </connections>
                 </button>
+                <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="c1u-iG-YM2">
+                    <rect key="frame" x="8" y="12" width="40" height="56"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="56" id="SKi-Za-BW9"/>
+                        <constraint firstAttribute="width" constant="40" id="d2u-Ci-pUM"/>
+                    </constraints>
+                    <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="egu-zY-8bF"/>
+                </imageView>
             </subviews>
             <constraints>
-                <constraint firstItem="9BP-LK-TK6" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="8" id="Jbd-vV-F3a"/>
+                <constraint firstItem="c1u-iG-YM2" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="8" id="DPy-9S-nnx"/>
+                <constraint firstItem="9BP-LK-TK6" firstAttribute="leading" secondItem="c1u-iG-YM2" secondAttribute="trailing" constant="8" id="Gb2-73-VDt"/>
                 <constraint firstItem="9BP-LK-TK6" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="ddV-Cy-IHk"/>
                 <constraint firstItem="5ya-vD-YSW" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="dp9-du-KDu"/>
                 <constraint firstItem="5ya-vD-YSW" firstAttribute="leading" secondItem="9BP-LK-TK6" secondAttribute="trailing" constant="4" id="gKw-Mg-2Xr"/>
                 <constraint firstItem="9BP-LK-TK6" firstAttribute="width" relation="lessThanOrEqual" secondItem="c22-O7-iKe" secondAttribute="width" multiplier="0.8" id="gbo-oe-34t"/>
+                <constraint firstItem="c1u-iG-YM2" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="jug-b2-4DS"/>
             </constraints>
-            <point key="canvasLocation" x="-200" y="149"/>
+            <point key="canvasLocation" x="-109" y="190"/>
         </customView>
     </objects>
     <resources>

+ 62 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingWidthTableCell.swift

@@ -0,0 +1,62 @@
+//
+//  KMBatchProcessingWidthTableCell.swift
+//  PDF Reader Pro
+//
+//  Created by lizhe on 2025/1/17.
+//
+
+import Cocoa
+import KMComponentLibrary
+
+class KMBatchProcessingWidthTableCell: KMBatchProcessingTableCell {
+    @IBOutlet var contentView: NSView!
+    
+    @IBOutlet weak var sizeLabel: NSTextField!
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+    // MARK: 初始化
+    override init(frame frameRect: NSRect) {
+        super.init(frame: frameRect)
+        initContentView()
+        setup()
+    }
+    
+    required init?(coder decoder: NSCoder) {
+        super.init(coder: decoder)
+        initContentView()
+        setup()
+    }
+    
+    private func initContentView() {
+        //绑定xib
+        let resource = NSNib(nibNamed: String(describing: self.classForCoder.self),
+                             bundle: Bundle(for: self.classForCoder.self))!
+        resource.instantiate(withOwner: self, topLevelObjects: nil)
+        addSubview(contentView)
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            contentView.topAnchor.constraint(equalTo: topAnchor),
+            contentView.leftAnchor.constraint(equalTo: leftAnchor),
+            contentView.rightAnchor.constraint(equalTo: rightAnchor),
+            contentView.bottomAnchor.constraint(equalTo: bottomAnchor)])
+        contentView.updateConstraintsForSubtreeIfNeeded()
+    }
+    
+    override func setup() {
+        super.setup()
+        
+        self.sizeLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
+        self.sizeLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-regular")
+        
+    }
+    
+    override func reloadData() {
+        super.reloadData()
+        
+        self.sizeLabel.stringValue = "\(Int(self.model.image.size.width))x\(Int(self.model.image.size.height))"
+    }
+}

+ 37 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingWidthTableCell.xib

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchProcessingWidthTableCell" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <connections>
+                <outlet property="contentView" destination="c22-O7-iKe" id="74d-ie-zNy"/>
+                <outlet property="sizeLabel" destination="ydk-iA-hgm" id="OMz-4J-QaY"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="173" height="28"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ydk-iA-hgm">
+                    <rect key="frame" x="6" y="6" width="72" height="16"/>
+                    <textFieldCell key="cell" lineBreakMode="clipping" title="1080x1080" id="DS2-Ym-dDk">
+                        <font key="font" usesAppearanceFont="YES"/>
+                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                    </textFieldCell>
+                </textField>
+            </subviews>
+            <constraints>
+                <constraint firstItem="ydk-iA-hgm" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="8" id="YuU-ka-lA9"/>
+                <constraint firstItem="ydk-iA-hgm" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="z6S-8J-ZCf"/>
+            </constraints>
+            <point key="canvasLocation" x="81" y="178"/>
+        </customView>
+    </objects>
+</document>

+ 7 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/ImageToPDF/KMBatchImageToPDFView.swift

@@ -175,6 +175,13 @@ class KMBatchImageToPDFView: KMBatchSettingItemView {
         self.languageSelectButton.properties.isDisabled = !self.model.isOCR
         self.languageSelectButton.reloadData()
         
+        if self.model.ocrType == .google {
+            self.OCRPlan1Button.properties.checkboxType = .selected
+            self.OCRPlan2Button.properties.checkboxType = .normal
+        } else if self.model.ocrType == .apple {
+            self.OCRPlan1Button.properties.checkboxType = .normal
+            self.OCRPlan2Button.properties.checkboxType = .selected
+        }
         self.OCRPlan1Button.properties.isDisabled = !self.model.isOCR
         self.OCRPlan1Button.reloadData()
         

+ 16 - 0
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -835,6 +835,12 @@
 		AD01D7AF2D37979000D5DF2D /* KMBatchImageToPDFModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7AE2D37979000D5DF2D /* KMBatchImageToPDFModel.swift */; };
 		AD01D7B02D37979000D5DF2D /* KMBatchImageToPDFModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7AE2D37979000D5DF2D /* KMBatchImageToPDFModel.swift */; };
 		AD01D7B12D37979000D5DF2D /* KMBatchImageToPDFModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7AE2D37979000D5DF2D /* KMBatchImageToPDFModel.swift */; };
+		AD01D7BD2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7BC2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift */; };
+		AD01D7BE2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7BC2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift */; };
+		AD01D7BF2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD01D7BC2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift */; };
+		AD01D7C12D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = AD01D7C02D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib */; };
+		AD01D7C22D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = AD01D7C02D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib */; };
+		AD01D7C32D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = AD01D7C02D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib */; };
 		AD055E1F2B70B3840035F824 /* KMBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD055E1E2B70B3840035F824 /* KMBookmark.swift */; };
 		AD055E202B70B3840035F824 /* KMBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD055E1E2B70B3840035F824 /* KMBookmark.swift */; };
 		AD055E212B70B3840035F824 /* KMBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD055E1E2B70B3840035F824 /* KMBookmark.swift */; };
@@ -5044,6 +5050,8 @@
 		AD01D7A52D377D1900D5DF2D /* KMBatchImageToPDFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchImageToPDFView.swift; sourceTree = "<group>"; };
 		AD01D7A92D377D2600D5DF2D /* KMBatchImageToPDFView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMBatchImageToPDFView.xib; sourceTree = "<group>"; };
 		AD01D7AE2D37979000D5DF2D /* KMBatchImageToPDFModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchImageToPDFModel.swift; sourceTree = "<group>"; };
+		AD01D7BC2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchProcessingWidthTableCell.swift; sourceTree = "<group>"; };
+		AD01D7C02D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMBatchProcessingWidthTableCell.xib; sourceTree = "<group>"; };
 		AD032CB62A4E6A7E00F1D745 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Starscream.framework; sourceTree = "<group>"; };
 		AD055E1E2B70B3840035F824 /* KMBookmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBookmark.swift; sourceTree = "<group>"; };
 		AD055E232B70B3C10035F824 /* KMBookmarkController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBookmarkController.swift; sourceTree = "<group>"; };
@@ -8711,6 +8719,8 @@
 				AD8B59C62D2B778D00150EA6 /* KMBatchProcessingStateTableCell.xib */,
 				AD8B59CD2D2B778D00150EA6 /* KMBatchProcessingTableCell.swift */,
 				AD8B59C92D2B778D00150EA6 /* KMBatchProcessingTableRowView.swift */,
+				AD01D7BC2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift */,
+				AD01D7C02D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -13247,6 +13257,7 @@
 				ADBC16082D2E2081000ACD95 /* KMBatchOCRView.xib in Resources */,
 				BB6347C82AF24F6C00F5438E /* KMBatchoperateConvertCollectionViewItem.xib in Resources */,
 				BB183DD42B4EAD5400F99C7E /* Ubuntu-Bold.ttf in Resources */,
+				AD01D7C12D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */,
 				BB031B5A2C47BB080099F7AD /* KMUserFbHelpPopController.xib in Resources */,
 				ADD1B6CB2942E85300C3FFF7 /* KMPrintBottomView.xib in Resources */,
 				89752DB02936F505003FF08E /* KMCustomButtonPopMenuViewController.xib in Resources */,
@@ -13556,6 +13567,7 @@
 				AD2BF2292B5608700029F03F /* Assets.xcassets in Resources */,
 				AD8B598F2D2B777700150EA6 /* KMBatchWatermarkView.xib in Resources */,
 				BB86C2A32BC8C39600326A6B /* ExportAccessoryView.xib in Resources */,
+				AD01D7C22D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */,
 				BB4F7E9A2B0C858D0077EC8C /* KMNoteTypeCollectionViewItem.xib in Resources */,
 				651675ED2CE3313500019A20 /* KMOutlineEditViewController.xib in Resources */,
 				BB0308602CC7A40A00F4AAC7 /* KMPDFSideBarController.xib in Resources */,
@@ -14294,6 +14306,7 @@
 				BB1E7F2E2B4FE2C6002D9785 /* GuideInfoImages.xcassets in Resources */,
 				BBAFC84F298519F700D0648E /* KMSavePanelAccessoryController.xib in Resources */,
 				656C1E642CD0DFF400295F82 /* KMConvertJsonSettingView.xib in Resources */,
+				AD01D7C32D39F9ED00D5DF2D /* KMBatchProcessingWidthTableCell.xib in Resources */,
 				ADDF83A62B391A5D00A81A4E /* DSignatureConfigWindowController.xib in Resources */,
 				BB19A76D2CB7D107008204DC /* KMHomeFilesEmptyHeaderView.xib in Resources */,
 				9F8539D029430BF300DF644E /* KMBrowserWindowController.xib in Resources */,
@@ -14722,6 +14735,7 @@
 				ADE86AF72B0AF59A00414DFA /* KMCompareContentSettingView.swift in Sources */,
 				ADDF834D2B391A5C00A81A4E /* DSignatureCertifyDetailViewController.swift in Sources */,
 				BBA922182B4E783F0061057A /* KMPurchaseCompareDMGWindowController.m in Sources */,
+				AD01D7BD2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */,
 				ADD1B6AB2941E97F00C3FFF7 /* KMPrintWindowController.swift in Sources */,
 				65157BA02D02DD790005F3A8 /* KMNBotaAnnotationModel.swift in Sources */,
 				F3599222292CA27B000D25DE /* CPDFListViewRuntime.m in Sources */,
@@ -16390,6 +16404,7 @@
 				BB403BAB2B15CA6E00B3106D /* KMBatchConvertOperation.swift in Sources */,
 				ADDEEA732AD3EFE200EF675D /* KMButton.swift in Sources */,
 				BB67EE272B54FFEF00573BF0 /* ASINetworkQueue.m in Sources */,
+				AD01D7BE2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */,
 				AD8B59712D2B777700150EA6 /* KMBatchConverPDFImageView.swift in Sources */,
 				656C1E5F2CD0DFE900295F82 /* KMConvertJsonSettingView.swift in Sources */,
 				BB2F9AB92AFCC3AD00F9DD93 /* KMProfileInfo.swift in Sources */,
@@ -17008,6 +17023,7 @@
 				BB183DE52B4EC0AF00F99C7E /* KMRepeatVerifyExpireController.m in Sources */,
 				BB7256BF2CDC5B5300B6CE64 /* KMBackgroundController.swift in Sources */,
 				655445102C88483C00BD9010 /* KMDiscountToSaveWindowController.m in Sources */,
+				AD01D7BF2D39F9DD00D5DF2D /* KMBatchProcessingWidthTableCell.swift in Sources */,
 				BB5F8A1029BB04F000365ADB /* GBDeviceInfo_OSX.m in Sources */,
 				BB0782FA2CD0BDCA00101C81 /* KMPageNumberPromptView.swift in Sources */,
 				BBEDC2292B98205200970C54 /* Bundle+KMExtension.swift in Sources */,