Image loading system

Overview

Image Loading System

Nuke ILS provides an efficient way to download and display images in your app. It's easy to learn and use thanks to a clear and concise API. Its architecture enables many powerful features while offering virtually unlimited possibilities for customization.

Despite the number of features, the framework is lean and compiles in just under 3 seconds¹. Nuke has an automated test suite 2x the size of the codebase itself, ensuring excellent reliability. Every feature is carefully designed and optimized for performance.

Fast LRU memory and disk cache · SwiftUI · Smart background decompression · Image processing · Resumable downloads · Intelligent deduplication · Request prioritization · Prefetching · Rate limiting · Progressive JPEG, HEIF, WebP, SVG, GIF · Alamofire · Combine · Reactive extensions

Sponsors

Stream

Nuke is proudly sponsored by Stream, the leading provider in enterprise grade Feed & Chat APIs. Try the iOS Chat Tutorial.

Documentation

Nuke is easy to learn and use thanks to beautiful Nuke Docs. Make sure to also check out Nuke Demo.

Upgrading from the previous version? Use a Migration Guide.

Extensions

The image pipeline is easy to customize and extend. Check out the following first-class extensions and packages built by the community.

Name Description
NukeUI A comprehensive solution for displaying lazily loaded images on Apple platforms
NukeBuilder A fun and convenient way to use Nuke
Alamofire Plugin Replace networking layer with Alamofire
RxNuke RxSwift extensions for Nuke with examples
WebP Plugin Community. WebP support, built by Ryo Kosuge
Gifu Plugin Use Gifu to load and display animated GIFs
FLAnimatedImage Plugin Use FLAnimatedImage to load and display animated GIFs
Xamarin NuGet Community. Makes it possible to use Nuke from Xamarin

Contribution

Nuke's roadmap is managed in Trello and is publicly available.

Minimum Requirements

Nuke Swift Xcode Platforms
Nuke 10.0 Swift 5.3 Xcode 12.0 iOS 11.0 / watchOS 4.0 / macOS 10.13 / tvOS 11.0
Nuke 9.0 Swift 5.1 Xcode 11.0 iOS 11.0 / watchOS 4.0 / macOS 10.13 / tvOS 11.0

See Installation Guide for information about the older versions.

License

Nuke is available under the MIT license. See the LICENSE file for more info.


¹ Measured on MacBook Pro 2018 (2,2 GHz 6-Core Intel Core i7, 16 GB 2400 MHz DDR4)

