Image를 JpegData로 바꾸기

SteadySlower·2022년 7월 11일
0
post-custom-banner

Image를 Data로 바꿔야 하는 이유

구현할 기능

단어장에 텍스트만 저장할 수 있다면 긴 일본어 문장을 전부 키보드로 작성해야합니다. 아직 일본어 타자에 익숙하지 않은 제가 이렇게 문장 연습 단어장을 만든다면 단어를 입력하는 시간이 너무나도 오래 걸릴 것입니다. 따라서 클립보드에서 이미지를 가져와서 사용자에게 보여주고 난 이후에 사용자가 저장 버튼을 누르면 서버에 이미지 파일이 저장될 수 있도록 기능 구현을 해보겠습니다.

아래 캡쳐에서 볼 수 있듯이 “앞면 이미지" 버튼을 누르면 클립보드에 있는 이미지가 사용자에게 보여집니다. 그리고 아래에 저장버튼을 누르면 해당 이미지는 Data 타입으로 변경되어 서버에 저장되게 됩니다.

왜 Data로 바꾸어야 하는가?

클립보드에서 가져온 이미지를 화면에 띄우기 위해서는 Image 타입(UIImage 혹은 NSImage)을 활용해야 합니다. Image 타입(UIImage 혹은 NSImage)는 각각 UIKit과 Cocoa에 선언되어 있다는 점에서 알 수 있듯이 View에 해당 이미지를 나타내기 위한 자료형입니다. 따라서 View에 띄울 때는 자료형의 변환 없이 바로 활용할 수 있지만 네트워크 통신을 위해서는 Data 타입으로 변형해야 합니다.

Data는 반대로 네트워크 통신 혹은 파일 시스템에 저장하는 것에는 최적화된 유형이지만 Image 타입으로 변형하지 않으면 View에 바로 띄울 수는 없습니다.

이 포스팅에서는 Image를 네트워크 전송을 위해 jpeg 방식의 data로 변경하는 방법을 알아봅니다.

Image to Data

UIImage

UIImage에는 jpeg Data로 바로 바꾸어주는 메소드가 있어서 한 줄의 코드로 변경할 수 있습니다. 인자인 compressionQuality에는 압축률을 전달하면 됩니다. 0.0 ~ 1.0 사이의 CGFloat이고 숫자가 클 수록 높은 퀄리티입니다.

func compressImageToJPEG(image: UIImage) -> Data {
    image.jpegData(compressionQuality: 0.5)!
}

NSImage

NSImage의 경우 UIImage처럼 한번에 jpeg Data로 바꾸어주는 메소드는 없습니다.

몇가지 과정을 거쳐야 하는데요.

  1. 먼저 NSImage를 CGImage 바꿔줍니다. CGImage는 비트맵 방식의 이미지 입니다.
  2. 그 후에 CGImage를 NSBitmapImageRep로 바꾸어줍니다. NSBitmapImageRep는 이미지 자체가 아니라 이미지를 비트맵 데이터에서 가져와서 이미지로 랜더링을 해주는 객체입니다. 즉 비트맵 데이터 → 이미지를 담당하는 객체인데요. 우리는 이 방식을 거꾸로 해서 이미지 → 데이터로 바꾸는 작업을 하는 중입니다.
  3. NSBitmapImageRep의 repesentation 메소드를 활용해서 jpeg data로 바꾸어 줍시다. 해당 메소드는 지정한 storage type (여기서는 jpeg)으로 변경해서 Data 객체를 만들어줍니다.
    1. UIImage처럼 압축률을 정해줄 수도 있습니다. property에 key를 compressionFactor로 압축률(0.0 ~ 1.0)을 value로 한 dictionary를 전달하면 됩니다.
func compressImageToJPEG(image: NSImage) -> Data {
		//1. NSImage를 CGImage로 변경
    let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)!
		//2. CGImage를 NSBitmapImageRep로 변경
    let bitmapRep = NSBitmapImageRep(cgImage: cgImage)
		//3. NSBitmapImageRep를 Data로 변경
    let jpegData = bitmapRep.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:])!
    return jpegData
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.
post-custom-banner

0개의 댓글