PNG, JPEG 또는 GIF 중 어떤 이미지 형식이 메모리 효율이 더 좋습니까?


답변:


153

"메모리"와 "효율"은 일반적으로 잘못 사용되는 용어이므로 게임 성능에 영향을 줄 수있는 4 가지 요소에 대한 답변을 드리겠습니다.

나는 간결하고 간결하게하기에는 너무 많은 것들을 지나치게 단순화 할 것이지만,이 본문에 부정확 한 부분이 많으므로 소금 한 덩어리로 가져 가십시오. 그러나 주요 개념은 이해할 수 있어야합니다.

저장

소프트웨어 배포에 이미지가 사용하는 크기입니다. 리소스를 많이 사용하면 웹 사이트에서와 같이 다운로드 시간이 길어집니다 . CD 또는 DVD와 같은 실제 미디어에 배포하는 경우이 부분에서 심각한 최적화를 수행해야 할 것입니다.

일반적으로 JPEG는 경계가 뚜렷하지 않은 사진 및 이미지에 가장 적합합니다. 그러나 JPEG는 손실 압축을 사용하기 때문에 이미지 품질이 저하됩니다 (이미지를 JPEG로 내보낼 때 압축 레벨 / 분해를 미세 조정할 수 있습니다. 자세한 내용은 이미징 소프트웨어 설명서를 참조하십시오).

그러나 JPEG만큼 좋은 것은 투명도를 지원하지 않습니다 . 다른 사람을 통해 보여지는 이미지를 원하거나 모양이 불규칙한 이미지를 원할 경우에 중요합니다. GIF는 좋은 선택이지만 PNG로 대체되었습니다. PNG가 지원하지 않는 GIF는 GIF에 불과하지만 게임 프로그래밍과는 크게 관련이 없습니다.

PNG는 투명도 (반투명도)를 지원하고 품질 저하없이 데이터를 압축하며 (즉, 무손실 압축 사용) JPG만큼 압축되지는 않지만 상당히 잘 압축합니다.

투명성뿐만 아니라 좋은 압축이 필요할 때 문제가 발생합니다. 당신이 약간 저하 된 이미지를 괜찮다면, 당신은 같은 PNG 양자화 프로그램을 사용할 수 있습니다 pngquant 당신이 온라인으로 테스트 할 수 있습니다, TinyPNG을 . 자체적으로 양자화에 의해 수행되는 이미지 열화는 JPEG (양자화 및 기타 공격적인 기술 포함)와는 다르므로 다양한 설정으로 두 가지를 모두 시도하십시오.

배포 크기를 적극적으로 최소화하려면 다음과 같이 모든 이미지를 수동으로 처리 할 수 ​​있습니다.

if the image has transparency then
    try pngquant on the image
    if the results are not satisfactory then
        revert to the non-quantized image
    end
    store as PNG
else
    try storing it as JPG with different quality settings
    if no single setting yields an image of an acceptable quality then
        try pngquant on the image
        if the results are not satisfactory then
            revert to the non-quantized image
        end
        store as PNG
    else
        store as JPG
    end
end

팁 : 일부 이미지는 한 형식으로 저장하고 다른 이미지는 다른 형식으로 저장해도됩니다.

DXT, ETC 및 PVRTC와 같은 다른 특수 형식이 있습니다. 압축을 지원하고 메모리로 압축하여로드 할 수 있지만 특정 GPU에서만 지원되며 대부분의 GPU는 그 중 하나만 지원하므로 대상 하드웨어의 정확한 하드웨어 사양을 모르는 경우 PVRTC 텍스처를 지원하는 iPhone / iPad)는 이러한 형식을 피해야합니다.

프로그램 메모리

여기에는 "메모리"로 알려진 것이기 때문에 여기에 포함 시켰습니다. 그러나 게임에서 그래픽 가속을 사용하는 경우 (1998 년 이후에 게임을 만드는 경우), 메모리를 소비하는 유일한 것은 텍스처 설명자 (이미지 당 몇 바이트)뿐입니다. 크기 나 형식이 아닌 이미지 의 에 영향을받습니다 (몇 가지주의 사항이 있지만 대부분 관련이 없음).

플랫폼에 전용 비디오 메모리가 없거나 하드웨어 가속 또는 기타 드문 경우 인 경우 VRAM에 대한 다음 섹션은 RAM에서 완전히 또는 부분적으로 발생하지만 기본 원칙은 동일합니다.

비디오 메모리

