macOS Swift Bildverarbeitung Beispiele

macOS Swift Bildverarbeitungsbeispiele einschließlich Laden/Speichern, Filterung und Transformationen

💻 Bild Laden/Speichern swift

🟢 simple ⭐⭐

Bilder aus Dateien, URLs und Bundle-Ressourcen laden und in verschiedenen Formaten speichern

⏱️ 25 min 🏷️ swift, macos, image processing, loading
Prerequisites: Basic Swift, AppKit framework, NSImage
// macOS Swift Image Loading/Saving Examples
// Using AppKit and CoreImage

import Cocoa
import CoreImage
import AppKit

// 1. Load Image from File
class ImageFileLoader {

    static func loadFromFile(path: String) -> NSImage? {
        print("\n--- Load Image from File ---")

        guard FileManager.default.fileExists(atPath: path) else {
            print("File does not exist: \(path)")
            return nil
        }

        let imageURL = URL(fileURLWithPath: path)
        guard let image = NSImage(contentsOf: imageURL) else {
            print("Failed to load image from: \(path)")
            return nil
        }

        print("Loaded image from: \(path)")
        print("Size: \(image.size)")

        return image
    }

    static func loadFromAbsolutePath(path: String) -> NSImage? {
        print("\n--- Load from Absolute Path ---")

        let imagePath = NSString(string: path).expandingTildeInPath
        return loadFromFile(path: imagePath as String)
    }
}

// 2. Load Image from URL
class ImageURLLoader {

    static func loadFromURL(url: URL, completion: @escaping (NSImage?) -> Void) {
        print("\n--- Load Image from URL ---")
        print("Loading: \(url.absoluteString)")

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else {
                print("Failed to load image: \(error?.localizedDescription ?? "")")
                completion(nil)
                return
            }

            let image = NSImage(data: data)
            completion(image)
        }

        task.resume()
    }

    static func loadFromURLSynchronously(url: URL) -> NSImage? {
        print("\n--- Load from URL (Synchronous) ---")

        if let data = try? Data(contentsOf: url) {
            let image = NSImage(data: data)
            print("Loaded from URL: \(url.lastPathComponent)")
            return image
        }

        return nil
    }
}

// 3. Load Image from Bundle
class BundleImageLoader {

    static func loadFromBundle(name: String, extension: String) -> NSImage? {
        print("\n--- Load Image from Bundle ---")

        guard let imagePath = Bundle.main.path(forResource: name, ofType: extension) else {
            print("Image not found in bundle: \(name).\(extension)")
            return nil
        }

        let image = NSImage(contentsOfFile: imagePath)

        if let image = image {
            print("Loaded from bundle: \(name).\(extension)")
            print("Size: \(image.size)")
        }

        return image
    }

    static func loadFromAssetCatalog(assetName: String) -> NSImage? {
        print("\n--- Load from Asset Catalog ---")

        let image = NSImage(named: assetName)

        if let image = image {
            print("Loaded asset: \(assetName)")
            print("Size: \(image.size)")
        } else {
            print("Asset not found: \(assetName)")
        }

        return image
    }
}

// 4. Save Image to File
class ImageFileSaver {

    static func saveToFile(image: NSImage, path: String, fileType: NSBitmapImageFileType = .png) -> Bool {
        print("\n--- Save Image to File ---")

        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else {
            print("Failed to get bitmap representation")
            return false
        }

        let imageData = bitmap.representation(using: fileType, properties: [:])

        guard let data = imageData else {
            print("Failed to convert image")
            return false
        }

        do {
            try data.write(to: URL(fileURLWithPath: path))
            print("Saved image to: \(path)")
            print("Format: \(fileType)")
            print("Size: \(data.count) bytes")
            return true
        } catch {
            print("Failed to save: \(error)")
            return false
        }
    }

    static func saveAsPNG(image: NSImage, path: String) -> Bool {
        return saveToFile(image: image, path: path, fileType: .png)
    }

    static func saveAsJPEG(image: NSImage, path: String, quality: Float = 0.9) -> Bool {
        print("\n--- Save as JPEG ---")

        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else {
            return false
        }

        let imageData = bitmap.representation(using: .jpeg, properties: [.compressionFactor: quality])

        guard let data = imageData else {
            return false
        }

        do {
            try data.write(to: URL(fileURLWithPath: path))
            print("Saved as JPEG to: \(path)")
            print("Quality: \(quality)")
            print("Size: \(data.count) bytes")
            return true
        } catch {
            print("Failed to save: \(error)")
            return false
        }
    }
}

// 5. Image Information
class ImageInfo {

