Created
April 9, 2026 02:10
-
-
Save brownsoo/86e0a31ac511460df8ab860147955b77 to your computer and use it in GitHub Desktop.
CGImageSourceCreateThumbnailAtIndex 활용하는 이미지 크기 변경
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| import ImageIO | |
| enum ImageResizeError: Error { | |
| case invalidMaxDimension | |
| case cannotCreateImageSource | |
| case cannotReadImageProperties | |
| case cannotCreateThumbnail | |
| case cannotEncodeJPEG | |
| } | |
| extension URL { | |
| func thumbnail(maxDimension: CGFloat = 1123.0) async throws -> URL { | |
| let imageSource = try await makeImageSource(from: self) | |
| guard let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [CFString: Any] else { | |
| throw ImageResizeError.cannotReadImageProperties | |
| } | |
| guard | |
| let pixelWidth = properties[kCGImagePropertyPixelWidth] as? CGFloat, | |
| let pixelHeight = properties[kCGImagePropertyPixelHeight] as? CGFloat | |
| else { | |
| throw ImageResizeError.cannotReadImageProperties | |
| } | |
| let longestSide = max(pixelWidth, pixelHeight) | |
| let thumbnailMaxPixelSize = max(1, min(Int(maxDimension.rounded(.down)), Int(longestSide.rounded(.down)))) | |
| let thumbnailOptions: [CFString: Any] = [ | |
| kCGImageSourceCreateThumbnailFromImageAlways: true, | |
| kCGImageSourceCreateThumbnailWithTransform: true, | |
| kCGImageSourceShouldCache: false, | |
| kCGImageSourceThumbnailMaxPixelSize: thumbnailMaxPixelSize | |
| ] | |
| guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, thumbnailOptions as CFDictionary) else { | |
| throw ImageResizeError.cannotCreateThumbnail | |
| } | |
| let image = UIImage(cgImage: thumbnail) | |
| guard let jpegData = image.jpegData(compressionQuality: 0.9) else { | |
| throw ImageResizeError.cannotEncodeJPEG | |
| } | |
| let tempURL = FileManager.default.temporaryDirectory | |
| .appendingPathComponent(UUID().uuidString) | |
| .appendingPathExtension("jpg") | |
| try jpegData.write(to: tempURL, options: .atomic) | |
| return tempURL | |
| } | |
| private func makeImageSource(from url: URL) async throws -> CGImageSource { | |
| if url.isFileURL { | |
| guard let source = CGImageSourceCreateWithURL(url as CFURL, nil) else { | |
| throw ImageResizeError.cannotCreateImageSource | |
| } | |
| return source | |
| } | |
| let (data, _) = try await URLSession.shared.data(from: url) | |
| guard let source = CGImageSourceCreateWithData(data as CFData, nil) else { | |
| throw ImageResizeError.cannotCreateImageSource | |
| } | |
| return source | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment