이미지 픽커 또는 갤러리에서 이미지를 가져오는 방식에 따라 용량차이가 많이 나서 여러가지 방법을 찾아봤습니다.

1. PHCachingImageManager를 통해서 Asset 이미지 가져오기

   : 예를들어 실제 파일 사이즈가 2MB 정도지만 아래 방식으로 UIImage 로 받을 경우 이미지를 디코딩 및 압축 해제과정에서 이미지 

     용량이 기하급수적으로 늘어납니다.. 그래서 서버로 이미지를 업로드시 JPG Data로 변환할때 압축비를 0.7 ~ 1.0 정도 조절하는데 

     화질에 민감한 이미지의 경우 압축비율을 1.0으로 할 경우 7.3MB나 되는 용량으로 업로드가 됩니다.

 

[Log Data] 실제 데이터 크기
Data Value[1] : Image URL : file:///var/mobile/Media/DCIM/100APPLE/IMG_0222.HEIC
Data Value[2] : 2.5892372131347656MB

 

[Log Data] UIImage로 변환되서 받았을때 데이터 크기
Data Value[1] : image1
Data Value[2] : 7.346070289611816MB

let imageManager = PHCachingImageManager()
imageManager.requestImage(for: assets[i], targetSize: CGSize(width: assets[i].pixelWidth, height: assets[i].pixelHeight),
                          contentMode: .aspectFit,
                          options: option) { image, _ in
                                   
                               guard let image = image else { return }
                               
                               // 이미지 처리
                         }

 

 

2. Asset 이미지를 UIImage 대신 JPG Data 형태로 받아서 처리하면 이미지 용량이 많이 줄어듭니다.

UIImage로 변환된 상태로 받는거 보다 늘어나는 크기가 훨씬 적어집니다. 이미지 퀄리티는 동일한 걸로 예상됩니다.

 

[Log Data] 실제 데이터 크기
Data Value[1] : Image URL : file:///var/mobile/Media/DCIM/100APPLE/IMG_0222.HEIC
Data Value[2] : 2.5892372131347656MB

 

[Log Data] JPG Data로 변환되서 받았을때 데이터 크기
Data Value[1] : image1
Data Value[2] : 3.34MB

let imageManager = PHCachingImageManager()
let option = PHImageRequestOptions()
option.isNetworkAccessAllowed = true // for icloud
option.deliveryMode = .highQualityFormat

var imageDatas: [Data] = []

if assets.count > 0 {
    LoadingHUD.show()
}

for i in 0..<assets.count {
    
    let resources = PHAssetResource.assetResources(for: assets[i])
    let filename = resources.first!.originalFilename
    
    /*
     HEIC파일의 경우 Data형태로 받아서 Jpeg 데이터로 변형 전송
     JPG 파일의 경우 Data형태 바이패스 전송
     https://stackoverflow.com/questions/46759347/convert-heif-photo-to-jpeg-for-uploading-to-backend/46991535#46991535
     */
    
    let options : PHImageRequestOptions = PHImageRequestOptions()
    options.deliveryMode = .highQualityFormat
    options.version = .original
    options.resizeMode = .none
    options.isSynchronous = true
    imageManager.requestImageData(for: assets[i], options: options) { data, string, orient, info in
        
        if filename.contains(".HEIC") {
            // JPEG 데이터로 변경 (UIImage 사용금지)
            let ciImage = CIImage(data: data!)
            let imageData = CIContext().jpegRepresentation(of: ciImage!, colorSpace: CGColorSpaceCreateDeviceRGB())!
            imageDatas.append(imageData)
        } else {
            // 그외 포맷은 Data형태 바이패스
            imageDatas.append(data!)
        }
        
        if imageDatas.count == assets.count {
            completion(imageDatas)
            LoadingHUD.hide()
        }
    }
}

 

 

3. Asset URL Path로 다이렉트 Data 불러서 사용하기

이경우 아이폰의 HEIC 확장자를 Data에 다이렉트로 담아서 보내야되서 서버쪽에서 라이브러리를 통해서 HEIC -> JPG로 변환작업을 해줘야됩니다.

 

서버로 전송되는 용량은 로드했을때와 동일합니다.

 

asset.requestContentEditingInput(with: nil) { (editingInput, info) in
if let input = editingInput, let imgUrl = input.fullSizeImageURL {                                        
	let data = try! Data(contentsOf: imgUrl)
    // 이미지 data 처리
}

+ Recent posts