    static func getInfo(_ image: NSImage) -> [String: Any] {
        print("\n--- Image Information ---")

        var info: [String: Any] = [:]

        info["size"] = NSSize(width: image.size.width, height: image.size.height)
        print("Size: \(image.size)")

        if let tiffData = image.tiffRepresentation,
           let bitmap = NSBitmapImageRep(data: tiffData) {

            info["pixelsWide"] = bitmap.pixelsWide
            info["pixelsHigh"] = bitmap.pixelsHigh
            info["bitsPerSample"] = bitmap.bitsPerSample
            info["samplesPerPixel"] = bitmap.samplesPerPixel
            info["hasAlpha"] = bitmap.hasAlpha
            info["isPlanar"] = bitmap.isPlanar
            info["colorSpaceName"] = bitmap.colorSpaceName ?? ""

            print("Dimensions: \(bitmap.pixelsWide) x \(bitmap.pixelsHigh)")
            print("Bits per sample: \(bitmap.bitsPerSample)")
            print("Samples per pixel: \(bitmap.samplesPerPixel)")
            print("Has alpha: \(bitmap.hasAlpha)")
            print("Color space: \(bitmap.colorSpaceName ?? "unknown")")
        }

        return info
    }

    static func getEXIFData(from path: String) -> [String: Any]? {
        print("\n--- Get EXIF Data ---")

        let imageURL = URL(fileURLWithPath: path)
        guard let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, nil),
              let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [String: Any] else {
            print("No EXIF data found")
            return nil
        }

        if let exif = properties[kCGImagePropertyExifDictionary as String] as? [String: Any] {
            print("EXIF data found")

            if let dateTime = exif[kCGImagePropertyExifDateTimeOriginal as String] {
                print("Date taken: \(dateTime)")
            }

            if let make = exif[kCGImagePropertyExifMake as String] {
                print("Camera make: \(make)")
            }

            if let model = exif[kCGImagePropertyExifModel as String] {
                print("Camera model: \(model)")
            }

            return exif
        }

        return nil
    }
}

// 6. Convert Between Formats
class ImageFormatConverter {

    static func convertToData(image: NSImage, type: NSBitmapImageFileType) -> Data? {
        print("\n--- Convert to Data ---")

        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else {
            return nil
        }

        let data = bitmap.representation(using: type, properties: [:])

        if let imageData = data {
            print("Converted to \(type)")
            print("Size: \(imageData.count) bytes")
        }

        return data
    }

    static func convertToPNG(image: NSImage) -> Data? {
        return convertToData(image: image, type: .png)
    }

    static func convertToJPEG(image: NSImage, quality: Float = 0.9) -> Data? {
        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else {
            return nil
        }

        return bitmap.representation(using: .jpeg, properties: [.compressionFactor: quality])
    }

    static func convertToTIFF(image: NSImage) -> Data? {
        return image.tiffRepresentation
    }
}

// 7. Create Image from Data
class ImageFromData {

    static func createFromData(_ data: Data) -> NSImage? {
        print("\n--- Create Image from Data ---")

        let image = NSImage(data: data)

        if let image = image {
            print("Created image from data (\(data.count) bytes)")
            print("Size: \(image.size)")
        } else {
            print("Failed to create image from data")
        }

        return image
    }

    static func createFromPNGData(_ data: Data) -> NSImage? {
        print("\n--- Create from PNG Data ---")
        return createFromData(data)
    }

    static func createFromJPEGData(_ data: Data) -> NSImage? {
        print("\n--- Create from JPEG Data ---")
        return createFromData(data)
    }
}

// 8. Resize Image on Load
class ImageResizeOnLoad {

    static func loadResized(path: String, maxSize: NSSize) -> NSImage? {
        print("\n--- Load Resized Image ---")

        let imageURL = URL(fileURLWithPath: path)

        guard let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, nil),
              let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [String: Any] else {
            return nil
        }

        let options: [String: Any] = [
            kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
            kCGImageSourceThumbnailMaxPixelSize: max(maxSize.width, maxSize.height)
        ]

        guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary) else {
            return nil
        }

        let image = NSImage(cgImage: thumbnail, size: maxSize)

        print("Loaded resized image: \(image.size)")

        return image
    }
}

// 9. Batch Image Loading
class BatchImageLoader {

    static func loadFromDirectory(directory: String, extensions: [String] = ["jpg", "png", "gif"]) -> [String: NSImage] {
        print("\n--- Batch Load Images ---")

        var images: [String: NSImage] = [:]

        guard let fileURLs = try? FileManager.default.contentsOfDirectory(
            at: URL(fileURLWithPath: directory),
            includingPropertiesForKeys: nil,
            options: [.skipsHiddenFiles]
        ) else {
            return images
        }

        print("Found \(fileURLs.count) files")

        for fileURL in fileURLs {
            let pathExtension = fileURL.pathExtension.lowercased()

            if extensions.contains(pathExtension) {
                if let image = NSImage(contentsOf: fileURL) {
                    images[fileURL.lastPathComponent] = image
                    print("  Loaded: \(fileURL.lastPathComponent)")
                }
            }
        }

        print("Loaded \(images.count) images")

        return images
    }

    static func loadAsync(paths: [String], completion: @escaping ([String: NSImage]) -> Void) {
        print("\n--- Async Batch Load ---")

        let group = DispatchGroup()
        var images: [String: NSImage] = [:]
        let queue = DispatchQueue(label: "imageLoader")

        for path in paths {
            group.enter()

            queue.async {
                if let image = NSImage(contentsOfFile: path) {
                    DispatchQueue.main.async {
                        images[path] = image
                    }
                }
                group.leave()
            }
        }

        group.notify(queue: .main) {
            print("Async loaded \(images.count) images")
            completion(images)
        }
    }
}

