我正在尝试使用 swift 创建一个 iOS 应用程序,让用户可以拍照或从图库中选择图像,并将其转换为可以保存到手机上的 pdf 文件。我的代码当前可以打开相机或图库并选择图像,但我无法将其转换为 pdf。 任何提示将不胜感激,谢谢!
CameraViewController 类
import UIKit
class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate
{
@IBOutlet weak var myImg: UIImageView!
@IBAction func takePhoto(_ sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
myImg.contentMode = .scaleToFill
myImg.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
@IBAction func savePhoto(_ sender: AnyObject) {
let imageData = UIImagePNGRepresentation(myImg.image!)
let compressedImage = UIImage(data: imageData!)
UIImageWriteToSavedPhotosAlbum(compressedImage!, nil, nil, nil)
let alert = UIAlertController(title: "Saved", message: "Your image has been saved", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
GalleryViewController 类
import UIKit
class GalleryViewController: UIViewController {
@IBOutlet weak var myImg: UIImageView!
@IBAction func pickPhoto(_ sender: Any) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
myImg.contentMode = .scaleToFill
myImg.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
答案已更新:
自从Apple将PDFKit引入iOS 11.0以来,您可以使用下面的代码将uiimage转换为pdf,我只尝试了下面的osx,但它在iOS上应该以相同的方式工作。
// Create an empty PDF document
let pdfDocument = PDFDocument()
// Load or create your UIImage
let image = UIImage(....)
// Create a PDF page instance from your image
let pdfPage = PDFPage(image: image!)
// Insert the PDF page into your document
pdfDocument.insert(pdfPage!, at: 0)
// Get the raw data of your PDF document
let data = pdfDocument.dataRepresentation()
// The url to save the data to
let url = URL(fileURLWithPath: "/Path/To/Your/PDF")
// Save the data to the url
try! data!.write(to: url)
====================================================
实际上有很多类似的问题和足够好的答案。让我再次尝试回答这个问题。
生成PDF基本上和iOS中绘图类似。
所以最简单的方法是这样的:
func createPDF(image: UIImage) -> NSData? {
let pdfData = NSMutableData()
let pdfConsumer = CGDataConsumer(data: pdfData as CFMutableData)!
var mediaBox = CGRect.init(x: 0, y: 0, width: image.size.width, height: image.size.height)
let pdfContext = CGContext(consumer: pdfConsumer, mediaBox: &mediaBox, nil)!
pdfContext.beginPage(mediaBox: &mediaBox)
pdfContext.draw(image.cgImage!, in: mediaBox)
pdfContext.endPage()
return pdfData
}
创建了 PDF 文件的所有 NSData,然后我们需要将数据保存到文件中:
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let docURL = documentDirectory.appendingPathComponent("myFileName.pdf")
try createPDF(image: someUIImageFile)?.write(to: docURL, atomically: true)
在此处阅读更多信息:生成 PDF 内容
在 swift 5 中使用 PDFKit : 首次导入PDFKit
然后使用这个数组扩展:
import UIKit
import PDFKit
extension Array where Element: UIImage {
func makePDF()-> PDFDocument {
let pdfDocument = PDFDocument()
for (index,image) in self.enumerated() {
let pdfPage = PDFPage(image: image)
pdfDocument.insert(pdfPage!, at: index)
}
return pdfDocument
}
}
并且使用这个:
let imageArray = [UIImage(named: "1")!,UIImage(named: "2")!] let yourPDF = imageArray.makePDF()
Swift 5 我们将使用 UIGraphicsPDFRenderer() 类,它将适用于 iOS 10+
let image = results.croppedScan.image
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let docURL = documentDirectory.appendingPathComponent("Scanned-Docs.pdf")
let outputFileURL: URL = docURL
let imageBounds = CGRect(origin: .zero, size: image.size)
let pdfRenderer = UIGraphicsPDFRenderer(bounds: imageBounds)
do {
try pdfRenderer.writePDF(to: outputFileURL) { context in
context.beginPage()
results.croppedScan.image.draw(in: imageBounds)
}
} catch {
print("Could not create PDF file: \(error)")
}
print("save at ===\(outputFileURL)")
//Show PDF in Controller
let dc = UIDocumentInteractionController(url: outputFileURL)
dc.delegate = self
dc.presentPreview(animated: true)
func exportToPDF(_ uiImage:UIImage) {
let outputFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("testing" + ".pdf")
let pageSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size: uiImage.size))
DispatchQueue.main.async {
do {
let imageBounds = CGRect(origin: .zero, size: uiImage.size)
try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
context.beginPage()
uiImage.draw(in: imageBounds)
})
print("wrote file to: \(outputFileURL.path)")
var documentoPath = outputFileURL.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: documentoPath){
let documento = NSData(contentsOfFile: documentoPath)
let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [documento!], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true, completion: nil)
}
else {
print("wrote file to: No Document \(outputFileURL.path)")
}
} catch {
print("Could not create PDF file: \(error.localizedDescription)")
}
}
}