You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIGraphicsImageRenderer无法渲染PDFPage中二维码的技术求助

问题解决:PDF页面二维码未渲染的修复方案

你遇到的问题大概率是PDF内容区域识别错误,或是渲染上下文配置没覆盖到某些PDF元素特性,以下是几种可行的修复思路:

1. 切换PDF页面的Box类型

很多PDF的实际内容会放在cropBox而非mediaBox里,原代码用mediaBox可能拿到超出实际内容的区域,导致元素渲染偏移或丢失。修改代码里的Box类型试试:

private func imageFromPDF(page: CGPDFPage) -> UIImage {
    // 替换为cropBox获取实际内容区域
    let pageRect = page.getBoxRect(.cropBox)
    let renderer = UIGraphicsImageRenderer(size: pageRect.size)
    let image = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(pageRect)
        ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
        ctx.cgContext.drawPDFPage(page)
    }
    return image
}

2. 添加PDF页面旋转适配

部分PDF页面带有旋转属性,直接渲染会导致内容裁切或偏移。可以先获取页面旋转角度,调整上下文变换:

private func imageFromPDF(page: CGPDFPage) -> UIImage {
    let pageRect = page.getBoxRect(.cropBox)
    // 获取页面旋转角度
    let rotationAngle = page.rotationAngle
    var renderSize = pageRect.size
    
    // 根据旋转调整渲染尺寸
    if rotationAngle == 90 || rotationAngle == 270 {
        renderSize = CGSize(width: pageRect.height, height: pageRect.width)
    }
    
    let renderer = UIGraphicsImageRenderer(size: renderSize)
    let image = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(CGRect(origin: .zero, size: renderSize))
        
        // 先居中、旋转,再平移回原位置
        ctx.cgContext.translateBy(x: renderSize.width/2, y: renderSize.height/2)
        ctx.cgContext.rotate(by: CGFloat(rotationAngle * .pi / 180))
        ctx.cgContext.translateBy(x: -pageRect.width/2, y: -pageRect.height/2)
        
        ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
        
        ctx.cgContext.drawPDFPage(page)
    }
    return image
}

3. 调整渲染上下文配置

如果二维码是带透明通道或特殊颜色空间的元素,可以给UIGraphicsImageRenderer指定更全面的配置:

private func imageFromPDF(page: CGPDFPage) -> UIImage {
    let pageRect = page.getBoxRect(.cropBox)
    let format = UIGraphicsImageRendererFormat()
    // 开启透明通道支持
    format.opaque = false
    // 使用屏幕原生分辨率
    format.scale = UIScreen.main.scale
    
    let renderer = UIGraphicsImageRenderer(size: pageRect.size, format: format)
    let image = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(pageRect)
        
        ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
        ctx.cgContext.drawPDFPage(page)
    }
    return image
}

优先尝试第一种方案,大部分这类问题都是Box类型选错导致的。如果仍未解决,再结合旋转适配和上下文配置调整。

内容的提问来源于stack exchange,提问作者Konstantin.Efimenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:35:25