[Swift] JPEG압축 사용시 주의할 사항


문제 발생

이미지를 AI모델로 변환해주는 서버API를 이용할때 일입니다. 이미지를 보내기 위해 UIImage타입의 이미지를 Data타입으로 압축해서 보내야 했습니다.

위의 이미지의 예시는 400x400를 각각 JPEG압축, PNG압축을 한 결과 인데, 크기는 약 1.6배 정도 차이나지만, 육안으로 봤을 때 퀄리티 차이가 있지 않습니다. 이미지 퀄리티가 중요했던 모델이 아니였기 때문에 용량이 적은 JPEG압축을 이용했습니다.

(400x400크기 기준 흰선 생기는 정도)

하지만 변환된 이미지의 오른쪽과 아래쪽에 흰선이 생기는 문제가 생겼습니다.
서버요청을 보내기 직전에 압축을 해서 보내기 때문에 원인을 찾기가 힘들었고, 당연히 서버API의 문제라고 생각했습니다.
결론적으로 JPEG의 손실압축이 문제의 원인이 였습니다.

JPEG 압축과정

나무위키에 따르면 JPEG 압축과정은 YIQ모델로 변환 → Macroblock화 → 8×8블록화 → 이산 코사인 변환 → 양자화 → 지그재그 스캐닝 → 엔트로피 코딩의 단계를 거친다고 합니다.

제가 길게 설명하는 것보다 유튜브 영상(JPEG은 왜 디지털 풍화가 생길까 - 코딩애플)을 보시는게 이해하는데 더 도움이 될 것 같습니다.

흰선 이슈

JPEG압축으로 인한 디지털풍화현상은 양자화(Quantization)이 주원인 입니다. 하지만 이번에 발생한 오른쪽과 아래에 생긴 흰선도 양자화(Quantization)때문일까 테스트를 해보았습니다.
차이를 명확히 보기 위해 50x50사이즈로 이미지를 줄여서 테스트를 하였습니다.
이 처럼 Quantization수치(quality)가 낮을 수록 디지털 풍화현상이 심하다는 것을 확인할 수 있습니다. 하지만 흰선이 생기는 원인은 아닙니다.

다음으로 Quantization수치(quality)는 1.0으로 고정시키고 사이즈를 소수점 단위로 다르게 하여 테스트를 해보았습니다.
위의 결과를 보면 알듯이 소수점단위의 크기의 이미지를 압축할때 흰선 이슈가 발생했습니다.

결론

먼저 테스트해본 결과 다음과 같습니다.

  • width의 크기가 소수점 단위가 있을 경우 오른쪽에 흰선 생김
  • height의 크기가 소수점 단위가 있을 경우 아래쪽에 흰선 생김

이점으로 미루어보면 Macroblock화 → 8×8블록화과정에서 발생한 이슈이지 않을까 추측하고 있습니다.
데이터용량보다 퀄리티가 중요하다면, 무손실압축인 PNG압축방식을 이용하는게 좋을 것 같습니다.
만약 JPEG압축방식을 사용할 수 밖에 없다면, 이미지의 크기를 정수단위로 만드는 것이 중요합니다.

참고링크

https://namu.wiki/w/JPEG
https://namu.wiki/w/YUV
JPEG은 왜 디지털 풍화가 생길까 - 코딩애플




© 2021.02. by kirim

Powered by kkrim