728x90
반응형
안녕하세요 욱승입니다.
요새 토이 프로젝트를 진행중인데 메모리 관련해서 이슈가 생겼는데 남겨두면 좋을것 같아서 포스팅 해봅니다! (태클 환영)
그럼
우선 결과부터 보면 이러함
프로젝트 진행중 메모리가 기하급수적으로 증가하는걸 볼수 있는데 이것은 서버에서 불러오는 이미지 크기 및 해상도와 ImageView의 해상도 이미지 크기 및 해상도가 맞지않아 억지로 끼워넣고 원본이미지는 파일 크기가 너무 커 메모리가 기하급수적으로 증가하는 것.
그래서 이미지 리사이징이 필요한데
이미지 리사이징이란?
이미지가 커서 메모리를 많이 잡아먹다보면 메모리 부족으로 앱이 죽어버리는 경우가 생긴다고해요.
이러한 현상을 줄이고자 이미지 사이즈를 줄여 다시 만들어내는데 이것을 이미지 리사이징이라고 해요!
이미지작업을 위해서 사용할 클래스는 UIGraphicsBeginImageContext, UIGraphicsImageRenderer가 있는데 이둘의 차이는 구버전과 신버전의 차이라고 하네요
WWDC18에서는 UIGraphicsImageRenderer을 권장 하고있음 !
이미지 리사이징에 다양한 방법이 있겠지만 이 두가지 버전을 소개해볼까함
// UIGraphicsBeginImageContext
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage {
let scale = newWidth / image.size.width
let newHeight = image.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
// UIGraphicsImageRenderer
func resize(image: UIImage, newWidth: CGFloat) -> UIImage {
let scale = newWidth / image.size.width
let newHeight = image.size.height * scale
let size = CGSize(width: newWidth, height: newHeight)
let render = UIGraphicsImageRenderer(size: size)
let renderImage = render.image { context in
image.draw(in: CGRect(origin: .zero, size: size))
}
return renderImage
}
사용법
func setProfileImage(_ imageView: UIImageView,_ urlString: String?) {
guard let urlString = urlString else {
imageView.image = UIImage(named: "NonProfile")
return
}
let url = URL(string: urlString)
//DispatchQueue를 쓰는 이유 -> 이미지가 클 경우 이미지를 다운로드 받기 까지 잠깐의 멈춤이 생길수 있다. (이유 : 싱글 쓰레드로 작동되기때문에)
//DispatchQueue를 쓰면 멀티 쓰레드로 이미지가 클경우에도 멈춤이 생기지 않는다.
DispatchQueue.global().async {
DispatchQueue.main.async {
imageView.kf.indicatorType = .activity
imageView.kf.setImage(
with: url,
placeholder: nil,
options: [.transition(.fade(1.2))],
completionHandler: { result in
switch(result) {
case .success(let imageResult):
// UIGraphicsImageRenderer 방식
let resized = resize(image: imageResult.image, newWidth: 40)
imageView.image = resized
imageView.isHidden = false
case .failure(let error):
imageView.isHidden = true
}
})
}
}
}
728x90
반응형
'iOS > Swift' 카테고리의 다른 글
[Swift] print와 dump차이, 콘솔에 로그찍기 Console Log (0) | 2023.03.16 |
---|---|
[Swift] API 가이드라인 (0) | 2023.03.10 |
[Swift] App Version정보 가져오기 (0) | 2023.01.10 |
[Swift] privacy-sensitive 에러 메시지 ImagePicker 이슈 (0) | 2022.12.29 |
[Swift] defer 문이란? (0) | 2022.10.05 |