프로그램이 실행되면 이미지가 저장됩니다. 일반적으로 이미지를 비디오 메모리에로드하기 전에 모든 이미지의 압축이 풀리므로 이미지를 저장 한 형식은 여기에 아무런 차이가 없습니다.

이제 이미지에서 소비되는 VRAM은 대략 VRAM에로드 된 width * height * bitdepth 이미지에 대한 것 입니다. 여기에 주목해야 할 몇 가지가 있습니다.

  1. 이미지가 VRAM에 저장되는 너비와 높이는 반드시 원본 이미지의 너비와 높이와 일치하지는 않습니다. 일부 GPU는 2의 거듭 제곱 크기의 텍스처 만 처리 할 수 ​​있으므로 320x240 이미지가 실제로 VRAM의 512x256 공간에 저장되어 사용되지 않은 메모리가 효과적으로 낭비 될 수 있습니다. 때로는 GLES 1.1과 같이 2의 거듭 제곱이 아닌 크기의 텍스처도로드 할 수 없습니다.

    따라서 VRAM 사용을 최소화하려면 이미지를 아틀라스로 설정 하고 2의 거듭 제곱으로 크기를 조정하면 렌더링시 렌더링 상태 변경이 적다는 이점이 있습니다. 이것에 대해서는 나중에 더 설명하겠습니다.

  2. 깊이는 매우 중요합니다. 일반적으로 텍스처는 32 비트 ARGB 또는 32 비트 XRGB로 VRAM에로드되지만 하드웨어가 16 비트 심도를 지원할 수 있고 비트 심도가 낮은 경우 각 이미지에서 소비하는 VRAM의 절반을 줄일 수 있습니다 고려할만한 흥미로운 내용이 될 수 있습니다.

  3. 그러나 무엇을 하든지 게임에서 사용하는 VRAM의 양을 고려할 때 가장 중요한 요소 는 주어진 시간에 VRAM에있는 이미지양입니다 . 성능이 좋은 게임을 원할 경우 최대한 낮게 유지하려는 숫자입니다. 텍스처를 VRAM으로로드 및 언로드하는 것은 비용이 많이 들기 때문에 사용할 때마다 각 이미지를로드 할 수는 없습니다. 가장 많이 사용하는 이미지를 미리로드하고 더 이상 사용하지 않을 것이라고 확신 할 때 이미지를 언로드해야합니다. 이 권리를 얻는 것은 사소한 것이 아니며 특정 게임에 대한 자신의 전략을 생각해야합니다.

실행 속도

"메모리"는 아니지만 게임 성능과 관련이 있습니다. 이미지를 그리기에는 비용이 많이 들고 렌더링을 최대한 빨리 실행하려고합니다. 물론 여기서는 형식이 중요하지 않지만 다른 것은 중요합니다.

  1. 이미지 크기 (실제로 "샘플링 크기") : 그릴 이미지의 가장 큰 영역 일수록 이미지를 그리는 데 더 많은 시간이 걸립니다. 화면의 작은 부분에 큰 이미지를 렌더링하는 것은 그리 효과적이지 않으므로 밉 매핑 이라는 기술이 있습니다.이 기법 은 렌더링 속도를 위해 VRAM을 거래하고 여러 해상도로 이미지를 여러 번 저장하고 줄 수있는 가장 작은 이미지를 사용하여 당신은 주어진 시간에 필요한 품질. 밉 매핑은 이미지가로드 될 때 수행 될 수 있으며, 이는 로딩 속도 및 VRAM 사용에 영향을 미치거나 전처리 (동일한 이미지의 다른 버전을 수동으로 저장하거나 DDS와 같은 밉 매핑을 기본적으로 지원하는 형식을 사용하여)하여 저장에 영향을 미칩니다. 및 VRAM 사용량이지만로드 속도에는 거의 영향을 미치지 않습니다.

  2. 렌더링 상태 변경 화면에 여러 개의 다른 이미지를 동시에 그리는 것이 좋습니다. 그러나 GPU는 주어진 시간에 단일 소스 이미지 만 사용할 수 있습니다 (사실은 아니지만 여기 나와 함께 참아주세요). 렌더링에 현재 사용되는 이미지는 많은 렌더링 상태 중 하나 이며 비용이 많이 듭니다. 따라서 동일한 이미지를 여러 번 사용하려는 경우 ( 텍스처 아틀라스를 언급했을 때를 기억 하십니까?) 렌더링 상태를 변경하고 다양한 이미지

그러나 이미지 사용 최적화는 매우 복잡한 주제이며 여기에 쓴 것은 게임을 작성할 때 고려해야 할 몇 가지 요소에 대한 매우 광범위하고 지나치게 단순화 된 개요이므로 간단하게 유지하는 것이 가장 좋습니다. 실제로 필요할 때만 최적화하십시오. 대부분의 경우 조기 최적화는 불필요하며 때로는 해 롭기도합니다.


25
+1. 이것은 엄청나게 많은 근거를 다루는 매우 포괄적 인 답변입니다. 텍스처 디스크립터의 크기에 필요한만큼의 공간이 필요하다는 것을 확신하지 못하며 DXT / ETC / PVRTC 언급에는 각 플랫폼이 일부 플랫폼에서만 작동한다는 사실이 포함되어야합니다. JPEG, PNG 및 GIF와 같은 방식으로 어디에서나 사용할 수있는 표준. 그러나 전반적으로 매우 감동했습니다. 이것은 내 답변 위에 "사소한 주석"그 이상입니다! : D
트레버 파월

9
@ 판다 파자마 : 어쩌면 그렇지는 않지만이 질문에 비해 놀랍도록 더 나은 대답입니다.
Marcks Thomas

1
가능하면 +1 이상. 이것은 훌륭한 답변이며, "메모리 효율성"에 대한 모든 질문에 대한 표준 참조 지점이되어야합니다. 메모리를 적게 사용하는 것이 이미지뿐만 아니라 항상 최선의 접근 방식이라는 일반적인 신화를 효과적으로 폐기합니다. 내가 추가 할 것을 제안하는 한 가지 항목은 가속되지 않은 경우에 그릴 때 즉시 압축 풀기가 필요한 경우 허용 할 수없는 성능 오버 헤드가 발생할 수 있다는 것입니다.
Maximus Minimus

2
PNGGauntlet 을 제안하고 싶습니다 . PNG 파일 크기에 대해 무손실 최적화를 수행 할 수 있으며 특히 스프라이트가 많은 경우 더해질 수 있습니다. 슬프게도 Windows 전용이지만 대안은 다른 OS의 홈페이지에 나열되어 있습니다.
orlp

1
@DavidDimalanta 나는 libgdx에 대한 경험이 없지만의 문서에서 볼 수 있듯이 setEnforcePotImagesOpenGLES 1.0에 대해 2 크기 텍스처의 힘을 적용하지 않습니다. 모든 하드웨어가 2의 제곱이 아닌 텍스처를 지원하는 것은 아니기 때문에 이것은 좋은 생각이 아닙니다. OpenGLES 2.0은 2의 제곱이 아닌 텍스처를 지원해야하므로 2.0을 대상으로하는 경우 모든 크기의 텍스처를 사용할 수 있습니다. 자세한 내용은 libgdx 설명서를 참조하십시오.
Panda Pajama

26

이미지가 디스크에로드되고 렌더링 용으로 포맷되면 PNG, JPEG 또는 GIF를 사용하여 이미지를 디스크에 저장했는지 여부에 관계없이 동일한 양의 메모리를 사용합니다.

일반적인 경험 법칙 : JPEG는 손실이 많은 형식이며 디스크에서 이미지를 작게 만들기 위해 이미지 품질을 떨어 뜨립니다. 반면 PNG는 무손실 이미지 형식이므로 일반적으로 디스크에서 파일 크기가 더 커집니다. GIF는 기술적으로 무손실 형식이지만 이미지 당 최대 256 색만 지원하므로 GIF로 저장하면 높은 색상의 이미지로 인해 품질이 크게 떨어질 수 있습니다.

그러나 그것은 디스크상의 표현만을위한 것입니다. 메모리에서는 디스크에 PNG, JPEG 또는 GIF로 저장했는지 여부에 관계없이 동일한 양의 메모리를 사용하여 동일한 텍스처 형식으로 확장됩니다.


따라서 메모리 크기가 아닌 파일 크기가 아닌 파일 크기입니까?
Tredecies Nocturne

둘 다. 메모리의 크기는 이미지 크기와 비트 깊이를 기반으로합니다. 이미지가 화면에 그려 지도록 메모리에로드되면 이미지 파일의 압축이 제거됩니다. (GPU는 PNG 나 JPEG 등을 렌더링 할 수 없기 때문에 이미지는 일반 픽스맵으로 확장되어 GPU가 처리 할 수 ​​있습니다.)
Trevor Powell

2
이것은 100 % 사실이 아닙니다. 임베디드 GPU를 포함한 대부분의 최신 GPU는 임베디드 메모리에서 DXT, ETC 및 PVRTC와 같은 형식이 그래픽 메모리에 압축 된 텍스처로드 및 저장을 지원합니다. 물론 PNG / JPG / GIF 대신 이러한 형식으로 텍스처를 먼저 저장해야합니다.
Panda Pajama

6
문제는 PNG / JPG / GIF 사이의 명확한 선택이었습니다.이 중 어느 것도 내가 아는 GPU에서 기본적으로 지원되지 않습니다. 원래의 asker는 디스크의 파일 크기와 RAM에서 차지하는 공간을 구별하는 데 충분한 문제가 있었기 때문에 더 많은 파일 형식을 추가하면 근본적인 문제를 혼란스럽게한다고 생각했습니다. 그래도 자신의 답변을 자유롭게 제공하십시오.
트레버 파월

2
내 의견은 단지 주석입니다. 내가 답을 제공한다면, 나는 당신과 똑같은 글을 썼을 것입니다. 추가 할 것이 없으므로 자체 답변을 제공하여 반복을 피할 수 있습니다.
Panda Pajama

3

따라 다릅니다.

Jpeg는 사진에 가장 효율적입니다. 무손실은 아니지만 압축에 의해 도입 된 아티팩트는이 사용 사례에서 가장 잘 보이지 않습니다.

PNG는 손실이없고 선이 선명하고 색상이 적은 픽셀 아트에 가장 효율적입니다. 또한 알파 투명도를 지원합니다.

GIF는 애니메이션을 저장할 수있는 능력을 제외하고 PNG가 더 이상 할 수없는 일을 할 수 없습니다. 그러나 이것은 웹 응용 프로그램의 맥락에서만 관련이 있습니다. 게임 개발에서는 일반적으로 스프라이트 시트를 사용하여 애니메이션을 만듭니다.

Libgdx와 같은 그래픽 엔진을 사용하는 경우 이미지를로드 한 직후 이미지를 압축 해제 한 다음 메모리에 압축되지 않은 RGBA 값으로 유지합니다. 따라서 이미지 형식은 로딩 속도에만 중요하며 드라이브 공간 (또는 네트워크를 통해 전송할 때 대역폭 사용량)이 있습니다.


2

libgdx에 대해서는 잘 모르지만 이미지 형식과 그래픽에 대해서는 잘 모르겠습니다.

실제 사진의 경우 JPEG가 매우 좋습니다. 그것들은 손실이 있지만 글씨 나 만화와 같이 평평한 색 공간으로 선명한 가장자리 사진을 찍지 않으면 사진에 아티팩트가 표시되지 않습니다. 큰 배경 그래픽에 사용하십시오.

GIF는 더 이상 사용되지 않으며 완전한 투명성을 위해 하나의 전용 색상으로 팔레트 색상 (픽셀 당 최대 8 비트) 만 저장할 수 있습니다. 프레임을 기반으로 작은 애니메이션을 허용합니다. 일단 포장 알고리즘에 대한 특허가 있었으므로 법적으로 어디에서나 사용할 수 없었습니다. 그 특허 때문에 PNG가 개발되었습니다.

PNG는 RGB + 알파 (최대 32 비트) 및 기타 픽셀 형식을 저장할 수있는 압축 된 비트 맵입니다. 이 그림의 작은 부분을 고속 압축 해제하는 데 특화되어 있으며 10 년 된 휴대폰과 같이 매우 작고 느린 장치에는 편리하지만 오늘날 라이브러리는로드 될 때 비트 맵으로 압축을 풉니 다.

PNG는 크기와 속도 및 기능면에서 GIF보다 낫지 만 비트 맵을 효율적으로 저장하려면 다음과 같이 제안합니다. .PNM.BZ2 ([편집] 다른 패킹 방법으로 인해 .PNM.BZ2가 항상 더 효율적인 것은 아닙니다 .PNG보다. [/ edit])

PNM / PBM / PGM / PAM 은 일반 텍스트로 KISS 헤더가있는 일반 비트 맵 형식입니다. 이것에 gzip을 사용하면 PNG와 비슷한 파일 크기가 생성되므로 bzip2가 더 나은 솔루션입니다. 프로그램에서 내부적으로 비트 맵을 사용하려는 경우 .tar 또는 .zip 컨테이너에서 bzip2 압축 비트 맵을 사용할 수 있습니다. bzip2가없는 경우 zip 컨테이너 (PNG 최대 압축)에서 PNM을 사용하는 것은 PNG를 사용하는 것과 유사 할 수 있습니다. – 따라서 ZIP 파일에 PNG를 저장하면 이점이 적거나 전혀 없을 수 있습니다. 이미지를로드하는 시간이 늘어날 가능성이 높습니다.