// 10. Image Thumbnail Generation
class ThumbnailGenerator {

    static func generateThumbnail(from imagePath: String, size: NSSize, saveTo: String) -> Bool {
        print("\n--- Generate Thumbnail ---")

        let imageURL = URL(fileURLWithPath: imagePath)

        guard let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, nil) else {
            return false
        }

        let options: [String: Any] = [
            kCGImageSourceCreateThumbnailWithTransform: true,
            kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
            kCGImageSourceThumbnailMaxPixelSize: max(size.width, size.height)
        ]

        guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary) else {
            print("Failed to create thumbnail")
            return false
        }

        let image = NSImage(cgImage: thumbnail, size: size)

        // Save thumbnail
        return ImageFileSaver.saveAsPNG(image: image, path: saveTo)
    }

    static func generateIconThumbnail(from imagePath: String) -> NSImage? {
        print("\n--- Generate Icon Thumbnail ---")

        let iconSize = NSSize(width: 64, height: 64)

        guard let image = NSImage(contentsOfFile: imagePath) else {
            return nil
        }

        let thumbnail = NSImage(size: iconSize)

        thumbnail.lockFocus()
        image.draw(
            in: NSRect(origin: .zero, size: iconSize),
            from: NSRect(origin: .zero, size: image.size),
            operation: .copy,
            fraction: 1.0
        )
        thumbnail.unlockFocus()

        return thumbnail
    }
}

// Main demonstration
func demonstrateImageLoadingSaving() {
    print("=== macOS Swift Image Loading/Saving Examples ===")

    // Create a sample image for testing
    let samplePath = "/tmp/test_image.png"

    // Create a simple test image
    let testImage = NSImage(size: NSSize(width: 200, height: 200))
    testImage.lockFocus()
    NSColor.blue.set()
    NSRect(origin: .zero, size: NSSize(width: 200, height: 200)).fill()
    testImage.unlockFocus()

    // Save test image
    ImageFileSaver.saveAsPNG(image: testImage, path: samplePath)

    // Load examples
    if let loadedImage = ImageFileLoader.loadFromFile(path: samplePath) {
        _ = ImageInfo.getInfo(loadedImage)

        // Convert to different formats
        if let pngData = ImageFormatConverter.convertToPNG(image: loadedImage) {
            print("PNG data: \(pngData.count) bytes")
        }

        if let jpegData = ImageFormatConverter.convertToJPEG(image: loadedImage) {
            print("JPEG data: \(jpegData.count) bytes")
        }
    }

    // Save in different formats
    _ = ImageFileSaver.saveAsJPEG(image: testImage, path: "/tmp/test_image.jpg")
    _ = ImageFileSaver.saveToFile(image: testImage, path: "/tmp/test_image.tiff", fileType: .tiff)

    print("\n=== All Image Loading/Saving Examples Completed ===")
}

// Run demonstration
demonstrateImageLoadingSaving()

💻 Bildfilterung swift

🟡 intermediate ⭐⭐⭐

Verschiedene Filter mit CoreImage anwenden einschließlich Weichzeichnen, Schärfen und Farbanpassung

⏱️ 35 min 🏷️ swift, macos, image processing, filtering
Prerequisites: Intermediate Swift, CoreImage framework, NSImage
// macOS Swift Image Filtering Examples
// Using CoreImage framework

import Cocoa
import CoreImage
import AppKit

// 1. Basic Filter Application
class BasicFilters {

    static func applyFilter(to image: NSImage, filterName: String) -> NSImage? {
        print("\n--- Apply Filter: \(filterName) ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            print("Failed to get CGImage")
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)

        guard let filter = CIFilter(name: filterName) else {
            print("Filter not found: \(filterName)")
            return nil
        }

        filter.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter.outputImage else {
            print("Filter failed")
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            print("Failed to create CGImage")
            return nil
        }

        let result = NSImage(cgImage: outputCGImage, size: image.size)
        print("Applied filter: \(filterName)")

        return result
    }
}

// 2. Blur Filters
class BlurFilters {

    static func gaussianBlur(image: NSImage, radius: Double) -> NSImage? {
        print("\n--- Gaussian Blur ---")
        print("Radius: \(radius)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIGaussianBlur")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        let result = NSImage(cgImage: outputCGImage, size: image.size)
        print("Applied Gaussian blur")

        return result
    }

