modemlooper avatar
About Blog

SwiftUI Save Image as PNG

8 min read
swftui macos
import SwiftUI
import AppKit

// MARK: - Bundle Extension
extension Bundle {
    static var displayName: String {
        return Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
            ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
            ?? "App"
    }
}

// MARK: - NSImage PNG Extension
extension NSImage {
    func pngData() -> Data? {
        guard let tiffData = self.tiffRepresentation,
              let bitmapImage = NSBitmapImageRep(data: tiffData) else {
            return nil
        }
        return bitmapImage.representation(using: .png, properties: [:])
    }
}

// MARK: - Main Content View
struct ContentView: View {
    @State private var showSuccessAlert = false
    @State private var savedIconPath = ""
    @State private var customImage: NSImage?
    
    var body: some View {
        VStack(spacing: 30) {
            Image(systemName: "photo.on.rectangle.angled")
                .font(.system(size: 80))
                .foregroundColor(.blue)
                .symbolRenderingMode(.hierarchical)
            
            VStack(spacing: 10) {
                Text("Image to PNG Converter")
                    .font(.title)
                    .fontWeight(.bold)
                
                Text("Load any image and save it as PNG")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            
            Button(action: {
                loadAndSaveCustomImage()
            }) {
                HStack {
                    Image(systemName: "photo")
                    Text("Load & Save Image")
                }
                .padding(.horizontal, 20)
                .padding(.vertical, 10)
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            
            if let customImage = customImage {
                VStack(spacing: 10) {
                    Text("Loaded Image:")
                        .font(.caption)
                        .foregroundColor(.secondary)
                    
                    Image(nsImage: customImage)
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: 250, maxHeight: 200)
                        .border(Color.gray.opacity(0.3))
                }
            }
        }
        .frame(width: 450, height: 500)
        .padding()
        .alert("Image Saved!", isPresented: $showSuccessAlert) {
            Button("OK") { }
        } message: {
            Text("Your image has been saved successfully!")
        }
    }
    
    // Example: Load and save any image
    private func loadAndSaveCustomImage() {
        let panel = NSOpenPanel()
        panel.allowedContentTypes = [.png, .jpeg, .tiff, .gif, .bmp]
        panel.allowsMultipleSelection = false
        panel.canChooseDirectories = false
        
        if panel.runModal() == .OK, let url = panel.url {
            if let image = NSImage(contentsOf: url) {
                customImage = image
                saveImageAsPNG(image, defaultName: "Converted-\(url.lastPathComponent)")
            } else {
                NSSound.beep()
            }
        }
    }
    
    // MARK: - Save Any Image Method (Flexible)
    private func saveImageAsPNG(_ image: NSImage, defaultName: String = "Image.png") {
        guard let pngData = image.pngData() else {
            NSSound.beep()
            return
        }
        
        let panel = NSSavePanel()
        panel.allowedContentTypes = [.png]
        panel.nameFieldStringValue = defaultName
        panel.title = "Save Image"
        panel.canCreateDirectories = true
        panel.isExtensionHidden = false
        panel.level = .modalPanel
        
        if panel.runModal() == .OK, let url = panel.url {
            do {
                try pngData.write(to: url, options: Data.WritingOptions.atomic)
                savedIconPath = url.path
                showSuccessAlert = true
                NSWorkspace.shared.activateFileViewerSelecting([url])
            } catch {
                NSSound.beep()
                print("Failed to write PNG: \(error)")
            }
        }
    }
}