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

问题描述

我很困惑。我的应用程序允许用户使用相机/相册拍照,然后在应用程序结束时将这些照片打印为 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,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,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 文件最终比以前大 两倍!!如何?!?!?!我不明白在世界上如何调整大小的图像一旦被绘制到 PDF 上就会突然比其原始形式大两倍。

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

请用代码或教程链接彻底解释您的答案。我是初学者……如果你不知道的话。

注意:请确保您的代码响应是以将图像传递给函数的方式设置的……而不是 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,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,height: image.size.height))
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage!
        }
        else {
            return image
        }
        
    }

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

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

压缩示例:

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),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。