본문 바로가기

Android/Tech

비트맵과 WebP

 

A Sunday Afternoon on the Island of La Grande Jatte, 점묘, 1886. Georges Seurat.

 

인간의 눈으로 디지털 디바이스에서 표시되는 이미지 (그림, 사진) 를 보는 것은 픽셀이라는 작은 점들이 빼곡히 모여있는 것을 보는 것과 같습니다. 학창 시절 미술 시간에 한 번 쯤은 해보았던 점묘화와 그 개념이 같습니다. 

 

디바이스마다 사이즈가 다르고, 1개의 픽셀에 적용할 수 있는 비트 수가 다릅니다. 

비트맵은 픽셀의 사각형 배열 내에서 각 픽셀의 색을 지정하는 비트 배열입니다. 개별 픽셀에 적용되는 비트 수에 따라 픽셀에 할당할 수 있는 색의 수가 결정됩니다. 즉, 비트 수가 높을 수록 더욱 다양한 색상을 할당할 수 있습니다.

 

픽셀당 비트 수 비트 당 색상 수
픽셀당 비트 수 1 2^1 = 2
픽셀당 비트 수 2 2^2 = 4
픽셀당 비트 수 4 2^4 = 16
픽셀당 비트 수 8 2^8 = 256
픽셀당 비트 수 16 2^16 = 65,536

 


 

픽셀 당 비트 수가 많으면, 그만큼 이미지가 더 많은 용량을 차지하게 됩니다.

1픽셀이 16비트를 포함하는 1280 * 720 이미지의 용량은 1280 * 720 * 16 인 14,745,600bit 이며,

이를 메가바이트로 환산하면 1.75MB 정도 됩니다. 우리가 봐 왔던 의 이미지 파일 정도의 용량으로 납득 가능한 사이즈입니다.

 

문제는 고해상도 이미지로부터 생겨납니다. 고화질 이미지의 경우, 가로 세로가 5,000 픽셀을 넘기는 경우도 많습니다. 이런 고해상도 이미지를 안드로이드에서 사용하게 되면, 렌더링에 시간이 오래 걸리는 것은 차치하고, 메모리 부족으로 앱이 뻗어버리는 경우도 있습니다. 

 

예를 하나 들어봅니다.

1픽셀이 16비트를 포함하는 5000 * 5000 이미지의 용량은 5000 * 5000 * 16 인 400,000,000bit 이며,

이를 메가바이트로 환산하면  47.68MB 정도 입니다. 모바일 뿐만 아니라 PC 환경에서도 가볍게 다루기 버거운 사이즈입니다. 이 마저도 16비트라 이 정도이고, 트루 컬러로 불리는 24비트 이미지를 사용하는 경우엔 메모리가 더 늘어날 것입니다. 

 

위와 같은 상황을 피하기 위해, 우리는 압축 포맷을 이용할 수 있습니다.

 


BMP 와 압축 포맷

 

위 기술하였듯 비트맵은 메모리 문제를 갖고 있습니다. 이미지 원본을 그대로 사용하여 가장 깔끔하다는 장점이 있지만, 픽셀 당 비트 수가 많고 해상도가 높을 수록 다루기 힘든 사이즈를 갖게 됩니다. '용량이 커진다' 는 것은 네트워크를 통해 이미지를 전송하는 시간과 비용이 많이 소모됨을 의미하고, 이는 고스란히 비용 문제로 이어집니다. 

 

이런 문제를 회피하기 위해 BMP 파일을, 이제는 익숙한 JPEG, PNG, WebP 등의 파일로 변환할 수 있습니다.

압축 포맷은 말 그대로 이미지를 작게 압축한 포맷을 의미합니다. 압축 포맷은 손실 압축 포맷

무손실 압축 포맷으로 나뉘게 됩니다.

 


손실 압축 포맷

디지털 풍화

 

요새는 무손실 압축 포맷인 PNG 를 자주 사용하지만, 약 10년 전만 해도 인터넷에는 JPEG 파일의 이미지가 많았습니다. JPEG 는 대표적인 손실 압축 이미지 포맷입니다. 위 이미지는 JPEG 파일이 캡쳐되고 내려받아지고 또 다시 압축 변환되며 생겨난 이미지입니다. 

 

손실 압축은 사진이나 음악, 동영상 등 주로 멀티미디어 데이터에서 인간이 지각하기 힘든 범위의 데이터는 소거하고 압축하는 방법입니다. 인지 심리학과도 관계가 있습니다.

 

실질적으로 필요하지 않다고 판단된 데이터는 과감하게 제거하기에 파일의 용량이 비약적으로 줄어듭니다. 이러한 원리에 입각하여, 이미지 압축을 위한 크로마 서브 샘플링이라는 기술이 있습니다. 인간의 눈이 색차보다 명도에 민감하게 반응하기 때문에, 비교적 민감하지 않은 색차 정보에 대한 압축을 수행합니다. 즉, 인간이 차이를 인지하기 힘든 색차 정보를 제거하여 직접적으로 용량을 줄이는 것입니다. 

 

손실 압축 포맷의 종류는 JPEG(JPG), WebP, BPG, AVIF 등 다양합니다. 

 


무손실 압축 포맷