    static func boxBlur(image: NSImage, radius: Double) -> NSImage? {
        print("\n--- Box Blur ---")
        print("Radius: \(radius)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIBoxBlur")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func motionBlur(image: NSImage, radius: Double, angle: Double) -> NSImage? {
        print("\n--- Motion Blur ---")
        print("Radius: \(radius), Angle: \(angle)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIMotionBlur")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)
        filter?.setValue(angle, forKey: kCIInputAngleKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 3. Color Adjustment Filters
class ColorAdjustmentFilters {

    static func adjustBrightness(image: NSImage, brightness: Double) -> NSImage? {
        print("\n--- Adjust Brightness ---")
        print("Brightness: \(brightness)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIColorControls")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(brightness, forKey: kCIInputBrightnessKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func adjustContrast(image: NSImage, contrast: Double) -> NSImage? {
        print("\n--- Adjust Contrast ---")
        print("Contrast: \(contrast)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIColorControls")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(contrast, forKey: kCIInputContrastKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func adjustSaturation(image: NSImage, saturation: Double) -> NSImage? {
        print("\n--- Adjust Saturation ---")
        print("Saturation: \(saturation)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIColorControls")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(saturation, forKey: kCIInputSaturationKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func adjustTemperature(image: NSImage, temperature: Double) -> NSImage? {
        print("\n--- Adjust Temperature ---")
        print("Temperature: \(temperature)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CITemperatureAndTint")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(temperature, forKey: kCIInputNeutral)
        filter?.setValue(temperature, forKey: kCIInputTargetNeutral)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func grayscale(image: NSImage) -> NSImage? {
        print("\n--- Grayscale ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectNoir")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func sepia(image: NSImage) -> NSImage? {
        print("\n--- Sepia ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CISepiaTone")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(0.8, forKey: kCIInputIntensityKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    static func invertColors(image: NSImage) -> NSImage? {
        print("\n--- Invert Colors ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIColorInvert")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        return applyFilterWithOutput(filter: filter, originalSize: image.size)
    }

    private static func applyFilterWithOutput(filter: CIFilter?, originalSize: NSSize) -> NSImage? {
        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: originalSize)
    }
}

// 4. Sharpen and Blur Enhancement
class SharpenFilters {

    static func sharpen(image: NSImage, intensity: Double) -> NSImage? {
        print("\n--- Sharpen ---")
        print("Intensity: \(intensity)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CISharpenLuminance")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(intensity, forKey: kCIInputSharpnessKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func unsharpMask(image: NSImage, radius: Double, intensity: Double) -> NSImage? {
        print("\n--- Unsharp Mask ---")
        print("Radius: \(radius), Intensity: \(intensity)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIUnsharpMask")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)
        filter?.setValue(intensity, forKey: kCIInputIntensityKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 5. Photo Effect Filters
class PhotoEffectFilters {

    static func applyVintageEffect(image: NSImage) -> NSImage? {
        print("\n--- Vintage Effect ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectInstant")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func applyChromeEffect(image: NSImage) -> NSImage? {
        print("\n--- Chrome Effect ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectChrome")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func applyFadeEffect(image: NSImage) -> NSImage? {
        print("\n--- Fade Effect ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectFade")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func applyMonoEffect(image: NSImage) -> NSImage? {
        print("\n--- Mono Effect ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectMono")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func applyTonalEffect(image: NSImage) -> NSImage? {
        print("\n--- Tonal Effect ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIPhotoEffectTonal")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 6. Vignette Filter
class VignetteFilter {

    static func applyVignette(image: NSImage, intensity: Double, radius: Double) -> NSImage? {
        print("\n--- Vignette ---")
        print("Intensity: \(intensity), Radius: \(radius)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIVignette")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(intensity, forKey: kCIInputIntensityKey)
        filter?.setValue(radius, forKey: kCIInputRadiusKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 7. Chain Multiple Filters
class FilterChain {

    static func applyChain(to image: NSImage, filters: [(String, [String: Any])]) -> NSImage? {
        print("\n--- Filter Chain ---")
        print("Applying \(filters.count) filters")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        var ciImage = CIImage(cgImage: cgImage)

        for (filterName, parameters) in filters {
            print("  Applying: \(filterName)")

            guard let filter = CIFilter(name: filterName) else {
                continue
            }

            filter.setValue(ciImage, forKey: kCIInputImageKey)

            for (key, value) in parameters {
                filter.setValue(value, forKey: key)
            }

            guard let outputImage = filter.outputImage else {
                continue
            }

            ciImage = outputImage
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            return nil
        }

        let result = NSImage(cgImage: outputCGImage, size: image.size)
        print("Filter chain applied successfully")

        return result
    }
}

// 8. Noise Reduction
class NoiseReduction {

    static func reduceNoise(image: NSImage, level: Double, sharpness: Double) -> NSImage? {
        print("\n--- Noise Reduction ---")
        print("Level: \(level), Sharpness: \(sharpness)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CINoiseReduction")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(level, forKey: kCIInputNoiseLevelKey)
        filter?.setValue(sharpness, forKey: kCIInputSharpnessKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 9. Edge Detection
class EdgeDetection {

    static func detectEdges(image: NSImage, intensity: Double = 1.0) -> NSImage? {
        print("\n--- Edge Detection ---")
        print("Intensity: \(intensity)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIEdges")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(intensity, forKey: kCIInputIntensityKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    static func lineOverlay(image: NSImage) -> NSImage? {
        print("\n--- Line Overlay ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CILineOverlay")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }
}

// 10. Color Matrix Filter
class ColorMatrix {

    static func applyColorMatrix(image: NSImage, matrix: [CGFloat], bias: [CGFloat] = []) -> NSImage? {
        print("\n--- Color Matrix ---")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let ciImage = CIImage(cgImage: cgImage)
        let filter = CIFilter(name: "CIColorMatrix")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(CIVector(cgFloat: matrix), forKey: "inputRVector")
        filter?.setValue(CIVector(cgFloat: matrix), forKey: "inputGVector")
        filter?.setValue(CIVector(cgFloat: matrix), forKey: "inputBVector")
        filter?.setValue(CIVector(cgFloat: matrix), forKey: "inputAVector")

        if !bias.isEmpty {
            filter?.setValue(CIVector(cgFloat: bias), forKey: "inputRBias")
            filter?.setValue(CIVector(cgFloat: bias), forKey: "inputGBias")
            filter?.setValue(CIVector(cgFloat: bias), forKey: "inputBBias")
            filter?.setValue(CIVector(cgFloat: bias), forKey: "inputABias")
        }

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image.size)
    }

    // Grayscale using color matrix
    static func grayscaleMatrix(image: NSImage) -> NSImage? {
        print("\n--- Grayscale (Color Matrix) ---")

        // Standard luminance values
        let matrix: [CGFloat] = [0.299, 0.587, 0.114, 0]

        return applyColorMatrix(image: image, matrix: matrix)
    }
}

// Main demonstration
func demonstrateImageFiltering() {
    print("=== macOS Swift Image Filtering Examples ===")

    // Create a test image
    let testImage = NSImage(size: NSSize(width: 300, height: 300))
    testImage.lockFocus()
    NSColor.red.set()
    NSBezierPath(ovalIn: NSRect(origin: .zero, size: NSSize(width: 300, height: 300))).fill()
    NSColor.white.set()
    NSBezierPath(ovalIn: NSRect(origin: NSPoint(x: 100, y: 100), size: NSSize(width: 100, height: 100))).fill()
    testImage.unlockFocus()

    // Apply filters
    if let blurred = BlurFilters.gaussianBlur(image: testImage, radius: 10) {
        print("Blur applied")
    }

    if let sharpened = SharpenFilters.sharpen(image: testImage, intensity: 2.0) {
        print("Sharpen applied")
    }

    if let vintage = PhotoEffectFilters.applyVintageEffect(image: testImage) {
        print("Vintage effect applied")
    }

    if let vignetted = VignetteFilter.applyVignette(image: testImage, intensity: 1.0, radius: 150) {
        print("Vignette applied")
    }

    if let grayscaled = ColorAdjustmentFilters.grayscale(image: testImage) {
        print("Grayscale applied")
    }

    if let sepia = ColorAdjustmentFilters.sepia(image: testImage) {
        print("Sepia applied")
    }

    if let edges = EdgeDetection.detectEdges(image: testImage) {
        print("Edge detection applied")
    }

    // Chain filters
    let filters: [(String, [String: Any])] = [
        ("CIGaussianBlur", [kCIInputRadiusKey: 5]),
        ("CIColorControls", [kCIInputBrightnessKey: 0.1, kCIInputContrastKey: 1.1])
    ]

    if let chained = FilterChain.applyChain(to: testImage, filters: filters) {
        print("Filter chain applied")
    }

    print("\n=== All Image Filtering Examples Completed ===")
}

// Run demonstration
demonstrateImageFiltering()

💻 Bildtransformationen swift

🟡 intermediate ⭐⭐⭐

Geometrische Transformationen auf Bilder anwenden einschließlich Skalierung, Rotation, Zuschneiden und Spiegeln

⏱️ 30 min 🏷️ swift, macos, image processing, transformations
Prerequisites: Intermediate Swift, CoreGraphics, NSImage
// macOS Swift Image Transformations Examples
// Using CoreGraphics and CoreImage

import Cocoa
import CoreImage
import AppKit

// 1. Resize Image
class ImageResize {

    static func resize(_ image: NSImage, to newSize: NSSize) -> NSImage? {
        print("\n--- Resize Image ---")
        print("Original size: \(image.size)")
        print("New size: \(newSize)")

        let resizedImage = NSImage(size: newSize)
        resizedImage.lockFocus()

        image.draw(
            in: NSRect(origin: .zero, size: newSize),
            from: NSRect(origin: .zero, size: image.size),
            operation: .copy,
            fraction: 1.0
        )

        resizedImage.unlockFocus()

        print("Resized successfully")

        return resizedImage
    }

    static func resizeMaintainingAspectRatio(_ image: NSImage, maxWidth: CGFloat, maxHeight: CGFloat) -> NSImage? {
        print("\n--- Resize Maintaining Aspect Ratio ---")

        let widthRatio = maxWidth / image.size.width
        let heightRatio = maxHeight / image.size.height
        let ratio = min(widthRatio, heightRatio)

        let newSize = NSSize(
            width: image.size.width * ratio,
            height: image.size.height * ratio
        )

        print("Target max: \(maxWidth)x\(maxHeight)")
        print("Calculated size: \(newSize)")

        return resize(image, to: newSize)
    }

    static func scaleBy(_ image: NSImage, scaleX: CGFloat, scaleY: CGFloat) -> NSImage? {
        print("\n--- Scale Image ---")
        print("Scale X: \(scaleX), Scale Y: \(scaleY)")

        let newSize = NSSize(
            width: image.size.width * scaleX,
            height: image.size.height * scaleY
        )

        return resize(image, to: newSize)
    }
}

// 2. Crop Image
class ImageCrop {

    static func crop(_ image: NSImage, to rect: NSRect) -> NSImage? {
        print("\n--- Crop Image ---")
        print("Crop rect: \(rect)")

        // Handle hi-DPI
        guard let rep = image.representations.first as? NSImageRep else {
            print("No image representation")
            return nil
        }

        let scaledRect = NSRect(
            x: rect.origin.x * rep.pixelsWide / image.size.width,
            y: rect.origin.y * rep.pixelsHigh / image.size.height,
            width: rect.size.width * rep.pixelsWide / image.size.width,
            height: rect.size.height * rep.pixelsHigh / image.size.height
        )

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let croppedCGImage = cgImage.cropping(to: scaledRect)
        let croppedImage = NSImage(cgImage: croppedCGImage, size: rect.size)

        print("Cropped to: \(rect.size)")

        return croppedImage
    }

    static func cropToCenter(_ image: NSImage, size: NSSize) -> NSImage? {
        print("\n--- Crop to Center ---")
        print("Target size: \(size)")

        let x = (image.size.width - size.width) / 2
        let y = (image.size.height - size.height) / 2
        let rect = NSRect(x: x, y: y, width: size.width, height: size.height)

        return crop(image, to: rect)
    }

    static func cropToSquare(_ image: NSImage) -> NSImage? {
        print("\n--- Crop to Square ---")

        let minDimension = min(image.size.width, image.size.height)
        let squareSize = NSSize(width: minDimension, height: minDimension)

        return cropToCenter(image, size: squareSize)
    }
}

// 3. Rotate Image
class ImageRotation {

    static func rotate(_ image: NSImage, byDegrees degrees: CGFloat) -> NSImage? {
        print("\n--- Rotate Image ---")
        print("Degrees: \(degrees)")

        guard let cgImage = image.cgImage(forProposedRect: nil, contextHints: nil) else {
            return nil
        }

        let radians = degrees * .pi / 180
        let rotatedRect = CGRectApplyAffineTransform(
            CGRect(origin: .zero, size: image.size),
            CGAffineTransform(rotationAngle: radians)
        )

        let newSize = NSSize(
            width: abs(rotatedRect.width),
            height: abs(rotatedRect.height)
        )

        let rotatedImage = NSImage(size: newSize)
        rotatedImage.lockFocus()

        let transform = NSAffineTransform()
        transform.translateX(by: newSize.width / 2)
        transform.translateY(by: newSize.height / 2)
        transform.rotate(byDegrees: degrees)
        transform.translateX(by: -image.size.width / 2)
        transform.translateY(by: -image.size.height / 2)

        transform.concat()
        image.draw(at: .zero, from: NSRect(origin: .zero, size: image.size), operation: .copy, fraction: 1.0)

        rotatedImage.unlockFocus()

        print("Rotated successfully")

        return rotatedImage
    }

    static func rotate90(_ image: NSImage) -> NSImage? {
        print("\n--- Rotate 90° ---")
        return rotate(image, byDegrees: 90)
    }

    static func rotate180(_ image: NSImage) -> NSImage? {
        print("\n--- Rotate 180° ---")
        return rotate(image, byDegrees: 180)
    }

    static func rotate270(_ image: NSImage) -> NSImage? {
        print("\n--- Rotate 270° ---")
        return rotate(image, byDegrees: 270)
    }
}

// 4. Flip Image
class ImageFlip {

    static func flipHorizontal(_ image: NSImage) -> NSImage? {
        print("\n--- Flip Horizontal ---")

        let flippedImage = NSImage(size: image.size)
        flippedImage.lockFocus()

        NSGraphicsContext.current?.imageInterpolation = .high
        NSAffineTransform.translateX(by: image.size.width, y: 0).concat()
        NSAffineTransform.scale(x: -1, y: 1).concat()
        image.draw(at: .zero, from: NSRect(origin: .zero, size: image.size), operation: .copy, fraction: 1.0)

        flippedImage.unlockFocus()

        print("Flipped horizontally")

        return flippedImage
    }

    static func flipVertical(_ image: NSImage) -> NSImage? {
        print("\n--- Flip Vertical ---")

        let flippedImage = NSImage(size: image.size)
        flippedImage.lockFocus()

        NSGraphicsContext.current?.imageInterpolation = .high
        NSAffineTransform.translateX(by: 0, y: image.size.height).concat()
        NSAffineTransform.scale(x: 1, y: -1).concat()
        image.draw(at: .zero, from: NSRect(origin: .zero, size: image.size), operation: .copy, fraction: 1.0)

        flippedImage.unlockFocus()

        print("Flipped vertically")

        return flippedImage
    }
}

// 5. Border/Padding
class ImagePadding {

    static func addPadding(_ image: NSImage, padding: CGFloat, color: NSColor = .white) -> NSImage? {
        print("\n--- Add Padding ---")
        print("Padding: \(padding)")

        let newSize = NSSize(
            width: image.size.width + 2 * padding,
            height: image.size.height + 2 * padding
        )

        let paddedImage = NSImage(size: newSize)
        paddedImage.lockFocus()

        color.set()
        NSBezierPath(rect: NSRect(origin: .zero, size: newSize)).fill()

        image.draw(
            in: NSRect(origin: NSPoint(x: padding, y: padding), size: image.size),
            from: NSRect(origin: .zero, size: image.size),
            operation: .copy,
            fraction: 1.0
        )

        paddedImage.unlockFocus()

        print("Added padding: \(padding)")

        return paddedImage
    }

    static func addBorder(_ image: NSImage, borderWidth: CGFloat, color: NSColor = .black) -> NSImage? {
        print("\n--- Add Border ---")
        print("Border width: \(borderWidth)")

        let newSize = NSSize(
            width: image.size.width + 2 * borderWidth,
            height: image.size.height + 2 * borderWidth
        )

        let borderedImage = NSImage(size: newSize)
        borderedImage.lockFocus()

        // Fill with border color
        color.set()
        NSBezierPath(rect: NSRect(origin: .zero, size: newSize)).fill()

        // Draw image inside
        image.draw(
            in: NSRect(origin: NSPoint(x: borderWidth, y: borderWidth), size: image.size),
            from: NSRect(origin: .zero, size: image.size),
            operation: .copy,
            fraction: 1.0
        )

        borderedImage.unlockFocus()

        return borderedImage
    }
}

// 6. Perspective Transform
class PerspectiveTransform {

    static func applyPerspective(_ image: NSImage, topLeft: CGPoint, topRight: CGPoint, bottomLeft: CGPoint, bottomRight: CGPoint) -> NSImage? {
        print("\n--- Perspective Transform ---")
        print("Top-left: \(topLeft)")
        print("Top-right: \(topRight)")
        print("Bottom-left: \(bottomLeft)")
        print("Bottom-right: \(bottomRight)")

        guard let ciImage = CIImage(image: image) else {
            return nil
        }

        // Calculate output size
        let maxX = max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x)
        let maxY = max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y)

        let extent = CGRect(x: 0, y: 0, width: maxX, height: maxY)

        guard let filter = CIFilter(name: "CIPerspectiveTransform") else {
            return nil
        }

        filter.setValue(ciImage, forKey: kCIInputImageKey)
        filter.setValue(CIVector(cgPoint: topLeft), forKey: "inputTopLeft")
        filter.setValue(CIVector(cgPoint: topRight), forKey: "inputTopRight")
        filter.setValue(CIVector(cgPoint: bottomLeft), forKey: "inputBottomLeft")
        filter.setValue(CIVector(cgPoint: bottomRight), forKey: "inputBottomRight")

        guard let outputImage = filter.outputImage else {
            return nil
        }

        let context = CIContext(options: [.useSoftwareRenderer: false])
        guard let outputCGImage = context.createCGImage(outputImage, from: extent) else {
            return nil
        }

        let result = NSImage(cgImage: outputCGImage, size: extent.size)
        print("Perspective transform applied")

        return result
    }
}

// 7. Rounded Corners
class RoundedCorners {

    static func applyRoundedCorners(_ image: NSImage, radius: CGFloat) -> NSImage? {
        print("\n--- Rounded Corners ---")
        print("Radius: \(radius)")

        let roundedImage = NSImage(size: image.size)
        roundedImage.lockFocus()

        let rect = NSRect(origin: .zero, size: image.size)
        let path = NSBezierPath(roundedRect: rect, xRadius: radius, yRadius: radius)

        path.clip()
        image.draw(in: rect, from: rect, operation: .copy, fraction: 1.0)

        roundedImage.unlockFocus()

        print("Applied rounded corners")

        return roundedImage
    }

    static func makeCircular(_ image: NSImage) -> NSImage? {
        print("\n--- Make Circular ---")

        let minDimension = min(image.size.width, image.size.height)
        let radius = minDimension / 2

        // First crop to square
        guard let squared = ImageCrop.cropToSquare(image) else {
            return nil
        }

        // Then apply rounded corners
        return applyRoundedCorners(squared, radius: radius)
    }
}

// 8. Thumbnail Generation with Transformations
class ThumbnailGenerator {

    static func generateThumbnail(_ image: NSImage, size: NSSize, mode: ThumbnailMode = .aspectFit) -> NSImage? {
        print("\n--- Generate Thumbnail ---")
        print("Target size: \(size), Mode: \(mode)")

        switch mode {
        case .aspectFit:
            return ImageResize.resizeMaintainingAspectRatio(image, maxWidth: size.width, maxHeight: size.height)

        case .aspectFill:
            // Scale to fill, then crop center
            let widthRatio = size.width / image.size.width
            let heightRatio = size.height / image.size.height
            let ratio = max(widthRatio, heightRatio)

            let scaledSize = NSSize(
                width: image.size.width * ratio,
                height: image.size.height * ratio
            )

            if let scaled = ImageResize.resize(image, to: scaledSize),
               let cropped = ImageCrop.cropToCenter(scaled, size: size) {
                return cropped
            }

        case .stretch:
            return ImageResize.resize(image, to: size)
        }

        return nil
    }

    enum ThumbnailMode {
        case aspectFit
        case aspectFill
        case stretch
    }
}

// 9. Image Composition
class ImageComposition {

    static func overlay(_ baseImage: NSImage, overlay: NSImage, at position: NSPoint, alpha: CGFloat = 1.0) -> NSImage? {
        print("\n--- Overlay Image ---")
        print("Overlay position: \(position)")
        print("Alpha: \(alpha)")

        let compositedImage = NSImage(size: baseImage.size)
        compositedImage.lockFocus()

        // Draw base image
        baseImage.draw(
            in: NSRect(origin: .zero, size: baseImage.size),
            from: NSRect(origin: .zero, size: baseImage.size),
            operation: .copy,
            fraction: 1.0
        )

        // Draw overlay
        overlay.draw(
            in: NSRect(origin: position, size: overlay.size),
            from: NSRect(origin: .zero, size: overlay.size),
            operation: .sourceOver,
            fraction: alpha
        )

        compositedImage.unlockFocus()

        print("Overlay applied")

        return compositedImage
    }

    static func blend(_ image1: NSImage, _ image2: NSImage, mode: BlendMode = .normal) -> NSImage? {
        print("\n--- Blend Images ---")
        print("Mode: \(mode)")

        guard let ciImage1 = CIImage(image: image1),
              let ciImage2 = CIImage(image: image2) else {
            return nil
        }

        let filter = CIFilter(name: "CIScreenBlendMode")
        filter?.setValue(ciImage1, forKey: kCIInputImageKey)
        filter?.setValue(ciImage2, forKey: kCIInputBackgroundImageKey)

        guard let outputImage = filter?.outputImage else {
            return nil
        }

        let context = CIContext()
        guard let outputCGImage = context.createCGImage(outputImage, from: outputImage.extent) else {
            return nil
        }

        return NSImage(cgImage: outputCGImage, size: image1.size)
    }

    enum BlendMode {
        case normal
        case multiply
        case screen
        case overlay
        case darken
        case lighten
    }
}

// 10. Batch Image Transformations
class BatchTransformations {

    static func processImages(in directory: String, operations: [(NSImage) -> NSImage?]) {
        print("\n--- Batch Process Images ---")

        let fileManager = FileManager.default
        guard let files = try? fileManager.contentsOfDirectory(
            at: URL(fileURLWithPath: directory),
            includingPropertiesForKeys: nil
        ) else {
            return
        }

        let imageFiles = files.filter { file in
            ["jpg", "jpeg", "png", "tiff"].contains(file.pathExtension.lowercased())
        }

        print("Processing \(imageFiles.count) images")

        for file in imageFiles {
            let path = file.path

            guard let image = NSImage(contentsOfFile: path) else {
                continue
            }

            var resultImage = image

            for operation in operations {
                if let processed = operation(resultImage) {
                    resultImage = processed
                }
            }

            // Save result
            let outputName = file.deletingPathExtension().lastPathComponent + "_processed"
            let outputPath = (file.deletingLastPathComponent()).appendingPathComponent(outputName).appendingPathExtension("png")

            if let tiffData = resultImage.tiffRepresentation,
               let bitmap = NSBitmapImageRep(data: tiffData),
               let outputData = bitmap.representation(using: .png, properties: [:]) {

                try? outputData.write(to: URL(fileURLWithPath: outputPath))
                print("  Saved: \(outputPath)")
            }
        }

        print("Batch processing completed")
    }
}

// Main demonstration
func demonstrateImageTransformations() {
    print("=== macOS Swift Image Transformations Examples ===")

    // Create a test image
    let testImage = NSImage(size: NSSize(width: 400, height: 300))
    testImage.lockFocus()
    NSColor.blue.set()
    NSRect(origin: .zero, size: NSSize(width: 400, height: 300)).fill()
    NSColor.white.set()
    NSRect(origin: NSPoint(x: 100, y: 100), size: NSSize(width: 200, height: 100)).fill()
    testImage.unlockFocus()

    // Resize
    if let resized = ImageResize.resize(testImage, to: NSSize(width: 200, height: 150)) {
        print("Resize: \(resized.size)")
    }

    // Crop
    if let cropped = ImageCrop.crop(testImage, to: NSRect(x: 50, y: 50, width: 200, height: 150)) {
        print("Crop: \(cropped.size)")
    }

    // Rotate
    if let rotated = ImageRotation.rotate90(testImage) {
        print("Rotated: \(rotated.size)")
    }

    // Flip
    if let flipped = ImageFlip.flipHorizontal(testImage) {
        print("Flipped: \(flipped.size)")
    }

    // Rounded corners
    if let rounded = RoundedCorners.applyRoundedCorners(testImage, radius: 20) {
        print("Rounded corners applied")
    }

    // Make circular
    if let circular = RoundedCorners.makeCircular(testImage) {
        print("Made circular: \(circular.size)")
    }

    // Thumbnail
    if let thumbnail = ThumbnailGenerator.generateThumbnail(testImage, size: NSSize(width: 100, height: 100), mode: .aspectFit) {
        print("Thumbnail: \(thumbnail.size)")
    }

    // Add padding
    if let padded = ImagePadding.addPadding(testImage, padding: 20) {
        print("Padded: \(padded.size)")
    }

    print("\n=== All Image Transformation Examples Completed ===")
}

// Run demonstration
demonstrateImageTransformations()