Comments
  • Crash in `TaskFetchOriginalImageData.swift`

    Crash in `TaskFetchOriginalImageData.swift`

    Hi Alexander, thanks for the great library.

    I noticed a crash related to TaskFetchOriginalImageData.swift:107 (data.append(chunk))

    Could it be related to private lazy var data = Data()? I thought if it's not thread-safe and if it's possible to access it from multiple threads then that might be the cause.

    Let me know if you need more information

    SIGTRAP (#0): Application crash: SIGTRAP (Trace/BPT trap)
    Thread 8 Crashed:
    0  libswiftFoundation.dylib   0x0000000185565ee4 specialized __DataStorage.init(bytes: UnsafeMutableRawPointer?, length: Int, copy: Bool, deallocator: (UnsafeMutableRawPointer, Int)?, offset: Int) + 360
    1  libswiftFoundation.dylib   0x0000000185451714 Data.InlineSlice.ensureUniqueReference() + 156
    2  libswiftFoundation.dylib   0x000000018545a944 Data.InlineSlice.append(contentsOf: UnsafeRawBufferPointer) + 40
    3  libswiftFoundation.dylib   0x000000018545b960 Data._Representation.append(contentsOf: UnsafeRawBufferPointer) + 580
    4  Transfer                   0x0000000105192228 TaskFetchOriginalImageData.dataTask(didReceiveData: Data, response: NSURLResponse) + 900 /Users/vagrant/git/SourcePackages/checkouts/Nuke/Sources/Core/Tasks/TaskFetchOriginalImageData.swift:107
    5  Transfer                   0x0000000105193e10 partial apply for closure #1 () in closure #1 (Data, NSURLResponse) in TaskFetchOriginalImageData.loadData(urlRequest: URLRequest, finish: ()) + 28 <compiler-generated>:0
    6  Transfer                   0x0000000105170f10 thunk for @escaping @callee_guaranteed () -> () + 28 <compiler-generated>:0
    7  libdispatch.dylib          0x00000001809fae68 _dispatch_call_block_and_release + 32
    8  libdispatch.dylib          0x00000001809fca2c _dispatch_client_callout + 20
    9  libdispatch.dylib          0x0000000180a04124 _dispatch_lane_serial_drain + 668
    10 libdispatch.dylib          0x0000000180a04c80 _dispatch_lane_invoke + 392
    11 libdispatch.dylib          0x0000000180a0f500 _dispatch_workloop_worker_thread + 648
    12 libsystem_pthread.dylib    0x00000001f1d1a0bc _pthread_wqthread + 288
    13 libsystem_pthread.dylib    0x00000001f1d19e5c start_wqthread + 8
    
    SIGTRAP (#0): Application crash: SIGTRAP (Trace/BPT trap)
    Thread 10 Crashed:
    0  libswiftFoundation.dylib   0x00000001db9b2ee4 0x1db892000 + 1183460
    1  libswiftFoundation.dylib   0x00000001db89e6ec 0x1db892000 + 50924
    2  libswiftFoundation.dylib   0x00000001db8a791c 0x1db892000 + 88348
    3  libswiftFoundation.dylib   0x00000001db8a8938 0x1db892000 + 92472
    4  Transfer                   0x000000010450a228 TaskFetchOriginalImageData.dataTask(didReceiveData: Data, response: NSURLResponse) + 900 /Users/vagrant/git/SourcePackages/checkouts/Nuke/Sources/Core/Tasks/TaskFetchOriginalImageData.swift:107
    5  Transfer                   0x000000010450be10 partial apply for closure #1 () in closure #1 (Data, NSURLResponse) in TaskFetchOriginalImageData.loadData(urlRequest: URLRequest, finish: ()) + 28 <compiler-generated>:0
    6  Transfer                   0x00000001044e8f10 thunk for @escaping @callee_guaranteed () -> () + 28 <compiler-generated>:0
    7  libdispatch.dylib          0x00000001d6e3ae6c 0x1d6e39000 + 7788
    8  libdispatch.dylib          0x00000001d6e3ca30 0x1d6e39000 + 14896
    9  libdispatch.dylib          0x00000001d6e44124 0x1d6e39000 + 45348
    10 libdispatch.dylib          0x00000001d6e44c80 0x1d6e39000 + 48256
    11 libdispatch.dylib          0x00000001d6e4f500 0x1d6e39000 + 91392
    12 libsystem_pthread.dylib    0x000000024833c0bc 0x24833b000 + 4284
    13 libsystem_pthread.dylib    0x000000024833be5c 0x24833b000 + 3676
    
    crash 
    opened by amirdew 26
  • xcodebuild show issues:  Cannot open

    xcodebuild show issues: Cannot open "*.docc" as a "Swift Package Folder" because it is already open as a "Folder".}

    Xcode Version 14.0.1 (14A400) Nuke version: 11.3.0

    2022-10-05 00:09:10.089 xcodebuild[13166:8526635] [MT] IDEFileReferenceDebug: [Load] <IDESwiftPackageCore.IDESwiftPackageSpecialFolderFileReference, 0x60000bae4d00: name:NukeExtensions.docc path:group:NukeExtensions.docc> Failed to load container at path: /SourcePackages/checkouts/Nuke/Sources/NukeExtensions/NukeExtensions.docc, Error: Error Domain=com.apple.dt.IDEContainerErrorDomain Code=6 "Cannot open "NukeExtensions.docc" as a "Swift Package Folder" because it is already open as a "Folder"." UserInfo={NSLocalizedDescription=Cannot open "NukeExtensions.docc" as a "Swift Package Folder" because it is already open as a "Folder".}
    2022-10-05 00:09:10.092 xcodebuild[13166:8526635] [MT] IDEFileReferenceDebug: [Load] <IDESwiftPackageCore.IDESwiftPackageSpecialFolderFileReference, 0x60000baeee00: name:Nuke.docc path:group:Nuke.docc> Failed to load container at path: /SourcePackages/checkouts/Nuke/Sources/Nuke/Nuke.docc, Error: Error Domain=com.apple.dt.IDEContainerErrorDomain Code=6 "Cannot open "Nuke.docc" as a "Swift Package Folder" because it is already open as a "Folder"." UserInfo={NSLocalizedDescription=Cannot open "Nuke.docc" as a "Swift Package Folder" because it is already open as a "Folder".}
    2022-10-05 00:09:10.094 xcodebuild[13166:8526635] [MT] IDEFileReferenceDebug: [Load] <IDESwiftPackageCore.IDESwiftPackageSpecialFolderFileReference, 0x60000baefa00: name:NukeUI.docc path:group:NukeUI.docc> Failed to load container at path: /SourcePackages/checkouts/Nuke/Sources/NukeUI/NukeUI.docc, Error: Error Domain=com.apple.dt.IDEContainerErrorDomain Code=6 "Cannot open "NukeUI.docc" as a "Swift Package Folder" because it is already open as a "Folder"." UserInfo={NSLocalizedDescription=Cannot open "NukeUI.docc" as a "Swift Package Folder" because it is already open as a "Folder".}
    
    bug 
    opened by Wei18 25
  • nk_cancelLoading() seems not working thoroughly when scrolling fast in a table view

    nk_cancelLoading() seems not working thoroughly when scrolling fast in a table view

    Let's say I have a table view with 1000 cells where each cell downloads one image in willDisplayCell:

    cell.image.nk_setImageWith(...)
    

    and each row cancels image in didEndDisplayingCell:

    cell.image.nk_cancelLoading()
    

    It works pretty well except the case when I scroll very fast (as fast as I can).

    Why do I say nk_cancelLoading not working "thoroughly"?

    • NOT Working -> When I scroll fast, say from row 1 to row 500, and I stop at row 500, the cells around row 500 shows no image until 10-20 seconds (seems waiting for something to be finished).
    • Working -> After I see the images for the rows around row 500, and if I scroll back, I see no images are downloaded for earlier rows (when I scroll back, images are shown in a second, which is normal if I scroll normally), which means "cancelling" is working. The images that had been cancelled wasn't downloaded.

    So for the not-working case, I guess somehow, the network requests still jammed in the lower level? Or why would it take so long to show the images. If previous image requests are all cancelled without blocking current requests, the images should shown within one or two seconds as usual.

    improvement 
    opened by joe528 21
  • Image rendering/networking issue across the OS

    Image rendering/networking issue across the OS

    Our app is experiencing some sort of severe cache corruption where all images go blank. Even more concerning, the user's entire phone is affected. Here's more info:

    image

    Our Nuke configuration in AppDelegate is as follows:

    ImagePipeline.shared = ImagePipeline {
        $0.dataLoadingQueue.maxConcurrentOperationCount = 12 // Default is 6
        $0.dataCachingQueue.maxConcurrentOperationCount = 5 // default is 2
        $0.imageDecodingQueue.maxConcurrentOperationCount = 3 // default is 1
        $0.imageEncodingQueue.maxConcurrentOperationCount = 3 // default is 1
        $0.imageProcessingQueue.maxConcurrentOperationCount = 5 //default is 2
        $0.isDeduplicationEnabled = true // Combine the requests for same original image into one.
    }
    
    ImageCache.shared.costLimit = 1024 * 1024 * 250
    ImageCache.shared.countLimit = 500
    ImageLoadingOptions.shared = ImageLoadingOptions(transition: .fadeIn(duration: 0.2))
    

    Out of desperation, we are currently testing an alternative config that doesn't use HTTP caching, since it seems like that is the only way this could be correlated to other apps:

        // Attempt to combat prominent "image disappearing" bug in prod by disabling the native HTTP cache in favor of LRU Disk Cache
        $0.dataLoader = DataLoader(configuration: {
            // Disable disk caching built into URLSession
            let conf = DataLoader.defaultConfiguration
            conf.urlCache = nil
            return conf
        }())
        
        $0.dataCache = try? DataCache(name: "app.blink")
    

    More info

    I've had the opportunity to debug the app while in this state, and unfortunately I don't see any errors in the console that would give clues. However, what I have noticed is that break points in the callback may not be getting invoked:

    Nuke.loadImage(with: url, into: imageView) { result in
        switch result {
        case .failure(let error): print(error)
        case .success(_): break
        }
    }
    

    This problem has only been observed for the past few months, after iOS 14 was released. It's really hard to tell the exact moment though, whether it was a Nuke upgrade, operating system version, or app change. Do you have any advice or insight as to what may be occurring?

    bug 
    opened by sjmueller 20
  • Responsive Images

    Responsive Images

    We have a server that provides small (50px), medium (300px), and large (1000px) sizes of images. We display different sizes in different places of the app.

    When we create an image view in the app, we know what image size is ideal for display. We fetch that size from the server using Nuke and it loads and caches just fine.

    We'd like to further improve loading speeds by displaying the smaller size from the cache if available while loading a larger size from the server.

    Further, if the large size is available in the cache and we are attempting to display a small size, we'd like to cache that size separately for performance reasons by simply downsizing the large image without making a request to the server. Think, the native Photos app. Apple caches and stores thumbnails for all your photos in separate files so they don't need to load the full size image when scrolling thousands of photos very quickly.

    Is this possible with Nuke? If so, could you point me in the right direction with regards to what needs to be implemented/adjusted/customized?

    feature 
    opened by IsaiahJTurner 18
  • Gaussian blur without border artifacts (CoreImage bug)

    Gaussian blur without border artifacts (CoreImage bug)

    Issue

    Gaussian blur CIFilter naturally creates gray artifacts at the borders of the output image. A common use case when blurring an image would be avoiding these artifacts.

    Proposed solution

    Add a new filter that extends the edge pixels indefinitely and crop the image to its original extend after blurring.

    /// A Gaussian blur filter that clamps to extent to avoid the gray border artefact.
    struct GaussianBlurClampedToExtent: ImageProcessing, Hashable, CustomStringConvertible {    
        private let radius: Int
        
        /// Initializes the receiver with a blur radius.
        public init(radius: Int = 8) {
            self.radius = radius
        }
        
        /// Applies `CIGaussianBlur` filter to the image.
        public func process(image: Image, context: ImageProcessingContext?) -> Image? {
            
            // Get CI image
            let ciImageOptional: CoreImage.CIImage? = {
                if let image = image.ciImage {
                    return image
                }
                if let image = image.cgImage {
                    return CoreImage.CIImage(cgImage: image)
                }
                return nil
            }()
            
            // Ensure CI image was retrieved
            guard let ciImage = ciImageOptional else { return nil }
            
            // Remember original image extent
            let extent = ciImage.extent
            
            // Create image with infinitely extended border pixels to prevent gray edges from blur filter
            let inputImage: CIImage = ciImage.clampedToExtent()
            
            // Create blur filter
            let filter = CIFilter(name: "CIGaussianBlur", parameters: [kCIInputRadiusKey: radius, kCIInputImageKey: inputImage])
            
            // Get filtered image
            guard let filteredImage = filter?.outputImage else { return nil }
            
            // Get default context shared between all Core Image filters.
            let context = CIContext(options: [.priorityRequestLow: true])
            
            // Create CI image cropped to original extent
            guard let imageRef: CGImage = context.createCGImage(filteredImage, from: extent) else { return nil }
            return UIImage(cgImage: imageRef, scale: image.scale, orientation: image.imageOrientation)
        }
    
        public var identifier: String {
            return "com.github.kean/nuke/gaussian_blur_clamped_to_extent?radius=\(radius)"
        }
    
        public var hashableIdentifier: AnyHashable {
            return self
        }
    
        public var description: String {
            return "GaussianBlurClampedToExtend(radius: \(radius))"
        }
    }
    

    Alternative solutions

    Extend existing GaussianBlur filter with a Boolean clampToExtend option: "com.github.kean/nuke/gaussian_blur?radius=\(radius)&clampToExtend=\(clampToExtend)"

    bug 
    opened by mtrezza 17
  • How to make images placed by Nuke in green when Color Blended Layers is enabled?

    How to make images placed by Nuke in green when Color Blended Layers is enabled?

    I download the images in the table view cells via Nuke as:

    imageView.nk_setImageWith(imageURL)
    

    the images are in red when the Simulator has Color Blended Layers checked. How to make them green? (It will help the scrolling performance.)

    PS. Earlier I use HanekeSwift, these images are in green by default. But with Nuke, they become all red.

    improvement 
    opened by joe528 16
  • Detect and download updated image

    Detect and download updated image

    I'm having trouble getting Nuke to detect images that's been updated on the server - the cached image is used instead. It seems like Nuke doesn't check if the file has been updated on the server by default? Is there a way to force this functionality?

    question 
    opened by andreaslindahl 15
  • How to determine failed downloads from preheating?

    How to determine failed downloads from preheating?

    Hi, So we're currently using Kingfisher, however we're noticing some performance issues on large collection views... So Nuke library seems like the ideal solution!

    The only query I have is in regards to the preheating... We're currently trying to download all the images our app needs on-launch so that by the time the users reaches the screen where they're actually needed; they're already available.

    We're keen for the app to work in areas where the user has weak signal; often meaning not all image requests are successful. Kingfisher's ImagePrefetcher caters for this by returning which images succeeded and failed downloading; we then log which ones failed and try again at an appropriate time.

    I'm struggling to find anything similar in the Nuke documentation; is there a way to determine which images were and weren't successfully preheated? Also is there a means of specifying a count for the number of times to potentially re-try downloading a given image? Or a means of getting a callback when each image in the preheat list has failed / been downloaded successfully?

    Many thanks!

    question 
    opened by SleepiestAdam 14
  • NSAllocateMemoryPages fails in ImageDecoder

    NSAllocateMemoryPages fails in ImageDecoder

    Seeing crashes come through in prod for cases where ImageDecoder is failing to initialize the UIImage with data

    Image decoder failing to create UIImage

    Fabric is reporting that most of these devices have low free memory.

    What can be done to handle this exception?

    improvement 
    opened by adomanico 14
  • Progressive image not so progressive

    Progressive image not so progressive

    Hello,

    I'm trying to use the progressive decoding feature of Nuke.

    The productImage ImageView never gets the image .. Any clues about this?

    Your example lacks in information because it only loads images from the app resources and loading from an URL is far way complicated.

    Thanks in advance.

    opened by adrianslr 13
  • GIF keeps running in the background

    GIF keeps running in the background

    I'm using LazyImageView right now. I have called reset in the prepareForReuse of UITableViewCell. And it did set imageContainer to nil to trigger the reset int the ImageView. But I found it only set _animatedImageView?.isHidden = true and _animatedImageView?.image = nil. It does not call prepareForReuse nor stopAnimatingGIF. So when it displays a high resolution GIF file, it makes the scrolling stuttering even if the prepareForReuse was called.

    opened by KimiChiu 0
  • Placeholder can't apply ImageProcessors?

    Placeholder can't apply ImageProcessors?

    I try to load an image and add ImageProcessors.Circle() processor, but processors can't apply to placeholders. So I must adapt the placeholder to a circle style using layer.cornerRadius.

    Nuke: 11.5.3

    opened by Jyhwenchai 0
  • Loading issue with wrong ext of the URL

    Loading issue with wrong ext of the URL

    My user has a image link, https://i.imgur.com/5TjxopD.png. But the actual link is https://i.imgur.com/5TjxopD.gif. Imgur is able to response the correct image no matter what the extension you're using. The problem is that Nuke will show nothing when the extension is not what it should be. If it's a GIF but the file of the url is PNG, it will show nothing, if it's a PNG but the file of the url is GIF, it will show nothing too. It works well when I was using Nuke 8.

        weak var previewImage: LazyImageView?
        weak var progressView: CircleProgressView?
        weak var failedView: CircleFailedView?
    
        func build() {
            isOpaque = true
            clearsContextBeforeDrawing = false
    
            let previewImage = LazyImageView()
    //        previewImage.clipsToBounds = true
            previewImage.imageView.resizingMode = resizingMode
    //        previewImage.transition = nil
    
            let progressView = CircleProgressView()
            let failedView = CircleFailedView()
    
            previewImage.placeholderView = progressView
            previewImage.failureView = failedView
    
            addSubview(previewImage)
    
            self.previewImage = previewImage
            self.progressView = progressView
            self.failedView = failedView
        }
    
        func load(url: URL) {
            guard let previewImage = previewImage else { return }
    
            progressView?.level = 0
    //            customView.previewImage.image = nil
            previewImage.url = url
            previewImage.onProgress = { [weak self] progress in
                if progress.total < 0 {
                    self?.progressView?.level = 10000.0
                }
                else{
                    self?.progressView?.level = CGFloat( (Float(progress.completed) / Float(progress.total)) * 10000.0 )
                }
    
                DispatchQueue.main.async { [weak self] in
                    self?.progressView?.setNeedsDisplay()
                }
            }
        }
    

    Nuke: 11.5.0 NukeWebP: 1.0.2 XCode: 14.2

    opened by KimiChiu 0
  • GIF delay to load first frame

    GIF delay to load first frame

    I have a gif image gif have delay between frames is 1 second. I saw this gif image load a black frame then after 1 second first frame image will be loaded.

    I test on a faster delay gif and it works as normal. Please see video below.

    GIF Information
    ---------------
    GIF size: 468,655 bytes (457.67kb)
    GIF length: 5 second(s)
    GIF width/height: 480×480 pixels
    number of frames: 5
    number of colors: 256
    loop count: 0 (endless)
    

    https://user-images.githubusercontent.com/9253378/209928249-382fe8ed-2037-49c1-aa9b-c0b5c26fdfc3.mov

    opened by abinhho 0
  • NukeUI Bad Instructions Error When Calling LazyImage

    NukeUI Bad Instructions Error When Calling LazyImage

    Hello inside of the following method I am getting the error:

    Thread 20: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

    Specifically on this line:

    imageView.isHidden = false

    public var image: PlatformImage? {
            get { imageContainer?.image }
            set { imageContainer = newValue.map { ImageContainer(image: $0) } }
        }
    
        private func display(_ container: ImageContainer) {
            if let customView = makeCustomContentView(for: container) {
                customContentView = customView
                return
            }
      #if (os(iOS) || os(tvOS)) && !targetEnvironment(macCatalyst)
              if isAnimatedImageRenderingEnabled, let data = container.data, container.type == .gif {
                  animatedImageView.animate(withGIFData: data)
                  animatedImageView.isHidden = false
                  return
              }
      #endif
              if isVideoRenderingEnabled, let asset = container.asset {
               public var image: PlatformImage? {
            get { imageContainer?.image }
            set { imageContainer = newValue.map { ImageContainer(image: $0) } }
        }
    
        private func display(_ container: ImageContainer) {
            if let customView = makeCustomContentView(for: container) {
                customContentView = customView
                return
            }
      #if (os(iOS) || os(tvOS)) && !targetEnvironment(macCatalyst)
              if isAnimatedImageRenderingEnabled, let data = container.data, container.type == .gif {
                  animatedImageView.animate(withGIFData: data)
                  animatedImageView.isHidden = false
                  return
              }
      #endif
              if isVideoRenderingEnabled, let asset = container.asset {
                  videoPlayerView.isHidden = false
                  videoPlayerView.isLooping = isVideoLooping
                  videoPlayerView.asset = asset
                  videoPlayerView.play()
                  return
              }
      
              imageView.image = container.image
              imageView.isHidden = false
        }   videoPlayerView.isHidden = false
                  videoPlayerView.isLooping = isVideoLooping
                  videoPlayerView.asset = asset
                  videoPlayerView.play()
                  return
              }
      
              imageView.image = container.image
              imageView.isHidden = false
        }
    
    crash 
    opened by jalvini 1
Releases(11.5.3)
  • 11.5.3(Jan 4, 2023)

  • 11.5.1(Dec 25, 2022)

    • Fix ImagePipeline.shared warning when Strict Concurrency Checking set to Complete
    • Fix an issue where ImagePrefetcher/didComplete wasn't called in some scenarios
    • ImagePrefetcher/didComplete is now called on the main queue
    Source code(tar.gz)
    Source code(zip)
  • 11.5.0(Dec 17, 2022)

    Changes

    • DataLoader/delegate now gets called for all URLSession/delegate methods, not just the ones required by Pulse. It allows you to modify DataLoader behavior in new ways, e.g. for handling authentication challenges.
    • Fix an issue with ImagePrefetcher/didComplete not being called when images are in the memory cache, thanks to @0xceed - #635
    • Move .docc folders back to Sources/, so that the Nuke docs are now again available in Xcode
    • Add new unit tests, thanks to @zzmasoud - #626

    New Contributors

    • @0xceed made their first contribution in https://github.com/kean/Nuke/pull/635
    • @zzmasoud made their first contribution in https://github.com/kean/Nuke/pull/626
    Source code(tar.gz)
    Source code(zip)
  • 11.4.1(Dec 15, 2022)

  • 11.4.0(Dec 15, 2022)

  • 11.3.1(Oct 22, 2022)

    Fixes

    • Fix deprecated withTaskCancellationHandler usage - #614, thanks to @swasta
    • Fix xcodebuild & docc build issue on Xcode 14.0.1 - #609

    New Contributors

    • @swasta made their first contribution in https://github.com/kean/Nuke/pull/614
    Source code(tar.gz)
    Source code(zip)
  • 11.3.0(Sep 17, 2022)

  • 11.2.1(Sep 10, 2022)

  • 11.2.0(Sep 10, 2022)

  • 11.1.1(Aug 17, 2022)

    • Breaking Progressive decoding is now disabled by default as a way to mitigate #572
    • Add prefersIncrementalDelivery to DataLoader. When progressive decoding is disabled, it now uses prefersIncrementalDelivery on URLSessionTask, slightly increasing the performance
    • Add convenience options to Image and LazyImage: resizingMode(_:), videoRenderingEnabled(_:), videoLoopingEnabled(_:), animatedImageRenderingEnabled(_:)
    • Fix an issue where AVPlayerLayer was created eagerly
    • Fix an issue with placeholder not being shown by LazyImage when the initial URL is nil#586, thanks to @jeffreykuiken
    • Disable prepareForDisplay by default and add a configuration option to enable it
    Source code(tar.gz)
    Source code(zip)
  • 11.1.0(Aug 7, 2022)

    • Add missing content mode to NukeUI - #582, thanks to Ethan Pippin
    • Add DataLoader delegate for easy Pulse integration (please use it with Pulse 2.0 which is optimized for images) - #583
    (ImagePipeline.shared.configuration.dataLoader as? DataLoader)?.delegate = URLSessionProxyDelegate()
    
    Source code(tar.gz)
    Source code(zip)
  • 11.0.1(Jul 24, 2022)

  • 11.0.0(Jul 20, 2022)

    Nuke 11 embraces Swift Structured Concurrency with full feature parity with legacy completion-based APIs. NukeUI is now part of the main repo. Docs were completely rewritten using DocC and hosted on GitHub: Nuke, NukeUI, NukeExtensions.

    There are no major source-breaking changes in this release. Instead, it adds dozens of API refinements to make the framework more ergonomic.

    • Increase the minimum supported Xcode version to 13.3
    • Increase minimum supported platforms: iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15
    • Add support for Xcode 14.0

    Structured Concurrency

    Extend Async/Await APIs to have complete feature parity with the existing completion-based APIs paving the road for its eventual deprecation and removal in the future major versions.

    • Add @MainActor to the following types: FetchImage, LazyImage, LazyImageView, Nuke loadImage(into:) method
    • Add Sendable to most of the Nuke types, including ImagePipeline, ImageRequest,ImageResponse, ImageContainer, ImageTask, and more
    • Add ImageTaskDelegate to achieve complete feature-parity with completion-based APIs - #559
    • ImageRequest now accepts async/await function to fetch data as a resource

    Loading an image and monitoring download progress:

    func loadImage() async throws {
        let response = try await pipeline.image(for: "https://example.com/image.jpeg", delegate: self)
    }
    
    func imageTaskCreated(_ task: ImageTask) {
        // You can capture the task instance here to change priority later, etc
    }
    
    func imageTask(_ task: ImageTask, didUpdateProgress progress: ImageTask.Progress) {
        // Update progress
    }
    
    func imageTask(_ task: ImageTask, didReceivePreview response: ImageResponse) {
        // Display progressively decoded image
    }
    
    // And more...
    

    NukeUI and NukeExtensions

    NukeUI is now part of the main repo and the existing UIKit and AppKit UI extensions were moved from the main module to NukeExtensions and soft-deprecated.

    • Move NukeUI to the main Nuke repo
    • Move UIImageView / NSImageView extensions to a separate target NukeExtensions and soft-deprecated them - #555
    • Remove deprecated APIs from NukeUI
    • Add ImageResponse typealias to NukeUI
    • Use new ImageTask.Progress in NukeUI
    • NukeUI no longer exposes public Gifu dependency or its APIs

    Error Reporting Improvements

    A complete overhaul of ImagePipeline.Error with many new cases covering every single point of failure in the pipeline.

    • Add throws to "advanced" ImageProcessing
    • Add throws to ImageDecoding
    • Add support for throwing processing in ImageProcessors.CoreImageFilter
    • Add ImageDecoding instance, ImageDecodingContext, and underlying error to .decodingFailed error case
    • Add ImageProcessingContext and underlying error to .processingFailed error case
    • Add .dataMissingInCache error case for a scenario where data is missing in cache and download is disabled using .returnCacheDataDontLoad.
    • Add .dataIsEmpty error case for a scenario where the data loader doesn't report an error, but the response is empty.
    • Add .decoderNotRegistered(context:) error case for a scenario where no decoders are registered for the downloaded data. This should never happen unless you remove the default decoder from the registry.
    • Add .imageRequestMissing error case for a scenario when the load image method is called with no image request.
    • Add cacheType to ImageDecodingContext

    Other Changes

    • Fix #511 OSAtomic deprecation warnings - #573
    • Add ImageTask.State. Improve performance when canceling and changing priority of completed tasks.
    • Add ImageTask.Progress to simplify progress reporting APIs
    • Add ImageRequest.Options.skipDecompression
    • Add public ImageCacheKey initializer with ImageRequest
    • Add imageCache(for:pipeline:) method to ImagePipelineDelegate
    • Add automatic hashableIdentifier implementation to ImageProcessing types that implement Hashable protocol - #563
    • Add a way to customize decompression using ImagePipelineDelegate
    • Add ImageRequest to ImageResponse
    • Improve decompression performance by using preparingForDisplay on iOS 15 and tvOS 15
    • Add metrics reporting using DataLoaderObserving protocol
    • Add custom disk caching for requests backed by data publishers - #553
    • Add .pipelineInvalidated error that is thrown for new requests started on the invalidated pipeline
    • Add public write access to ImageDecodingContext, ImageProcessingContext, ImageResponse properties
    • Add static default and imageIO functions to ImageEncoding protocol for easy creating of encoders
    • Add sizeLimit to withDataCache ImagePipeline.Configuration initializer
    • Make ImageCache ttl optional instead of using 0 as a "never expires" indicator

    Removals and Deprecations

    • Soft-deprecate ImageRequestConvertible and use ImageRequest and URL directly in all news APIs for better discoverability and performance - #567
    • Deprecate ImageDecoderRegistering
    • Deprecate ImageCaching extension that works with ImageRequest
    • Rename isFinal in ImageProcessingContext to isCompleted to match the remaining APIs
    • Rename ImagePipeline/Configuration/DataCachePolicy to ImagePipeline/DataCachePolicy
    • Remove ImageRequestConvertible conformance from String
    • Remove ImageTaskEvent and consolidate it with the new ImageTaskDelegate API - #564
    • Remove progress monitoring using Foundation.Progress
    • Remove WKInterfaceObject support (in favor of SwiftUI)
    • Remove ImageType typealias (deprecated in 10.5)
    • Remove Cancellable conformance from URLSessionTask
    • Remove public ImagePublisher class (make it internal)

    Non-Code Changes

    • Automatically discover typos on CI - #549
    • Remove CocoaPods support
    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-rc.1(Jul 5, 2022)

    Nuke 11 embraces Swift Structured Concurrency with full feature parity with legacy completion-based APIs. NukeUI is now part of the main repo. Docs were completely rewritten using DocC and hosted on GitHub: Nuke, NukeUI, NukeExtensions.

    There are no major source-breaking changes in this release. Instead, it adds dozens of API refinements to make the framework more ergonomic.

    • Increase the minimum supported Xcode version to 13.3
    • Increase minimum supported platforms: iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15

    Structured Concurrency

    Extend Async/Await APIs to have complete feature parity with the existing completion-based APIs paving the road for its eventual deprecation and removal in the future major versions.

    • Add @MainActor to the following types: FetchImage, LazyImage, LazyImageView, Nuke loadImage(into:) method
    • Add Sendable to most of the Nuke types, including ImagePipeline, ImageRequest,ImageResponse, ImageContainer, ImageTask, and more
    • Add ImageTaskDelegate to achieve complete feature-parity with completion-based APIs - #559
    • ImageRequest now accepts async/await function to fetch data as a resource

    Loading an image and monitoring download progress:

    func loadImage() async throws {
        let response = try await pipeline.image(for: "https://example.com/image.jpeg", delegate: self)
    }
    
    func imageTaskCreated(_ task: ImageTask) {
        // You can capture the task instance here to change priority later, etc
    }
    
    func imageTask(_ task: ImageTask, didUpdateProgress progress: ImageTask.Progress) {
        // Update progres
    }
    
    func imageTask(_ task: ImageTask, didReceivePreview response: ImageResponse) {
        // Display progressively decoded image
    }
    
    // And more...
    

    NukeUI and NukeExtensions

    NukeUI is now part of the main repo and the existing UIKit and AppKit UI extensions were moved from the main module to NukeExtensions and soft-deprecated.

    • Move NukeUI to the main Nuke repo
    • Move UIImageView / NSImageView extensions to a separate target NukeExtensions and soft-deprecated them - #555
    • Remove deprecated APIs from NukeUI
    • Add ImageResponse typealias to NukeUI
    • Use new ImageTask.Progress in NukeUI
    • NukeUI no longer exposes public Gifu dependency or its APIs

    Error Reporting Improvements

    A complete overhaul of ImagePipeline.Error with many new cases covering every single point of failure in the pipeline.

    • Add throws to "advanced" ImageProcessing
    • Add throws to ImageDecoding
    • Add support for throwing processing in ImageProcessors.CoreImageFilter
    • Add ImageDecoding instance, ImageDecodingContext, and underlying error to .decodingFailed error case
    • Add ImageProcessingContext and underlying error to .processingFailed error case
    • Add .dataMissingInCache error case for a scenario where data is missing in cache and download is disabled using .returnCacheDataDontLoad.
    • Add .dataIsEmpty error case for a scenario where the data loader doesn't report an error, but the response is empty.
    • Add .decoderNotRegistered(context:) error case for a scenario where no decoders are registered for the downloaded data. This should never happen unless you remove the default decoder from the registry.
    • Add .imageRequestMissing error case for a scenario when the load image method is called with no image request.
    • Add cacheType to ImageDecodingContext

    Other Changes

    • Fix #511 OSAtomic deprecation warnings - #573
    • Add ImageTask.State. Improve performance when canceling and changing priority of completed tasks.
    • Add ImageTask.Progress to simplify progress reporting APIs
    • Add ImageRequest.Options.skipDecompression
    • Add public ImageCacheKey initializer with ImageRequest
    • Add imageCache(for:pipeline:) method to ImagePipelineDelegate
    • Add automatic hashableIdentifier implementation to ImageProcessing types that implement Hashable protocol - #563
    • Add a way to customize decompression using ImagePipelineDelegate
    • Add ImageRequest to ImageResponse
    • Improve decompression performance by using preparingForDisplay on iOS 15 and tvOS 15
    • Add metrics reporting using DataLoaderObserving protocol
    • Add custom disk caching for requests backed by data publishers - #553
    • Add .pipelineInvalidated error that is thrown for new requests started on the invalidated pipeline
    • Add public write access to ImageDecodingContext, ImageProcessingContext, ImageResponse properties
    • Add static default and imageIO functions to ImageEncoding protocol for easy creating of encoders
    • Add sizeLimit to withDataCache ImagePipeline.Configuration initializer
    • Make ImageCache ttl optional instead of using 0 as a "never expires" indicator

    Removals and Deprecations

    • Soft-deprecate ImageRequestConvertible and use ImageRequest and URL directly in all news APIs for better discoverability and performance - #567
    • Deprecate ImageDecoderRegistering
    • Deprecate ImageCaching extension that works with ImageRequest
    • Rename isFinal in ImageProcessingContext to isCompleted to match the renaming APIs
    • Rename ImagePipeline/Configuration/DataCachePolicy to ImagePipeline/DataCachePolicy
    • Remove ImageRequestConvertible conformance from String
    • Remove ImageTaskEvent and consolidate it with the new ImageTaskDelegate API - #564
    • Remove progress monitoring using Foundation.Progress
    • Remove WKInterfaceObject support (in favor of SwiftUI)
    • Remove ImageType typealias (deprecated in 10.5)
    • Remove Cancellable conformance from URLSessionTask
    • Remove public ImagePublisher class (make it internal)

    Non-Code Changes

    • Automatically discover typos on CI - #549
    • Remove CocoaPods support
    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.5(Jul 2, 2022)

    • Fix #511 OSAtomic deprecation warnings - #573
    • Revert ImageTask priority replacement with setPriority(_:) method
    • Revert ImageDecoderRegistry init being made private
    • Add ImageTask.State. Improve performance when canceling and changing priority of completed tasks.
    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.4(Jul 1, 2022)

    • Soft-deprecate ImageRequestConvertible and use ImageRequest and URL directly in all news APIs for better discoverability and performance - #567
    • Rename ImagePipeline/Configuration/DataCachePolicy to ImagePipeline/DataCachePolicy
    • More documentation improvements: Nuke, NukeUI, NukeExtensions
    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.3(Jun 24, 2022)

    • Docs completely rewritten using DocC and hosted on GitHub: Nuke, NukeUI, NukeExtensions
    • Deprecate ImageCaching extension that works with ImageRequest
    • Make ImageCacheKey initializer with ImageRequest public
    • Add static method ImageProcessing.custom(id:closure:) for creating custom processors
    • Make ImagePipeline.Cache Sendable
    • Add ImageResponse typealias to NukeUI
    • Use new ImageTask.Progress in NukeUI
    • When pipeline is invalidated, it now throws a new .pipelineInvalidated error for new requests
    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.2(Jun 18, 2022)

    In addition to changes made in Nuke 11.0 (Beta 1):

    • Add DocC support. For the latest documentation, use the docs from the project repo.
    • Add imageCache(for:pipeline:) method to ImagePipelineDelegate
    • Remove public ImagePublisher class (make it internal)
    • ImageProcessing types that implement Hashable protocol now get default hashableIdentifier implementation - #563
    • Add a way to customize decompression using ImagePipelineDelegate
    • Remove CocoaPods support
    • Remove ImageTaskEvent and consolidate it with the new ImageTaskDelegate API - #564
    • Add ImageTask.Progress to simplify progress reporting APIs
    • Add ImageRequest.Options.skipDecompression
    • Remove progress monitoring using Foundation.Progress
    • Remove ImageRequestConvertible conformance from String

    For feedback, please use Nuke 11 Discussion Channel

    Source code(tar.gz)
    Source code(zip)
  • 11.0.0-beta.1(Jun 15, 2022)

    Nuke 11 embraces Swift Structured Concurrency with full feature parity with completion-based APIs. With NukeUI now being part of the main repo, adding async image loading into your apps is easier than ever. There are no major source-breaking changes, but tens of API refinements to make the framework more ergonomic.

    For feedback, please use Nuke 11 Discussion Channel

    Structured Concurrency

    Extend Async/Await APIs to have complete feature parity with the existing completion-based APIs paving the road for its eventual deprecation and removal in the future major versions.

    • Make @MainActor the following types: FetchImage, LazyImage, LazyImageView, Nuke loadImage(into:) method
    • Make most types Sendable, including ImagePipeline, ImageRequest,ImageResponse, ImageContainer, ImageTask, and many more
    • Add ImageTaskDelegate to achieve complete feature-parity with completion-based APIs - #559

    Loading an image and monitoring download progress:

    func loadImage() async throws {
        let response = try await pipeline.image(for: "https://example.com/image.jpeg", delegate: self)
    }
    
    func imageTaskWillStart(_ task: ImageTask) {
        // You can capture a task instance here to change priority later, etc
    }
    
    func imageTask(_ task: ImageTask, didUpdateProgress progress: (completed: Int64, total: Int64)) {
        print("Image task did update progress: \(progress)")
    }
    
    • Add images(for:) method that returns an AsyncThrowingStream to represent progressive decoding - #558

    Progressively loading an image using an async sequence:

    for try await response in pipeline.images(for: "https://example.com/image.jpeg") {
       print("Decoded a new image: \(response)")
    }
    
    • ImageRequest now accepts async/await function to fetch data as a resource

    NukeUI and Nuke Extensions

    • Move NukeUI to the main Nuke repo
    • Remove deprecated APIs from NukeUI
    • NukeUI no longer exposes public Gifu dependency or its APIs
    • Move UIImageView / NSImageView extensions to a separate target NukeExtensions and soft-deprecated them - #555

    Error Reporting Improvements

    • Make an "advanced" version of ImageProcessing APIs throwing
    • Make ImageDecoding throwing
    • Add support for throwing processing in ImageProcessors.CoreImageFilter
    • Add ImageDecoding instance, ImageDecodingContext, and underlying error to .decodingFailed error case
    • Add ImageProcessingContext and underlying error to .processingFailed error case
    • Add .dataMissingInCache error case for a scenario where data is missing in cache and download is disabled using .returnCacheDataDontLoad.
    • Add .dataIsEmpty error case for a scenario where the data loader doesn't report an error, but the response is empty.
    • Add .decoderNotRegistered(context:) error case for a scenario where no decoders are registered for the downloaded data. This should never happen unless you remove the default decoder from the registry.
    • Add .imageRequestMissing error case for a scenario when the load image method is called with no image request.
    • Add cacheType to ImageDecodingContext

    Other Changes

    • Increase the minimum supported Xcode version to 13.3
    • Increase minimum supported platforms: iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15
    • Use preparingForDisplay on iOS 15 and tvOS 15
    • Add ImageRequest to ImageResponse
    • Automatically discover typos on CI - #549
    • Add an option to skip load data immediately by skipping the data loading queue - #552
    • Implement custom disk caching for requests backed by data publishers - #553
    • Deprecate ImageDecoderRegistering
    • Make ImageDecoderRegistry initializer private
    • Make ImageDecodingContext, ImageProcessingContext, ImageResponse properties publicly writable
    • Rename isFinal in ImageProcessingContext to isCompleted to match the renaming APIs
    • DataLoader now collects metrics URLSessionTaskMetrics and reports them using an existing DataLoaderObserving protocol
    • Add static default and imageIO functions to ImageEncoding protocol for easy creating of encoders
    • Make ImageCache ttl optional instead of using 0 as a "never expires" indicator
    • Add sizeLimit to withDataCache ImagePipeline.Configuration initializer
    • Remove WKInterfaceObject support (in favor of SwiftUI)
    • Remove ImageType typealias (deprecated in 10.5)
    • Remove Cancellable conformance from URLSessionTask
    Source code(tar.gz)
    Source code(zip)
  • 10.11.2(Jun 10, 2022)

    • Revert changes to the deployment targets introduced in 10.10 release

    The minimum deployment targets will be increased in the upcoming major release

    Source code(tar.gz)
    Source code(zip)
  • 10.11.1(Jun 10, 2022)

  • 10.11.0(Jun 8, 2022)

  • 10.10.0(May 21, 2022)

  • 10.9.0(May 1, 2022)

    • Rename recently added async/await loadImage(with:) method to image(for:), and loadData(with:) to data(for:) (to match Apple naming convention)
    • Add Sendable conformance to some of the types
    Source code(tar.gz)
    Source code(zip)
  • 10.8.0(Apr 24, 2022)

    • Add async/await support (requires Xcode 13.3) – #532
    extension ImagePipeline {
        public func loadImage(with request: ImageRequestConvertible) async throws -> ImageResponse
        public func loadData(with request: ImageRequestConvertible) async throws -> (Data, URLResponse?)
    }
    
    extension FetchImage {
        public func load(_ action: @escaping () async throws -> ImageResponse)
    }
    
    Source code(tar.gz)
    Source code(zip)
  • 10.7.2(Apr 23, 2022)

  • 10.7.1(Jan 27, 2022)

  • 10.7.0(Jan 24, 2022)

  • 10.5.2(Dec 2, 2021)

  • 10.5.1(Oct 23, 2021)

Owner
Alexander Grebenyuk
I write kean.blog and like porridge
Alexander Grebenyuk
Lazy image loading for SwiftUI

A missing piece in SwiftUI that provides lazy image loading.

Alexander Grebenyuk 9 Dec 26, 2022
SwiftUI Image loading and Animation framework powered by SDWebImage

SDWebImageSwiftUI What's for SDWebImageSwiftUI is a SwiftUI image loading framework, which based on SDWebImage. It brings all your favorite features f

null 1.6k Jan 6, 2023
A pure Swift high-performance asynchronous image loading framework. SwiftUI supported.

Longinus Longinus is a pure-Swift high-performance asynchronous web image loading,caching,editing framework. It was learned from Objective-C web image

Qitao Yang 290 Dec 17, 2022
Lightweight and customisable async image loading in SwiftUI. Supports on-disk storage, placeholders and more!

Asyncrounously download and display images in Swift UI. Supports progress indicators, placeholders and image transitions. RemoteImageView Asyncrounous

Callum Trounce 192 Dec 7, 2022
Asynchronous image loading framework.

YYWebImage YYWebImage is an asynchronous image loading framework (a component of YYKit). It was created as an improved replacement for SDWebImage, PIN

null 3.5k Dec 27, 2022
EbImagesSwiftUI - SDWebImageSwiftUI - a SwiftUI image loading framework, which based on SDWebImage

SDWebImageSwiftUI What's for SDWebImageSwiftUI is a SwiftUI image loading framew

An Tran 1 Jan 6, 2022
SwiftUI project to show ActivityIndicator above Image while loading

ImageWithActivityIndicatorDemo SwiftUI project to show ActivityIndicator above Image while loading ImageWithActivityIndicatorDemo is a demo app that s

Ali Adam 4 May 27, 2021
SwiftUI view that download and display image from URL and displaying Activity Indicator while loading .

ViewWithActivityIndicator ViewWithActivityIndicator is a SwiftUI view that download and display image from URL and displaying Activity Indicator while

Ali Adam 28 Feb 3, 2022
LCWebImage - An asynchronous image loading framework based on AFNetworking.

LCWebImage is an asynchronous image loading framework based on AFNetworking, which supports memory and disk caching, and provides functions such as custom caching, custom image decoding, and custom network configuration.

LiuChang 27 Jul 23, 2022
📷 A composable image editor using Core Image and Metal.

Brightroom - Composable image editor - building your own UI Classic Image Editor PhotosCrop Face detection Masking component ?? v2.0.0-alpha now open!

Muukii 2.8k Jan 3, 2023
An image download extension of the image view written in Swift for iOS, tvOS and macOS.

Moa, an image downloader written in Swift for iOS, tvOS and macOS Moa is an image download library written in Swift. It allows to download and show an

Evgenii Neumerzhitckii 330 Sep 9, 2022
📷 A composable image editor using Core Image and Metal.

Brightroom - Composable image editor - building your own UI Classic Image Editor PhotosCrop Face detection Masking component ?? v2.0.0-alpha now open!

Muukii 2.8k Jan 2, 2023
AsyncImage before iOS 15. Lightweight, pure SwiftUI Image view, that displays an image downloaded from URL, with auxiliary views and local cache.

URLImage URLImage is a SwiftUI view that displays an image downloaded from provided URL. URLImage manages downloading remote image and caching it loca

Dmytro Anokhin 1k Jan 4, 2023
AYImageKit is a Swift Library for Async Image Downloading, Show Name's Initials and Can View image in Separate Screen.

AYImageKit AYImageKit is a Swift Library for Async Image Downloading. Features Async Image Downloading. Can Show Text Initials. Can have Custom Styles

Adnan Yousaf 11 Jan 10, 2022
A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image.

QRDecode A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image. QRDecode

David Phillip Oster 2 Oct 28, 2022
Convert the image to hexadecimal to send the image to e-paper

ConvertImageToHex Convert the image to hexadecimal to send the image to e-paper Conversion Order // 0. hex로 변환할 이미지 var image = UIImage(named: "sample

Hankyeol Park 0 Feb 26, 2022
Image-cropper - Image cropper for iOS

Image-cropper Example To run the example project, clone the repo, and run pod in

Song Vuthy 0 Jan 6, 2022
An instagram-like image editor that can apply preset filters passed to it and customized editings to a binded image.

CZImageEditor CZImageEditor is an instagram-like image editor with clean and intuitive UI. It is pure swift and can apply preset filters and customize

null 8 Dec 16, 2022
APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS.

APNGKit is a high performance framework for loading and displaying APNG images in iOS and macOS. It's built on top of a modified version of libpng wit

Wei Wang 2.1k Dec 30, 2022