使用UIGraphicsPDFRenderer设置图像质量:Aztec条码模糊问题
解决Aztec条码绘制到PDF模糊的问题
你的问题根源在于:通过CIFilter生成的CIImage默认尺寸极小,转成CGImage后是低分辨率位图,绘制到PDF的目标矩形时相当于被放大,导致模糊。设置interpolationQuality仅能调整位图缩放的插值方式,无法解决低分辨率本身带来的模糊问题。
以下是两种可行的解决方案:
方案一:直接绘制矢量形式的条码(推荐)
跳过转成UIImage的步骤,直接将CIImage渲染到PDF的CGContext中,保留矢量特性,避免位图缩放模糊:
let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 70.8661, height: 70.8661)) return renderer.pdfData { ctx in ctx.beginPage() let cgContext = ctx.cgContext // 初始化Aztec条码生成器 guard let aztecFilter = CIFilter(name: "CIAztecCodeGenerator") else { return } aztecFilter.setValue(Data(UUID().description.utf8), forKey: kCIInputMessageKey) guard let outputImage = aztecFilter.outputImage else { return } // 计算缩放比例,让条码填满目标区域 let scale = min(renderer.bounds.width / outputImage.extent.width, renderer.bounds.height / outputImage.extent.height) cgContext.scaleBy(x: scale, y: scale) // 直接渲染CIImage到PDF上下文,无位图转换 let ciContext = CIContext(cgContext: cgContext, options: [.interpolationQuality: CIInterpolationQuality.none]) ciContext.draw(outputImage, in: outputImage.extent) }
方案二:生成高分辨率位图后绘制
如果必须使用UIImage,生成与PDF目标尺寸匹配的高分辨率位图,避免缩放:
func generateAztecCode(from string: String, targetSize: CGSize) -> UIImage? { guard let filter = CIFilter(name: "CIAztecCodeGenerator") else { return nil } filter.setValue(Data(string.utf8), forKey: kCIInputMessageKey) guard let outputImage = filter.outputImage else { return nil } // 按目标尺寸缩放CIImage let scaleX = targetSize.width / outputImage.extent.width let scaleY = targetSize.height / outputImage.extent.height let scaledImage = outputImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY)) // 生成高分辨率CGImage let ciContext = CIContext(options: [.interpolationQuality: CIInterpolationQuality.none]) guard let cgImage = ciContext.createCGImage(scaledImage, from: scaledImage.extent) else { return nil } return UIImage(cgImage: cgImage) } // 调用代码 let targetSize = CGSize(width: 70.8661, height: 70.8661) let renderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size: targetSize)) return renderer.pdfData { ctx in ctx.beginPage() let cgContext = ctx.cgContext cgContext.interpolationQuality = .none if let barcode = generateAztecCode(from: UUID().description, targetSize: targetSize) { barcode.draw(in: CGRect(origin: .zero, size: targetSize)) } }
内容的提问来源于stack exchange,提问作者user3533049
相关产品推荐
相关产品推荐

