Skip to content

Instantly share code, notes, and snippets.

@lightandshadow68
Last active May 24, 2021 14:59
Show Gist options
  • Save lightandshadow68/2301a10fcb675198cb51820678828cc6 to your computer and use it in GitHub Desktop.
Save lightandshadow68/2301a10fcb675198cb51820678828cc6 to your computer and use it in GitHub Desktop.
import Foundation
import SwiftUI
class ViewModel: ObservableObject {
var downloadURL = URL(string: "https://i.redd.it/dwlyzl73nv071.jpg")!
@Published var downsampledImage: Image?
func downloadResourceToURL(optimize: Bool, width: CGFloat) {
let downloadTask = URLSession.shared.downloadTask(with: downloadURL) { url, response, error in
if let tempURL = url {
self.downsampleResource(at: tempURL, optimize: optimize, width: width)
}
}
downloadTask.resume()
}
func downloadResourceToData(width: CGFloat) {
let dataTask = URLSession.shared.dataTask(with: downloadURL) { data, response, error in
if let resourceData = data {
self.downsampleResource(data: resourceData, width: width)
}
}
dataTask.resume()
}
func downsampleResource(at url: URL, optimize: Bool, width: CGFloat) {
let options = (optimize ? [kCGImageSourceShouldCache: false] : [kCGImageSourceShouldCache: true]) as CFDictionary
if let source = CGImageSourceCreateWithURL(url as CFURL, options) {
let targetDimension = width
var thumbnailOptions: CFDictionary {
if optimize {
return [kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceThumbnailMaxPixelSize: targetDimension] as CFDictionary
}
return [kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceShouldCacheImmediately: false,
kCGImageSourceThumbnailMaxPixelSize: targetDimension] as CFDictionary
}
guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, thumbnailOptions) else { return }
DispatchQueue.main.async {
self.downsampledImage = Image.init(decorative: thumbnail, scale: 1.0)
print(thumbnail)
}
}
}
func downsampleResource(data: Data, width: CGFloat) {
let optimize = false
let options = (optimize ? [kCGImageSourceShouldCache: false] : [kCGImageSourceShouldCache: true]) as CFDictionary
if let source = CGImageSourceCreateWithData(data as CFData, options) {
let targetDimension = width
let thumbnailOptions = [kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceThumbnailMaxPixelSize: targetDimension] as CFDictionary
guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0,thumbnailOptions) else { return }
DispatchQueue.main.async {
self.downsampledImage = Image.init(decorative: thumbnail, scale: 1.0)
print(thumbnail)
}
}
}
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
GeometryReader { proxy in
VStack(spacing:8) {
Button("Downsample URL Optimized Exact") { viewModel.downloadResourceToURL(optimize: true, width: proxy.size.width) }
Button("Downsample URL Optimized 700") { viewModel.downloadResourceToURL(optimize: true, width: 700) }
Button("Downsample URL Exact") { viewModel.downloadResourceToURL(optimize: false, width: proxy.size.width) }
Button("Downsample URL 700") { viewModel.downloadResourceToURL(optimize: false, width: proxy.size.width) }
Button("Downsample Data") { viewModel.downloadResourceToData(width: proxy.size.width) }
if let image = viewModel.downsampledImage {
image
.resizable()
.aspectRatio(contentMode: .fit)
} else {
Image(systemName: "photo")
.resizable()
.aspectRatio(contentMode: .fit)
}
}
}
}
}
@main
struct ImageIOApp: App {
var body: some Scene {
WindowGroup {
ContentView(viewModel: ViewModel())
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment