• JPEG vs. PNG: 적절한 이미지 포맷 선택하기 (1) - JPEG편

    2021. 1. 23.

    by. 나나 (nykim)

    320x100

     

    프롤로그

    이미지 저장할 때 이런 고민한 적 없으신가요? 🤔🤔

     

     

    이미지는 웹페이지에서 많은 부분을 차지하는 리소스입니다. 따라서 용량이 적을 수록 당연히 좋죠.
    그래서 이미지를 표시할 때 적절한 포맷을 택하는 것이 여러모로 중요합니다.
    웹에서 사용하는 주 이미지 포맷은 JPEG와 PNG일 텐데, 그럼 둘 중에 뭘로 저장하는 게 좋을까요?

     

     

    저는 기존까지 이렇게 알고 있었는데요,

    • JPEG → 복잡한 이미지나 사진

    • PNG → 단순한 이미지, 투명 표현이 필요한 이미지

     

    결론부터 말하면 저게 맞습니다!

     

    👀어... 너무 당연한 얘기를 했나요 👀
    ‘사진은 JPEG! 투명 배경은 PNG!’라고만 알아도 충분하긴 하지만,
    그 이유가 궁금하기도 했고 사진도 아니고 투명하지도 않은 이미지는 어떤 포맷이 맞는 걸까 싶을 때도 있더라고요.

     

     

    일단 저렇게 나눠야 하는 이유는 JPEG와 PNG의 압축 방식이 다르기 때문입니다.
    아래 이미지는 겉보기엔 같아 보이지만 포맷이 다르며 용량도 다릅니다.

     

    GIF, JPEG, PNG

     

     

     

    게다가 확대해서 보면 이런 차이점도 있어요.

     


    도대체 왜 저렇게 차이가 나는가! 압축 방식이 다르다는 게 무슨 뜻인가!
    그것이 궁금해서 정리해보았습니다 🤓

     

     

     


     


    JPEG, 자기소개 부탁드립니다

    JPEG는 현재 웹에서 쓰이는 이미지 포맷 대부분을 차지하고 있고 가장 대중적인 존재감을 자랑합니다.
    게시글 제목이 고양이.jpeg면 무조건 클릭해야 하는 거 다 알잖아요 🐈

     

     

    사진을 위한 포맷

     

     

    이름인 JPEG는 Joint Photographic Experts Group의 약자입니다.
    풀어서 쓰면 '합동 사진 전문가 그룹'이 되는데요, 본래는 표준을 제정하는 단체를 뜻하는 말입니다.
    보통은 이미지 압축 방법 표준을 가리키는 말로 사용하고 있지만요.
    ISO*랑 CCITT*(지금의 ITU-T)가 협력해서 만들었기 때문에 Joint라는 이름이 붙었다고 합니다.
    읽을 때는 제이펙이라고 읽어주면 됩니다. (하지만 그냥 제이-피-지일 뿐)

    중요한 건 이름에서 알 수 있듯이 '사진'을 위한 이미지 포맷이란 거죠!

     

     

     

    JPEG는 픽셀 기반 이미지며, 하나의 픽셀에 24비트가 저장되어 있습니다.

    즉, 2^24 = 16,777,216의 색을 나타낼 수 있습니다.

     

    비트가 뭐지? 👾

    1비트는 0 또는 1이란 두 개의 경우를 나타냅니다.
    2비트는 00, 01, 10, 11 이렇게 4개의 경우를 나타낼 수 있습니다.
    그럼 3비트는 000, 001, 010, 011, 100, 101, 110, 111 이렇게 8개의 경우를 표현할 수 있겠네요.
    이는 2^1=2, 2^2=4, 2^3=8... 과 같이 표현할 수 있습니다. 즉, n비트는 2^n이 됩니다.

     

    좀 더 풀어서 쓰면 24비트 이미지는 R, G, B 채널에 각각 8비트씩 할당합니다.
    각 채널에 8비트씩 할당한다고 했는데요, 8비트는 2^8 = 256이 되겠죠?
    그래서 [0, 0, 0] 부터 [255, 255, 255]에 이르는 색을 표현할 수 있어요.

     

     


    예를 들어 파란색은 [35, 135, 245]이란 3개의 채널값으로 표현할 수 있습니다.
    이는 결국 [8bit, 8bit, 8bit] 로 볼 수 있고, 따라서 총합 [24bit]가 됩니다.
    픽셀 하나에 24비트를 할당한다는 건 바로 이 뜻이에요.

    그래서 2^24인 16777216 색을 표현할 수 있는 것입니다. 또는 256^3을 해도 같은 값이 나오겠죠.
    사람이 볼 수 있는 모든 색을 표현했다는 의미에서 이를 트루컬러 또는 풀컬러라고도 부릅니다.

     


    이렇게 JPEG는 다채로운 색을 표현할 수 있어 사진과 같은 이미지에 적합합니다.

    하지만 RGB 3개의 채널만 갖고 있고, 알파 채널을 지원하지 않기 때문에 투명한 배경화면을 사용할 수 없습니다.
    생각해보면 사진이 투명할 수는 없으니까 그런 기술이 필요 없긴 하죠 🧐

     


    *ISO: 국제표준화기구
    *CCITT: 국제전신전화자문위원회

     

     

     



    JPG = JPEG

    그러고보면 JPEG를 종종 JPG라고 줄여 부르기도 하던데요? 넵, 둘은 같은 말입니다!

     

     

    이전 Windows 운영 체제에서는 파일 이름을 최대 3자밖에 쓸 수 없었기 때문에 줄여서 사용한 것이 JPG라고 합니다.
    물론 요즘 Windows는 4글자 파일 확장자를 사용할 수 있지만 워낙 많이 사용했다보니 아직도 섞어 쓰고 있습니다.
    그리고 png, gif, bmp 처럼 세글자 어감이 착착 붙기도 하고요 ;)



     

    JPEG 2000은 신세대

    한편 JPEG 뒤에 2000이란 숫자가 붙은 포맷도 있는데, 이건 그냥 JPEG보다 조금 더 고급스러운 표준임을 나타냅니다. 2000년에 발표됐기에 저런 X세대적인 이름이 붙었습니다.
    JPEG는 DCT라는 기술을 쓰지만 JPEG 2000은 DWT라는 기법을 쓴다는 차이점이 있습니다.
    그밖에 비손실 압축도 가능하고 품질은 유지한 채 더 높은 압축 비율을 제공하는 등, JPEG보다 뛰어난 성능을 보이는 압축 표준입니다.

    하지만 잘 안 쓰는 데는 이유가 있죠.
    처음 개발됐을 때 완전히 새로운 포맷이다보니 이전 버전과 호환되지 않아, JPEG 2000을 지원하려면 기존의 JPEG도 지원할 수 있도록 인코딩해야 했습니다.
    또 더 많은 메모리를 필요로 한다는 문제도 있었고요.

    그래서 웹 브라우저나 카메라 제조업체도 '호환성 문제도 있으니 우리 좀 시간을 두고 친해질까?'하며 거리를 두있는데요.
    20년이 지났지만 아직도 어색한 사이로 남았다고 합니다...

    웹의 관점에서 보자면 지원하는 브라우저가 적기 때문에 잘 사용하지 않는 포맷이라고 볼 수 있습니다.

     

     

    [참고]

     

     

     

     

    손실 압축: 품질 대신 용량을 택하다

     


    JPEG는 손실 압축이라고 해서 이미지 품질을 희생하고 더 적은 용량을 택합니다.
    중요한 정보는 최대한 보존하고 사람들이 잘 느끼지 못하는 정보는 몰래몰래 내다버리는(?) 방법이죠.

    그래서 JPEG로 저장하기만 해도 손실이 일어나며 저장을 누적할 수록 손실도 누적됩니다.
    JPEG 저장을 반복하다보면 이른바 너덜너덜해진 짤방 같은 모습이 됩니다.
    (JPEG도 무손실 모드를 택할 수 있지만 널리 지원되지는 않습니다.)

    그럼 JPEG가 어떤 알고리즘으로 이미지를 압축하는지 짧게 훑어봅니다.

     




    1) 색 공간 변환 & 서브샘플링

     

    우선, 각 픽셀의 RGB 데이터를 YCbCr이라는 다른 색공간 데이터로 변환합니다.
    Y는 밝기, Cb는 파랑에 대한 색차성분, Cr은 빨강에 대한 색차성분을 뜻합니다.

    사람의 눈은 색상 성분보다 휘도 성분에 더 민감하다고 합니다.
    전체적인 이미지를 인지하는 과정에서는 명암이 중요하기 때문에, 명암만 맞춰주면 색이 살짝 바래도 사람은 잘 모른다는 거죠.

    출처: Compress-Or-die

     


    그래서 사람이 민감하게 반응하는 밝기 정보(Y)는 냅두고 색차(Cb, Cr) 정보를 줄여 압축하는 것을 서브샘플링이라 합니다.

    색차(Chrominance)는 줄여서 크로마라고 부르기 때문에 크로마 서브샘플링이라고도 하며, 다운샘플링이라 불리기도 합니다.

     

     


    아래는 서브샘플링 비율을 똑같이 50%로 적용했을 때,
    Y구성 요소(Luminance)가 이미지 품질에 가장 큰 영향을 주는 것을 알 수 있습니다.

    출처: Unraveling the JPEG

     

     

    이때 색차 정보를 어떤 비율로 버리느냐에 따라 4:4:4, 4:2:1, 4:2:0 등으로 방식이 나뉩니다.
    JPEG의 서브샘플링은 보통 4:2:0 방식을 사용한다고 해요.

     

    우선 4개씩 2줄로 묶어 8개짜리 픽셀 블럭을 범위로 잡습니다.

    첫번째 행에서 2개의 크로마만 살려주고 두번째 행에선 0개의 크로마를 살려줍니다. (=4:2:0)
    그리고 다음 범위에서도 두 녀석만 살리고 나머지 여섯은 버린 뒤.... (하략)
    이렇게 색 정보가 버려지면서 픽셀의 용량은 전보다 줄어들게 되겠죠. 

     

     

    8개 픽셀 블럭 중 딱 두 녀석(●)만 살려줍니다

     

     

    포토샵에서 이미지 압축 시 크로마 샘플링 적용


    포토샵에서는 품질 설정에 따라 크로마 서브샘플링을 실행합니다.
    '웹용으로 저장시' 이미지 품질이 51이하라면 4:2:0 서브샘플링이 사용되면서 용량이 작아집니다. ('다른 이름으로 저장'은 품질이 6 이하일 때)

     

     




    2) DCT & 양자화


    이것 역시 눈 속이기 기법(?)으로, 사람의 눈이 고주파의 명도 변화에 둔감하다는 점을 이용합니다.

     

     

    우선 이미지를 8*8 크기의 픽셀 블럭 단위로 나눈 다음 DCT(이산코사인변환)을 합니다.
    DCT는 공간 영역(spatial domain)에서 주파수 영역(Frequency domain)으로 바꾸는 과정을 말합니다.
    공간 영역은 우리가 알기 쉬운 픽셀 값으로 이루어진 거고, 주파수 영역은 픽셀이 아닌 계수로 표현되는 영역....이라고 하는데요.... (‘◉⌓◉’)ㄴ..네?

     

     


    예를 들어 0부터 3까지 [0, 1, 2, 0, 3, 1, 1, 2, 0] 으로 정렬되지 않은 값 목록이 있다고 생각해 봅시다.
    DCT를 하면 이 목록을 정돈하면서 동시에 각 숫자가 "얼마나 빈번한지" 카운트 합니다.
    따라서 저 값은 [3, 3, 2, 1]로 변환됩니다. 공간 정보는 잃어버렸지만 주파수 정보를 알게 된 거죠.

     


    이런 식으로 8*8 크기의 픽셀 블럭은 DCT를 통해 주파수값들을 갖는 테이블로 바뀝니다.

     

    출처: Wikipedia


    그러면 위의 이미지처럼 64개의 DCT 계수가 촤르륵 모이게 됩니다.
    정돈되면서 왼쪽 상단에는 큰 숫자가 오른쪽 하단에는 작은 숫자가 위치하게 될 텐데요, 큰 숫자는 DC계수라고 하고 나머지 63개는 AC 계수라고 부릅니다.
    이렇게 정리를 한 이유는 에너지가 큰 영역(왼쪽 상단)은 살리고, 에너지에 별 영향 없는 영역(오른쪽 하단)은 버리는 작업을 진행하기 위함입니다.


    이 패턴을 이미지로 표현하면 아래와 같습니다.

     

    출처: Compress-Or-die


    왼쪽 상단 모서리의 값은 블록 모양에 가장 큰 영향을 줍니다. 왼쪽 상단에서 오른쪽 하단으로 갈 수록 패턴이 겹치면서 이미지가 점점 더 세밀해져요.
    여기서 오른쪽 아래에 가까운 패턴들을 버리는 작업, 곧 양자화를 합니다.

     

     

     

     

    출처: Wikipedia


    이렇게 이미지를 아~주 가까이서 들여다보면 압축된 8*8 픽셀 블럭이 보여요!

    이때 왼쪽 상단은 저주파(Low Frequency), 오른쪽 하단은 고주파(High Frequency)라고 합니다.
    아까부터 주파수 얘기가 나왔는데 고주파...? 저주파......?

    주파수(Frequency)라는 건 ‘신호가 얼마나 자주 변화하는가’입니다.
    이미지에서 저(Low)주파는 주변영역과 색 차이가 적은 부분입니다. #111111과 #111112 정도의 차이죠. 주로 내부 영역이 됩니다.
    반대로 고(High)주파는 주변과 색 차이가 큰 부분입니다. #fff와 #000 같이 신호가 확확 바뀌는 것이며, 주로 모서리 부분이 됩니다.

     

     

    출처: unsplash

     

    위 이미지에서 파란색은 저주파, 빨간색은 고주파 부분을 가리킵니다.

    사람은 고주파 성분의 명도 변화를 잘 눈치채지 못하므로 이것들을 슬금슬금 내다버리는 양자화 작업을 진행합니다.
    그래서 용량은 줄었지만 우리의 눈은 뭐가 달라졌는지 잘 알지 못하는 거죠.


    문득 궁금한 거 하나! 왼쪽 상단에 저주파가 많이 모이게 되는 걸까요?
    사진의 경우는 보통 인접한 픽셀의 색상이 비슷할 확률이 높습니다.
    하늘을 찍은 사진이라면 [파랑 - 파랑 - 옅은 파랑 - 옅은 파랑] 이런 식으로 비슷한 색의 픽셀이 모여 있겠죠.
    그래서 64개의 픽셀 중 같은 색이 DC 계수로 모이고 색 변화가 있는 경우 AC 계수로 모이게 됩니다.
    따라서 사진은 저주파 성분이 많은 이미지라 할 수 있습니다.

    반면, 흰 바탕에 검은 글자가 쓰인 이미지라면요?
    색상값이 자연스레 이어지지 않고, 0이었다가 갑자기 255로 바뀌게 되죠. 즉, 인위적인 이미지는 고주파 성분이 많습니다.


     

     

    이게 바로 문자, 선, 세밀한 격자가 있는 이미지를 JPEG로 저장하지 않는 것이 좋은 이유입니다.
    JPEG는 고주파를 훠이 날려보낼 텐데 고주파 성분이 대다수인 이미지를 JPEG로 저장한다면 큰일이겠죠.
    아까 이미지를 확대했을 때 JPEG가 지저분했던 이유는 바로 이 때문이었습니다.

     

    (혹시 영상 전문가가 계신다면 댓글로 모시겠습니다 🎤 맞지 않는 내용이나 더 좋은 표현 등이 있으면 말씀해 주세요)

     

     

     


    3) 지그재그 스캐닝 & 부호화

    이후 엔트로피 코딩(부호화) 작업을 거칩니다.
    양자화된 계수를 지그재그로 훑어 일렬로 줄 세우고, 런 렝스 코딩과 허프만 코딩을 한다고 합니다. 반복되는 내용을 압축시켜 마지막까지 용량을 꽉 짜내는 작업이라고 볼 수 있겠네요!

    *부호화: 인코딩. 정보의 형태나 형식을 보안, 속도, 공간 절약 등의 문제로 다른 형태나 형식으로 변환하는 것

     

     


    JPEG 압축에 대한 자세한 내용은 아래의 멋진 글들이 상세히 설명하고 있으니 참고하시면 좋겠습니다!

    [참고]

     


     

    휴, 길었네요!

     

    아무튼 우리에게 중요한 내용은 ‘고주파 성분이 많은 이미지를 JPEG로 저장하면 화질이 저하되기 쉽다’는 사실입니다.
    달리 말하면 'JPEG 압축 알고리즘은 색상이 매끄럽게 변화하는 사진과 그림에 적합하다'는 것입니다.

     

     

    이제 PNG에 대해 알아보고 비교해 볼 차례인데요,

    요 내용은 다음 글에서 이어집니다 👾

     

    이 시리즈의 다음 글: JPEG vs. PNG: 적절한 이미지 포맷 선택하기 (2) - PNG편

     

     

    728x90

    댓글