在使用 PDFKit 打印为 PDF 之前调整 UIImage 的大小 – Swift/Xcode

Resize UIImage before printing to PDF with PDFKit – Swift/Xcode

我很困惑。我的应用程序允许用户使用 camera/photo 相册拍照,然后在应用程序结束时将这些照片打印成 PDF(使用 PDFKit)。我尝试了 NUMEROUS 种方法来调整照片大小,使 PDF 不会太大(约 13 张照片 8mb)。但是,我无法让它工作!

这是我尝试过的一种解决方案:

func resizeImage(image: UIImage) -> UIImage {
        
        if image.size.height >= 1024 && image.size.width >= 1024 {
            UIGraphicsBeginImageContext(CGSize(width: 1024, height: 1024))
            image.draw(in: CGRect(x: 0, y: 0, width: 1024, height: 1024))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else if image.size.height >= 1024 && image.size.width < 1024 {
            UIGraphicsBeginImageContext(CGSize(width: image.size.width, height: 1024))
            image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: 1024))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else if image.size.width >= 1024 && image.size.height < 1024 {
            UIGraphicsBeginImageContext(CGSize(width: 1024, height: image.size.height))
            image.draw(in: CGRect(x: 0, y: 0, width: 1024, height: image.size.height))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else {
            return image
        }
        
    }

我这样称呼它:

let theResizedImage = resizeImage(image: image)

这有效...有点。它将图像大小调整为之前的四分之一左右(仍然不是很好......但更好)。但问题是:当我将“theResizedImage”绘制到 PDF 时...

theResizedImage.draw(in: photoRect)

...PDF 文件最终是以前的 TWICE 倍!!如何?!?!?!我不明白世界上如何调整大小的图像在绘制到 原始 形式时突然变成原来的两倍PDF.

有人请帮我解决这个问题。如果您有更好的方法可以进一步调整图像的大小,那就太棒了!我不确定您是否熟悉名为 pdfFactoryPro 的软件(在 PC 上),但它会调整 HUGE 的大小(例如 40 something mb) file into one that's like... 3 mb.我需要大量调整这些图像的大小。我需要它们在打印为 PDF 时保持较小的尺寸,以便 PDF 较小。另一种选择是,如果您知道某种调整 PDF 本身大小的方法,就像 pdfFactoryPro 那样。

请使用代码或 link 教程彻底解释您的答案。我是初学者...如果你不知道。

注意:请确保您的代码响应设置为将图像传递给函数...而不是 URL。正如我之前所说,我正在调整用户用相机拍摄的照片的大小,这些照片是从应用程序 (imagePickerController) 中访问的。

谢谢!

编辑: 我通过大量谷歌搜索发现,即使您使用 UIImageJPEGRepresentation 调整图像大小,当您将图像打印为 PDF 时,也会打印 RAW 图像压缩图像。

名为“Michael McNabb”的人发布了此解决方案,但由于是在 2013 年,它确实已经过时了:

NSData *jpegData = UIImageJPEGRepresentation(sourceImage, 0.75);
CGDataProviderRef dp = CGDataProviderCreateWithCFData((__bridge CFDataRef)jpegData);
CGImageRef cgImage = CGImageCreateWithJPEGDataProvider(dp, NULL, true, kCGRenderingIntentDefault);
[[UIImage imageWithCGImage:cgImage] drawInRect:drawRect];

有人可以帮我把这个翻译成 Swift 5 吗?这可能是我问题的答案。

func draw(image: UIImage, in rect: CGRect) {
    guard let jpegData = image.jpegData(compressionQuality: 0.75),
          let dataProvider = CGDataProvider(data: jpegData as CFData),
          let cgImage = CGImage(jpegDataProviderSource: dataProvider, decode: nil, shouldInterpolate: true, intent: .defaultIntent) else {
        return
    }
    UIImage(cgImage: cgImage).draw(in: rect)
}

事实证明,调整图像大小以打印为 PDF 不仅仅是一项任务。这是两个任务。

第一个任务是调整照片大小。例如,如果您不希望照片超过 1MB,则可以将照片大小调整为 1024x1024。如果您希望像素质量能够更低,那么您可以根据需要进行更改。

调整大小示例:

func resizeImage(image: UIImage) -> UIImage {
        let maxSize = CGFloat(768)
        
        if image.size.height >= maxSize && image.size.width >= maxSize {
            UIGraphicsBeginImageContext(CGSize(width: maxSize, height: maxSize))
            image.draw(in: CGRect(x: 0, y: 0, width: maxSize, height: maxSize))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else if image.size.height >= maxSize && image.size.width < maxSize {
            UIGraphicsBeginImageContext(CGSize(width: image.size.width, height: maxSize))
            image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: maxSize))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else if image.size.width >= maxSize && image.size.height < maxSize {
            UIGraphicsBeginImageContext(CGSize(width: maxSize, height: image.size.height))
            image.draw(in: CGRect(x: 0, y: 0, width: maxSize, height: image.size.height))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else {
            return image
        }
        
    }

免责声明:我从 Whosebug 上的另一个人那里学到了这段代码。我不记得他的名字了,但要感谢他。

其次,然后压缩调整大小的图像。我不完全了解压缩,但我将我的设置为非常低的东西哈哈 – 随心所欲。

压缩示例:

func draw(image: UIImage, in rect: CGRect) {
        guard let oldImageData = image.jpegData(compressionQuality: 1) else {
            return
        }
        print("The size of the oldImage, before compression, is: \(oldImageData.count)")
        guard let jpegData = image.jpegData(compressionQuality: 0.05),
              let dataProvider = CGDataProvider(data: jpegData as CFData),
              let cgImage = CGImage(jpegDataProviderSource: dataProvider, decode: nil, shouldInterpolate: true, intent: .defaultIntent) else {
            return
        }
        let newImage = UIImage(cgImage: cgImage)
        print("The size of the newImage printed on the pdf is: \(jpegData.count)")
        newImage.draw(in: rect)
    }

免责声明:我从一个名叫 Michael McNabb 的人那里学到了这段代码。归功于他。

我继续在该函数的末尾将图像绘制为 PDF。这两件事加在一起使我的 PDF 从大约 24MB 左右增加到大约 570 KB。