Allow users to browse, edit, and save images using slideshows and Core Image filters using Quartz.

Posts under Quartz tag

7 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Crash when rendering CALayer using UIGraphicsImageRenderer on background thread
Hello! I’m experiencing a crash in my iOS/iPadOS app related to a CALayer rendering process. The crash occurs when attempting to render a UIImage on a background thread. The crashes are occurring in our production app, and while we can monitor them through Crashlytics, we are unable to reproduce the issue in our development environment. Relevant Code I have a custom view controller that handles rendering CALayers onto images. This method creates a CALayer on the main thread and then starts a detached task to render this CALayer into a UIImage. The whole idea is learnt from this StackOverflow post: https://stackoverflow.com/a/77834613/9202699 Here are key parts of my implementation: class MyViewController: UIViewController { @MainActor func renderToUIImage(size: CGSize, itemsToDraw: [MyDrawingItem], transform: CGAffineTransform) async -> UIImage? { // Create CALayer and add it to the view. CATransaction.begin() let customLayer = MyDrawingLayer() customLayer.setupContent(itemsToDraw: itemsToDraw) // Position the frame off-screen to it hidden. customLayer.frame = CGRect( origin: CGPoint(x: -100 - size.width, y: -100 - size.height), size: size) customLayer.masksToBounds = true customLayer.drawsAsynchronously = true view.layer.addSublayer(customLayer) CATransaction.commit() // Render CALayer to UIImage in background thread. let image = await Task.detached { customLayer.setNeedsDisplay() let renderer = UIGraphicsImageRenderer(size: size) let image = renderer.image { // CRASH happens on this line let cgContext = $0.cgContext cgContext.saveGState() cgContext.concatenate(transform) customLayer.render(in: cgContext) cgContext.restoreGState() } return image }.value // Remove the CALayer from the view. CATransaction.begin() customLayer.removeFromSuperlayer() CATransaction.commit() return image } } class MyDrawingLayer: CALayer { var itemsToDraw: [MyDrawingItem] = [] func setupContent(itemsToDraw: [MyDrawingItem]) { self.itemsToDraw = itemsToDraw } override func draw(in ctx: CGContext) { for item in itemsToDraw { // Render the item to the context (example pseudo-code). // All items are thread-safe to use. // Things to draw may include CGPath, CGImages, UIImages, NSAttributedString, etc. item.draw(in: ctx) } } } Crash Log The crash occurs at the following location: Crashed: com.apple.root.default-qos.cooperative 0 MyApp 0x5cb300 closure #1 in closure #1 in MyViewController.renderToUIImage(size: CGSize, itemsToDraw: [MyDrawingItem], transform: CGAffineTransform) + 4313002752 (<compiler-generated>:4313002752) 1 MyApp 0x5cb300 closure #1 in closure #1 in MyViewController.renderToUIImage(size: CGSize, itemsToDraw: [MyDrawingItem], transform: CGAffineTransform) + 4313002752 (<compiler-generated>:4313002752) 2 MyApp 0x1a4578 AnyModifier.modified(for:) + 4308649336 (<compiler-generated>:4308649336) 3 MyApp 0x7b4e64 thunk for @escaping @callee_guaranteed (@guaranteed UIGraphicsPDFRendererContext) -> () + 4315008612 (<compiler-generated>:4315008612) 4 UIKitCore 0x1489c0 -[UIGraphicsRenderer runDrawingActions:completionActions:format:error:] + 324 5 UIKitCore 0x14884c -[UIGraphicsRenderer runDrawingActions:completionActions:error:] + 92 6 UIKitCore 0x148778 -[UIGraphicsImageRenderer imageWithActions:] + 184 7 MyApp 0x5cb1c0 closure #1 in MyViewController.renderToUIImage(size: CGSize, itemsToDraw: [MyDrawingItem], transform: CGAffineTransform) + 100 (FileName.swift:100) 8 libswift_Concurrency.dylib 0x60f5c swift::runJobInEstablishedExecutorContext(swift::Job*) + 252 9 libswift_Concurrency.dylib 0x62514 swift_job_runImpl(swift::Job*, swift::SerialExecutorRef) + 144 10 libdispatch.dylib 0x15ec0 _dispatch_root_queue_drain + 392 11 libdispatch.dylib 0x166c4 _dispatch_worker_thread2 + 156 12 libsystem_pthread.dylib 0x3644 _pthread_wqthread + 228 13 libsystem_pthread.dylib 0x1474 start_wqthread + 8 Questions Is it safe to run UIGraphicsImageRenderer.image on the background thread? Given that I want to leverage GPU rendering, what are some best practices for rendering images off the main thread while ensuring stability? Are there alternatives to using UIGraphicsImageRenderer for background rendering that can still take advantage of GPU rendering? It is particularly interesting that the crash logs indicate the error may be related to UIGraphicsPDFRendererContext (crash log line number 3). It would be very helpful if someone could explain the connection between starting and drawing on a UIGraphicsImageRenderer and UIGraphicsPDFRendererContext. Any insights or guidance on this issue would be greatly appreciated. Thanks!!!
1
0
159
1w
How to create CGContext with 10 bits per component?
I’m trying to create a CGContext that matches my screen using the following code let context = CGContext( data: pixelBuffer, width: pixelWidth, // 3456 height: pixelHeight, // 2234 bitsPerComponent: 10, // PixelEncoding = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB" bytesPerRow: bytesPerRow, // 13824 space: CGColorSpace(name: CGColorSpace.extendedSRGB)!, bitmapInfo: CGImageAlphaInfo.none.rawValue | CGImagePixelFormatInfo.RGBCIF10.rawValue | CGImageByteOrderInfo.order16Little.rawValue ) But it fails with an error CGBitmapContextCreate: unsupported parameter combination: RGB 10 bits/component, integer 13824 bytes/row kCGImageAlphaNone kCGImageByteOrder16Little kCGImagePixelFormatRGBCIF10 Valid parameters for RGB color space model are: 16 bits per pixel, 5 bits per component, kCGImageAlphaNoneSkipFirst 32 bits per pixel, 8 bits per component, kCGImageAlphaNoneSkipFirst 32 bits per pixel, 8 bits per component, kCGImageAlphaNoneSkipLast 32 bits per pixel, 8 bits per component, kCGImageAlphaPremultipliedFirst 32 bits per pixel, 8 bits per component, kCGImageAlphaPremultipliedLast 32 bits per pixel, 10 bits per component, kCGImageAlphaNone|kCGImagePixelFormatRGBCIF10|kCGImageByteOrder16Little 64 bits per pixel, 16 bits per component, kCGImageAlphaPremultipliedLast 64 bits per pixel, 16 bits per component, kCGImageAlphaNoneSkipLast 64 bits per pixel, 16 bits per component, kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents|kCGImageByteOrder16Little 64 bits per pixel, 16 bits per component, kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents|kCGImageByteOrder16Little 128 bits per pixel, 32 bits per component, kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents 128 bits per pixel, 32 bits per component, kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents See Quartz 2D Programming Guide (available online) for more information. Why is it unsupported if it matches the 6th option? (32 bits per pixel, 10 bits per component, kCGImageAlphaNone|kCGImagePixelFormatRGBCIF10|kCGImageByteOrder16Little)
3
0
407
Jan ’25
Save UIImage with CATransform3D applied
I have a 3х3 Matrix which I need to apply to UIImage and save it in Documents folder. I successfully converted the 3x3 Matrix (represented as [[Double]]) to CATrasform3D and then I have broken my head with trying to figure out how to apply it to UIImage. The only property where I can I apply it is UIView(or UIImageView in case with working with UIImage) transform property. But it has nothing to do with UIImage itself. I can't save the UIImage from transformed the UIImageView with all the transformations. And all the CoreGraphic methods (like concatenate for CGContext) only work with affine transformations which not suits for me. Please give me a hint what direction I should look. Does Apple has native methods or I have to use 3rd party frameworks for this functionality?
1
0
592
Aug ’24
Crash in CAMediaTimingCopyRenderTiming
Hi Team, We are facing crash in CAMediaTimingCopyRenderTiming for production users. And we are unable to trace the crash. Below is the crash stack trace - Crashed: com.apple.main-thread 0 QuartzCore 0x14b9c CAMediaTimingCopyRenderTiming + 660 1 QuartzCore 0xfa9c -[CAAnimation _setCARenderAnimation:layer:] + 64 2 QuartzCore 0x146e4 -[CAAnimationGroup _copyRenderAnimationForLayer:] + 356 3 QuartzCore 0x12f3c CA::Layer::commit_animations(CA::Transaction*, double ()(CA::Layer, double, void*), void ()(CA::Layer, CA::Render::Animation*, void*), void ()(CA::Layer, __CFString const*, void*), CA::Render::TimingList* ()(CA::Layer, void*), void*) + 688 4 QuartzCore 0x277c invocation function for block in CA::Context::commit_transaction(CA::Transaction*, double, double*) + 176 5 QuartzCore 0x482bc CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 384 6 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 7 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 8 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 9 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 10 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 11 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 12 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 13 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 14 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 15 QuartzCore 0x48244 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 264 16 QuartzCore 0x2e078 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 6224 17 QuartzCore 0x59dc0 CA::Transaction::commit() + 644 18 QuartzCore 0x44dbc CA::Transaction::flush_as_runloop_observer(bool) + 84 19 CoreFoundation 0x898e8 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 32 20 CoreFoundation 0x1951c __CFRunLoopDoObservers + 552 21 CoreFoundation 0x75214 __CFRunLoopRun + 1004 22 CoreFoundation 0x79d20 CFRunLoopRunSpecific + 584 23 GraphicsServices 0x1998 GSEventRunModal + 160 24 UIKitCore 0x371448 -[UIApplication _run] + 868 25 UIKitCore 0x3710c0 UIApplicationMain + 312 26 SwiftUI 0x183c68 OUTLINED_FUNCTION_895 + 2184 27 SwiftUI 0xfdf1c block_copy_helper.1 + 452 28 SwiftUI 0xeaf6c OUTLINED_FUNCTION_901 + 2312 29 Evie Ring 0x2dd20c main + 10 (MovanoRingApp.swift:10) 30 ??? 0x1c7724344 (Missing)
1
0
425
Jul ’24
Crash in QuartzCore - CA::Render::Encoder::grow(unsigned long) + 288
Hi Team, some of our users are getting crash in QuartzCore. But we are not sure the exact reason for it. Can you please help us in it? App is crashing in production. Xcode version - 15.0 Platform - iOS Below is the crash stack trace. Crashed: com.apple.main-thread 0 libsystem_kernel.dylib 0xa974 __pthread_kill + 8 1 libsystem_pthread.dylib 0x60ec pthread_kill + 268 2 libsystem_c.dylib 0x75b80 abort + 180 3 QuartzCore 0x98ba8 CA::Render::Encoder::grow(unsigned long) + 288 4 QuartzCore 0x97e50 CA::Render::Vector::encode(CA::Render::Encoder*) const + 112 5 QuartzCore 0x10a76c CA::Render::KeyframeAnimation::encode(CA::Render::Encoder*) const + 68 6 QuartzCore 0x975ec CA::Render::Array::encode(CA::Render::Encoder*) const + 172 7 QuartzCore 0x75204 CA::Context::commit_animation(CA::Layer*, CA::Render::Animation*, void*) + 236 8 QuartzCore 0x72998 CA::Layer::commit_animations(CA::Transaction*, double ()(CA::Layer, double, void*), void ()(CA::Layer, CA::Render::Animation*, void*), void ()(CA::Layer, __CFString const*, void*), CA::Render::TimingList* ()(CA::Layer, void*), void*) + 956 9 QuartzCore 0x2b930 invocation function for block in CA::Context::commit_transaction(CA::Transaction*, double, double*) + 148 10 QuartzCore 0x2b838 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 368 11 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 12 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 13 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 14 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 15 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 16 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 17 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 18 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 19 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 20 QuartzCore 0x2b7c4 CA::Layer::commit_if_needed(CA::Transaction*, void (CA::Layer*, unsigned int, unsigned int) block_pointer) + 252 21 QuartzCore 0x6f5b0 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 11212 22 QuartzCore 0x661bc CA::Transaction::commit() + 648 23 QuartzCore 0x65e64 CA::Transaction::flush_as_runloop_observer(bool) + 88 24 CoreFoundation 0x35d3c CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 36 25 CoreFoundation 0x34738 __CFRunLoopDoObservers + 552 26 CoreFoundation 0x33e50 __CFRunLoopRun + 1028 27 CoreFoundation 0x33968 CFRunLoopRunSpecific + 608 28 GraphicsServices 0x34e0 GSEventRunModal + 164 29 UIKitCore 0x22aedc -[UIApplication _run] + 888 30 UIKitCore 0x22a518 UIApplicationMain + 340 31 SwiftUI 0x1033860 OUTLINED_FUNCTION_39 + 600 32 SwiftUI 0x10336a8 OUTLINED_FUNCTION_39 + 160 33 SwiftUI 0xc4f9fc get_witness_table 7SwiftUI4ViewRzlAA15ModifiedContentVyxAA30_EnvironmentKeyWritingModifierVySbGGAaBHPxAaBHD1__AgA0cI0HPyHCHCTm + 364 34 Evie Ring 0x324620 main + 10 (MovanoRingApp.swift:10) 35 ??? 0x1ad632d84 (Missing)
0
0
616
Apr ’24