Swift 3中如何让UIImage按UIPrintInfo页面比例适配打印?
解决Epson TM-T88V打印机打印UIImage尺寸过小的适配问题
嘿,我之前对接Epson热敏小票打印机时也踩过这个坑!TM-T88V这类打印机的纸张宽度是固定的(常见58mm或80mm),直接打印转好的UIImage往往会因为系统默认的打印页面尺寸不匹配,导致内容被压缩得很小。下面给你几个针对性的解决方案:
方案一:按打印机实际页面尺寸重新渲染UIImage
这种方式会先获取打印机的可打印区域宽高,然后按比例缩放你的标记视图生成适配的图片,确保内容填满小票宽度:
步骤1:获取打印机的可打印尺寸
func getPrinterPaperSize() -> CGSize? { let printController = UIPrintInteractionController.shared guard let printer = printController.printInfo.printer else { return nil } // 获取打印机支持的纸张类型,TM-T88V通常对应小票纸 for paper in printer.supportedPapers { if paper.paperSize == .roll58mm || paper.paperSize == .roll80mm { return paper.printableRect.size } } // 如果获取不到,用默认的小票尺寸兜底(比如80mm宽,换算成点:80mm * 3.779527559 ≈ 302点) return CGSize(width: 302, height: CGFloat.greatestFiniteMagnitude) }
步骤2:按比例缩放生成适配图片
假设你的标记视图是markedView,先把它转成UIImage,再按打印机尺寸缩放:
func generatePrintableImage(from view: UIView) -> UIImage? { guard let printerSize = getPrinterPaperSize() else { return nil } // 先把视图转成原始图片 UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale) view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) let originalImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() guard let original = originalImage else { return nil } // 计算缩放比例:以打印机宽度为基准,保持原图宽高比 let scale = printerSize.width / original.size.width let scaledHeight = original.size.height * scale // 生成适配后的图片 UIGraphicsBeginImageContextWithOptions(CGSize(width: printerSize.width, height: scaledHeight), false, UIScreen.main.scale) original.draw(in: CGRect(x: 0, y: 0, width: printerSize.width, height: scaledHeight)) let printableImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return printableImage }
方案二:直接用PDF打印(推荐!)
既然你分享时转PDF的效果已经符合预期,那打印时完全可以复用这套逻辑——PDF是矢量格式,能完美适配打印机的纸张尺寸,不会出现缩放模糊或尺寸不对的问题:
把UIView转成PDF数据流
func generatePDFData(from view: UIView) -> Data? { let pdfRenderer = UIGraphicsPDFRenderer(bounds: view.bounds) return pdfRenderer.pdfData { context in context.beginPage() view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) } }
配置打印控制器使用PDF打印
func printMarkedView() { let printController = UIPrintInteractionController.shared let printInfo = UIPrintInfo(dictionary: nil) printInfo.outputType = .general printInfo.jobName = "Receipt Print" printController.printInfo = printInfo // 使用PDF数据打印 guard let pdfData = generatePDFData(from: markedView) else { return } printController.printingItem = pdfData // 弹出打印界面 printController.present(animated: true) { _, completed, error in if let error = error { print("打印出错:\(error.localizedDescription)") } } }
这个方案不仅能解决尺寸问题,还能保证打印内容的清晰度,和你邮件分享的逻辑也统一,维护起来更方便。
内容的提问来源于stack exchange,提问作者Muthu Sabarinathan
相关产品推荐
相关产品推荐

