UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Should I always downsample when loading user-saved images?

Forums > SwiftUI

My app allows users to select and save images from the Photos app.

The saved image is stored in the core data as a Binary Data type, and when I show the image, I use a GeometryReader to downsample the image to a certain size and show the image. However, I feel that the performance of the app is not good and I want to improve it, but I don't know how to improve it.

I would be grateful if you could give me some advice to improve it.

struct ContextView: View {
    @State private var seletedItem: Item?
    var body: some View {
        MainListView()
            .sheet(item: $seletedItem) { item in
                GeometryProxy { proxy in
                    let size = proxy.size
                    DetailImageView(item: item, size: size)
                        .ignoresSafeArea(.container, edges: .top)

                }
            }
    }
}

struct DetailImageView: View {
    var item: Item
    var size: CGSize
    private var imageHeight: CGFloat {
        size.height * 0.56
    }
    @State private var uiImage: UIImage? = nil

    var body: some View {
        ScrollView {
            GeometryReader { proxy in
                let childSize = proxy.size
                if let uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFill()
                        .frame(width: childSize.width, height: childSize.height)
                }
            }
            .frame(height: size.height)
        }
        .coordinateSpace(name: "scroll")

        .task(id: size) {
            uiImage = downsampleImage(imageData: item.imageData,
                                      to: CGSize(width: size.width, height: imageHeight))
        }
        .onChange(of: item.unwrappedImageData) { newImageData in
            updateImage(data: newImageData, width: size.width, height: imageHeight)
        }
        .onDisappear {
            uiImage = nil
        }
    }

    private func downsampleImage(imageData: Data, to pointSize: CGSize, scale: CGFloat = UIScreen.main.scale) -> UIImage {
        let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
        guard let imageSource = CGImageSourceCreateWithData(imageData as CFData, imageSourceOptions) else { return UIImage() }

        let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
        let downsampleOptions = [
            kCGImageSourceCreateThumbnailFromImageAlways: true,
            kCGImageSourceShouldCacheImmediately: true,
            kCGImageSourceCreateThumbnailWithTransform: true,
            kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels
        ] as CFDictionary

        guard let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions) else { return UIImage() }
        return UIImage(cgImage: downsampledImage)
    }
}

2      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.