PNG 이미지. Alpha (투명도) 값을 정의할 수 있으므로 배경이 투명하다.

 

PNG는 대표적인 무손실 압축 이미지 포맷입니다. 안드로이드 개발에도 굉장히 많이 사용됩니다. 이름 그대로 손실이 없습니다. 

 

대체적으로 같은 비트맵에 대한 변환으로 만들어진 JPEG 와 PNG 중 용량이 작은 파일은 당연히 손실 압축 포맷인 JPEG입니다. 다만, JPEG 는 Alpha 값에 대한 정의를 할 수 없고 화질도 떨어지는 편이기에 PNG 를 사용하는 경향이 강해지기 시작했습니다. 변환 기술의 비약적인 발전의 영향도 있습니다.

 

🤔 손실이 없는데 어떻게 용량이 줄어드나요?

 

원리가 조금 복잡합니다. 미디어 파일의 엔트로피 (무질서도) 가 낮을 수록 압축이 잘 되는데, 이는 해당 파일의 데이터가 얼마나 일관적이냐에 따라 압축률이 변할 수 있음을 의미합니다.

데이터가 일관적일 수록 더욱 많은 부분을 간단하게 축약 및 치환할 수 있습니다.

예를 들어, '0123' 을 'a' 로 치환하면 '012301230123' 은 'aaa' 로 표시할 수 있습니다. 그럼 '0123' 4바이트를 'a' 1바이트로 줄일 수 있습니다. 즉, 12바이트를 3바이트로 줄인 것입니다. 

물론, 위와 같이 칼같이 떨어지진 않습니다. 파일 내부에 해당 치환에 대한 정보를 포함하는 별도의 메타 데이터가 추가되기 때문입니다.

 


WebP

 

유튜브 채널의 썸네일은 모두 WebP 포맷.

 

WebP 는 구글에서 만든 이미지 포맷입니다. '웹피' 라고 부릅니다.

구글은 세계 최대의 서피스 웹 포털 검색 서비스를 제공하고 있습니다. 큰 서비스를 제공하는 만큼 유지 보수에 큰 비용이 소요됩니다. 텍스트는 물론이고, 수많은 이미지를 표시해야 하는데 이 이미지들이 최적화가 되지 않는다면 불필요한 비용이 추가로 소요될 수 있습니다. 

 

WebP 는 특이하게 손실 압축 방식과 무손실 압축 모두 지원합니다.

손실 압축의 경우 JPEG 파일보다 30% 정도 파일 크기가 작다고 소개하고 있으며,

무손실 압축의 경우 PNG 파일보다 약 20~30% 정도가 작은 파일을 생성할 수 있다고 소개합니다.

 

위와 같은 장점이 있지만 단점도 있긴 합니다.

 

저전력 기기의 사양에 따라 렌더링에 높은 리소스를 필요로 하기도 합니다. WebP 가 GIF 에 비해 데이터를 아껴도, WebP 를 렌더링하는 과정에서 소모되는 배터리나 RAM, CPU, AP 점유 및 소모를 통해 전체적인 효율이 떨어질 수 있습니다. 다만, 최근에는 기기들의 성능이 워낙 좋아져서 큰 문제가 되진 않습니다.

 

2021년 부터는 애플도 WebP 를 지원하기 시작하였습니다. 멀지 않은 미래에 PNG, JPEG 를 모두 대체할 수 있는 WebP 가 대세가 될 수 있지 않을까 생각합니다.

 


In Android

안드로이드 역시 구글이 만든 것이므로, WebP 를 완벽하게 지원합니다. 내부에서의 파일 변환도 자유롭습니다. 

 

FileOutputStream out = new FileOutputStream(path); 
bitmap.compress(Bitmap.CompressFormat.WEBP_LOSSLESS, 100, out);
out.close();

 

CompressFormat 의 경우 기존에는 WEBP 라는 이름으로 손실 압축 형식만 지원했으나, 현재는 WEBP 가 @Deprecated 되고 WEBP_LOSELESS, WEBP_LOSSY 를 지원합니다. 전자는 무손실, 후자는 손실 압축입니다.

 

사실 WebP 의 경우 무손실 및 손실 간의 차이가 거의 없다시피해서 어떤 것을 선택하든 비슷한 결과물을 보여줍니다.

 


 

진행 중인 사이드 프로젝트에서 서버 비용을 줄이기 위해 PNG 대신 WebP 포맷을 선택하게 되면서 공부했던 내용을 기록했습니다.

 


2023.02.08 추가

실제로 프로젝트에 WebP 를 활용해보았고, 그 용량은 다음과 같습니다.

 

 

 

설 연휴때 만난 할머니댁 강아지입니다. 순서대로 위가 원본, 아래가 변환된 WebP 입니다. 육안으로 보았을 때는 같은 파일처럼 보입니다.

 

원본 용량

 

WebP 용량

 

2.2MB 정도 줄어들었습니다. 이미지 사이즈는 조절하지 않았고, 손실 압축에 로스율은 50% 로 수행했습니다. 확실한 차이를 보이므로, 가능하다면 서비스나 프로젝트에 WebP 형태로 이미지를 저장하는 것이 바람직해 보입니다.