그 외에도 여러 개의 작은 스프라이트 / 사진을 하나의 비트 맵에 저장하는 것이 좋습니다. 특히 같은 상황에서 모두 필요로하는 경우에 특히 그렇습니다.


모든 스마트 폰 OS 및 데스크톱 컴퓨터 OS에서 PNM 파일을 사용할 수 있습니까?
David Dimalanta

1
@David Dimalanta : 지원되는 곳과 지원되지 않는 곳을 모르겠습니다. PNM을 사용하여 프로그래밍하려는 경우 라이브러리를 사용하는 경우가 거의 없습니다. 형식이 너무 단순하여 API를 선택할 수 없기 때문입니다. 이로 인해 이진 파일 읽기 / 쓰기를 지원하는 기존의 모든 프로그래밍 언어로 읽고 쓸 수 있습니다. 물론 유닉스뿐만 아니라 모든 OS에서 Netpbm을 사용할 수 있습니다. 반면에, 어떤 일반 이미지 라이브러리가 이것을 지원하지 않는지 모르겠습니다. 압축 된 형식이 아니므로 이미지를 디스크에 저장하는 데 거의 사용되지 않습니다. en.wikipedia.org/wiki/Netpbm_format
comonad

1

저장 형식으로서 JPEG는 아마도 정보 손실이 감지되지 않는 잔디 나 벽과 같은 일부 텍스처에 가장 적합한 선택 일 것입니다. 투명성이 필요하거나 2D 게임의 스프라이트 (플레이어, 적, 재무부 상자)와 같은 정보 손실로 지불 할 수없는 경우 PNG가 뒤 따르는 경우 해당 이미지에 PNG를 사용할 수 있습니다.

메모리 비용에 관해 이야기 할 때 파일 시스템에 게임 그래픽을 저장하는 데 사용되는 형식은 전혀 관련이 없습니다. 픽셀 버퍼를 VRAM 또는 RAM (소프트웨어 렌더러)에 저장하는 경우 게임은 각 픽셀 버퍼에서 사용하는 메모리와 메모리의 빠른 읽기를 선호하기 때문에 압축되지 않은 상태로 저장했을 수 있습니다.

디스크 읽기를 저장하기 위해 어떤 종류의 캐시를 유지하는 것을 제외하고 메모리에 저장된 압축 된 데이터는 의미가 없지만 게임에서 주어진 시간에 사용중인 이미지에 대해 해당 캐시에서 압축되지 않은 상태로 읽어야합니다.

압축 된 이미지 데이터는 빠른 하드웨어 디코딩이 가능하다면 좀 더 의미가 있습니다. 정상적인 매핑의 경우 적어도 http://en.wikipedia.org/wiki/3Dc 기억합니다 . 이를 통해 VRAM을 절약 할 수 있습니다. 하드웨어 디코딩의 다른 예를 아직 알지 못합니다.

이력서 : 게임에서 영구 저장 장치에 그래픽을 저장하는 데 사용 된 형식에 관계없이 필요에 따라 빠르게 렌더링하려면 동적 메모리, 비디오 메모리 또는 둘 다에서 압축되지 않은 버전을 유지해야합니다.

마지막으로 저는 데스크탑 사람입니다. "메모리"라고 말하면 항상 동적 메모리를 말합니다. "디스크", "파일 시스템"또는 "영구 저장소"라고 말하면 항상 장치가 영구 저장소로 사용하는 모든 것을 가리 킵니다. 일반적으로 하드 디스크라고 생각합니다. "메모리 효율성"이라고 말했을 때 나는 "지속적인 저장"이 아닌 "동적 메모리"를 사용했다. 최근에 많은 사람들이 "메모리"라는 단어를 사용하여 "영구 저장 장치"(휴대 장치의 용어 일 수 있음)를 나타냅니다.


JPEG 또는 PNG가 메모리에 영향을 미치지 않고 파일 크기에 영향을 줄 수도 있습니까?
Tredecies Nocturne

예. 디스크 공간이나 대역폭 절약을 위해 논의 된 형식 중 하나를 선택합니다. 게임에 이미지를로드 할 때 내가 아는 라이브러리 / 엔진은 압축되지 않은 픽셀 버퍼로 디코딩합니다 (픽셀 버퍼는 RGB 또는 RGBA 값의 배열로 생각합니다. 각 채널은 일반적으로 32 비트를 사용하는 경우 RAM / VRAM에서 1 바이트를 차지합니다 픽셀, 아마도 모든 사람이하는 일입니다).
Hatoru Hansou
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.