Skip to content

Commit

Permalink
Merge pull request #98 from boostcampwm-2022/feature_image
Browse files Browse the repository at this point in the history
이미지 처리 및 캐싱 모듈 수정
  • Loading branch information
trumanfromkorea authored Dec 12, 2022
2 parents ca9d0c1 + 04b3960 commit 67b6f66
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 46 deletions.
8 changes: 8 additions & 0 deletions SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
0D706137292C630D0077787E /* DatePickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D706136292C630D0077787E /* DatePickerViewModel.swift */; };
0D706139292C63140077787E /* DatePickerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D706138292C63140077787E /* DatePickerCoordinator.swift */; };
0D70613E292CD24D0077787E /* FirebaseStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D70613D292CD24D0077787E /* FirebaseStorageManager.swift */; };
0D752DB12944A643004A704C /* NSCache+subscript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D752DB02944A643004A704C /* NSCache+subscript.swift */; };
0D752DB32944A964004A704C /* UIImage+resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D752DB22944A964004A704C /* UIImage+resize.swift */; };
0D77D7C9292B5D490038D054 /* SelectButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D77D7C8292B5D490038D054 /* SelectButton.swift */; };
0D90DAEF29238B77000DCC84 /* CapsuleLocateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D90DAEE29238B77000DCC84 /* CapsuleLocateView.swift */; };
0D90DAF129238B85000DCC84 /* CapsuleLocateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D90DAF029238B85000DCC84 /* CapsuleLocateCoordinator.swift */; };
Expand Down Expand Up @@ -203,6 +205,8 @@
0D706136292C630D0077787E /* DatePickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerViewModel.swift; sourceTree = "<group>"; };
0D706138292C63140077787E /* DatePickerCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerCoordinator.swift; sourceTree = "<group>"; };
0D70613D292CD24D0077787E /* FirebaseStorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseStorageManager.swift; sourceTree = "<group>"; };
0D752DB02944A643004A704C /* NSCache+subscript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSCache+subscript.swift"; sourceTree = "<group>"; };
0D752DB22944A964004A704C /* UIImage+resize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+resize.swift"; sourceTree = "<group>"; };
0D77D7C8292B5D490038D054 /* SelectButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectButton.swift; sourceTree = "<group>"; };
0D90DAEE29238B77000DCC84 /* CapsuleLocateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleLocateView.swift; sourceTree = "<group>"; };
0D90DAF029238B85000DCC84 /* CapsuleLocateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleLocateCoordinator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -907,6 +911,8 @@
isa = PBXGroup;
children = (
599C1A42292CC99900517E93 /* KingReceiver+UIImageView.swift */,
0D752DB02944A643004A704C /* NSCache+subscript.swift */,
0D752DB22944A964004A704C /* UIImage+resize.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -1129,6 +1135,7 @@
599C1A4E292CC99A00517E93 /* KingReceiver+UIImageView.swift in Sources */,
288A8EA929235AFC000229D2 /* NicknameCoordinator.swift in Sources */,
288A8EE629235FD5000229D2 /* CapsuleCloseView.swift in Sources */,
0D752DB12944A643004A704C /* NSCache+subscript.swift in Sources */,
0D90DAF7292397CF000DCC84 /* UIColor+.swift in Sources */,
599C1A4B292CC99A00517E93 /* NoneImageCache.swift in Sources */,
28049CE729237B2B002389BD /* BaseViewController.swift in Sources */,
Expand Down Expand Up @@ -1191,6 +1198,7 @@
28A700D52938AE100049FAF8 /* AnimationResource.swift in Sources */,
288A8EE229235E3F000229D2 /* CapsuleLocateViewModel.swift in Sources */,
59D8CFBC29360A8900FD9CF6 /* ThemeThumbnailImageView.swift in Sources */,
0D752DB32944A964004A704C /* UIImage+resize.swift in Sources */,
0D4C11372927489D00B1C2B6 /* UIViewPreview.swift in Sources */,
288A8EB229235B5A000229D2 /* ProfileView.swift in Sources */,
599C1A48292CC99A00517E93 /* KingReceiver.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ final class CustomAnnotationView: MKAnnotationView {
}

func update(for annotation: MKAnnotation?) {
image = (annotation as? CustomAnnotation)?.pinImage?.resize(40)
guard let pinImage = (annotation as? CustomAnnotation)?.pinImage,
let imageData = pinImage.pngData() else {
return
}

let newWidth: CGFloat = 40
let ratio = newWidth / pinImage.size.width
let newHeight = pinImage.size.height * ratio
let size = CGSize(width: newWidth, height: newHeight)

image = UIImage.resize(data: imageData, to: size, scale: 1)
}
}
35 changes: 0 additions & 35 deletions SpaceCapsule/SpaceCapsule/Extensions/UIImage+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,38 +36,3 @@ extension UIImage {
static let refresh = UIImage(systemName: "arrow.clockwise")
}

extension UIImage {
func resize(_ newWidth: CGFloat) -> UIImage {
let scale = newWidth / self.size.width
let newHeight = self.size.height * scale

let size = CGSize(width: newWidth, height: newHeight)
let render = UIGraphicsImageRenderer(size: size)
let renderImage = render.image { _ in
self.draw(in: CGRect(origin: .zero, size: size))
}

return renderImage
}

static func resize(data: Data, to targetSize: CGSize, scale: CGFloat) -> UIImage? {
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let imageSource = CGImageSourceCreateWithData(data as CFData, imageSourceOptions) else {
return nil
}

let maxDimension = max(targetSize.width, targetSize.height) * scale
let resizingOptions = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimension,
] as CFDictionary

guard let resizedImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, resizingOptions) else {
return nil
}

return UIImage(cgImage: resizedImage)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ extension KingReceiverWrapper where Base: UIImageView {
}
}

func setImage(with data: Data, placeholder: UIImage? = nil, size: CGFloat) {
guard let image = UIImage(data: data) else {
func setImage(with data: Data, placeholder: UIImage? = nil, width: CGFloat, scale: CGFloat = 1) {
guard let image = UIImage.resize(data: data, to: base.frame.size, scale: scale) else {
base.image = placeholder
return
}

base.image = image.resize(size)
base.image = image
}

/// 로딩 indicator 시작
Expand All @@ -62,6 +62,7 @@ extension KingReceiverWrapper where Base: UIImageView {
}

stop(indicator: indicator)

indicator.translatesAutoresizingMaskIntoConstraints = false
base.addSubview(indicator)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// NSCache+.swift
// SpaceCapsule
//
// Created by 장재훈 on 2022/12/10.
//

import Foundation

extension NSCache where KeyType == NSString, ObjectType == NSData {
subscript(_ url: URL) -> NSData? {
get {
let key = url.absoluteString as NSString

return object(forKey: key)
}

set {
let key = url.absoluteString as NSString

if let newValue {
setObject(newValue, forKey: key)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// UIImage+.swift
// SpaceCapsule
//
// Created by 장재훈 on 2022/12/10.
//

import UIKit.UIImage

extension UIImage {
static func resize(data: Data, to targetSize: CGSize, scale: CGFloat) -> UIImage? {
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let imageSource = CGImageSourceCreateWithData(data as CFData, imageSourceOptions) else {
return nil
}

let maxDimension = max(targetSize.width, targetSize.height) * scale
let resizingOptions = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimension,
] as CFDictionary

guard let resizedImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, resizingOptions) else {
return nil
}

return UIImage(cgImage: resizedImage)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import Foundation
final class MemoryImageCache: ImageCache {
private let cache = NSCache<NSString, NSData>()

func fetch(with url: URL, completion: @escaping (Data?) -> Void) {
let key = url.absoluteString as NSString
init(cacheLimit: Int = 52428800) {
cache.totalCostLimit = cacheLimit
}

if let data = cache.object(forKey: key) {
func fetch(with url: URL, completion: @escaping (Data?) -> Void) {
if let data = cache[url] {
completion(data as Data)
return
}
Expand All @@ -25,12 +27,12 @@ final class MemoryImageCache: ImageCache {
return
}

self?.save(data: data, with: key)
self?.save(data: data, with: url)
completion(data)
}
}

func save(data: Data, with key: NSString) {
cache.setObject(data as NSData, forKey: key)
func save(data: Data, with url: URL) {
cache[url] = data as NSData
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class AddImageCell: UICollectionViewCell {
}

func configure(data: Data) {
imageView.kr.setImage(with: data, placeholder: .empty, size: frame.size.width)
imageView.kr.setImage(with: data, placeholder: .empty, width: frame.size.width)
}

private func addSubViews() {
Expand Down

0 comments on commit 67b6f66

Please sign in to comment.