Skip to content

Instantly share code, notes, and snippets.

@brownsoo
Created April 9, 2026 02:10
Show Gist options
  • Select an option

  • Save brownsoo/86e0a31ac511460df8ab860147955b77 to your computer and use it in GitHub Desktop.

Select an option

Save brownsoo/86e0a31ac511460df8ab860147955b77 to your computer and use it in GitHub Desktop.
CGImageSourceCreateThumbnailAtIndex 활용하는 이미지 크기 변경
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