Post

Replies

Boosts

Views

Activity

App crashes (UIGraphicsImageRenderer, PDF to images with PDFKit)
Hello, fams! I have a probably stupid question for you guys who're coding in Swift. I'm extracting images from PDF with PDFKit and everything works well if there are a few pages. If there are many pages my app crashes and doesn't produce any crash log (I check error logs in XCode > Device and Simulators > Device log). I can guess that iOS terminates the app because methods I use are blocking UI thread for a long time. Could anyone suggest me what to do to improve that? Is there a way to achieve the same result using other methods that can be ran on a background thread? That's an example I found on the internet of how to extract image from PDF page: guard let path = Bundle.main.path(forResource: "filename", ofType: "pdf") else { return } let url = URL(fileURLWithPath: path) // Instantiate a `CGPDFDocument` from the PDF file's URL. guard let document = PDFDocument(url: url) else { return } // Get the first page of the PDF document. guard let page = document.page(at: 0) else { return } // Fetch the page rect for the page we want to render. let pageRect = page.bounds(for: .mediaBox) let renderer = UIGraphicsImageRenderer(size: pageRect.size) let img = renderer.image { ctx in // Set and fill the background color. UIColor.white.set() ctx.fill(CGRect(x: 0, y: 0, width: pageRect.width, height: pageRect.height)) // Translate the context so that we only draw the `cropRect`. ctx.cgContext.translateBy(x: -pageRect.origin.x, y: pageRect.size.height - pageRect.origin.y) // Flip the context vertically because the Core Graphics coordinate system starts from the bottom. ctx.cgContext.scaleBy(x: 1.0, y: -1.0) // Draw the PDF page. page.draw(with: .mediaBox, to: ctx.cgContext) }` Since I'm a .net developer and use C#, I've rewrote this code for my needs in C# and added loop to extract images from all PDF pages. Please, take a look: public IEnumerable<byte[]> ExtractImagesFromPdf(string pathToPdf) { using var data = NSData.FromFile(pathToPdf); using var doc = new PdfDocument(data); var bytesOfImages = new List<byte[]>(); for (int i = 0; i < doc.PageCount; i++) { var page = doc.GetPage(i); var pageRect = page.GetBoundsForBox(PdfDisplayBox.Media); using var renderer = new UIGraphicsImageRenderer(pageRect.Size); var img = renderer.CreateJpeg(100, (ctx) => { UIColor.White.SetColor(); ctx.FillRect(new CoreGraphics.CGRect(0, 0, pageRect.Width, pageRect.Height)); ctx.CGContext.TranslateCTM(-pageRect.X, pageRect.Size.Height - pageRect.Y); ctx.CGContext.ScaleCTM(1.0f, -1.0f); page.Draw(PdfDisplayBox.Media, ctx.CGContext); }); bytesOfImages.Add(img.ToArray()); } return bytesOfImages; } Thanks in advance!
2
0
2k
Nov ’21