Lepton 압축 방지


17

Dropbox는 최근 JPEG 이미지 를 무손실 압축하여 평균 22 %의 비용을 절약하는 Lepton ( GitHub )을 출시했습니다 .

때문에의 비둘기 집 원리 , 어떤 일반적인 압축 알고리즘이 될 수없는 보증 (작은 파일에 결과에 일반적으로 는 특정 형식에 제약 입력에 적용되지 않기 때문에). Lepton은 JPEG에 대한 일반적인 특성을 활용하여 파괴 될 경우 소스보다 큰 파일을 생성 할 수 있습니다.

요구 사항

다음을 생성하는 프로그램을 작성하십시오.

  • 유효한 JPEG / JFIF 이미지
  • 0.5MB에서 1MB 사이의 크기로
  • 256 × 256 픽셀 이상
  • 4096 × 4096 픽셀 이하
  • Lepton에서 인식 가능 ( .lep이미지 를 성공적으로 "압축"할 수 있음 )
  • (입력 과 동일) 압축을 풉니 다 .jpg.
  • APPx, COM및 기타 메타 데이터의 비 그래픽 마커 섹션은 JPEG에서 제한됩니다 (임의로 1 : 1 압축에 접근하기 위해 임의의 양의 임의 바이트를 이미지에 주입하여 1 : 1 압축이 지연됨).
    • APP0JFIF 마커는 허용하지만 섬네일 (정확히 16 바이트이어야 함) 허용되지 않습니다
    • tl; dr 의도적으로 EXIF ​​세그먼트에 메타 데이터를 넣지 않고 선택한 언어 라이브러리가 이미지에 넣고 자하는 썸네일을 비활성화하면 괜찮습니다.

코드와 이미지를 게시하십시오.

변환 할 때 기준에 맞는 JPEG 를 생성하는 Lepton 이미지 를 생성하는 프로그램을 작성 하려면 괜찮습니다. 임의로 많은 JPEG → Lepton → JPEG → ... 사이클에서 동일하게 유지되어야합니다.

채점

Lepton 이미지의 바이트 크기를 소스 JPEG 이미지로 나눈 값입니다. 높을수록 (Lepton 압축이 나빠질수록) 좋습니다. 기본 플래그 및 스위치와 함께 Lepton을 실행하십시오.


렙턴 얻기

Lepton을 구축하는 5 초의 충돌 과정 :

git clone https://github.com/dropbox/lepton.git
cd lepton
./autogen.sh && ./configure && make

# fish shell: ./autogen.sh ;and ./configure ;and make

그런 다음 ./lepton --help말해야합니다.


나는 이것이 적어도 일정한 상수로 압축에 실패한 이미지를 생성하는 코드를 작성하는 코드 골프 도전에 retool 될 수 있다고 생각합니다. 실제로, jpeg를 하드 코딩하기위한 크기보다 훨씬 작은 코드 크기에 상한을 두는 것만으로도 충분할 수 있지만 합리적인 프로그램을 만들기에는 충분합니다.
xnor

3
균일하게 임의의 픽셀이 최선의 대답이 아니라고 예상 할만한 이유가 있습니까?
feersum

@feersum 당신은 내 예처럼 의미합니까?
Nick T

1
또한 JPEG는 손실이 많은 형식이기 때문에 주어진 이미지를 압축하는 방법에는 여러 가지가 있습니다 (예 : "품질"). 각 JPEG 파일에는 나머지 이미지가 어떻게 디코딩되는지를 나타내는 몇 개의 테이블이 포함되어 있으며 기본적으로 어떤 테이블이든 가능합니다. 다른 프로그램에 BMP 이미지를 저장하면 아마도 동일 할 것입니다. JPG를 다른 프로그램에 저장하면 동일한 백엔드 라이브러리를 사용하지 않는 한 그렇지 않을 수 있습니다.
Nick T

2
@feersum JPEG 압축기에 균일하게 무작위로 입력해도 균일하게 무작위로 출력되지 않으며, 그 출력은 lepton이 작동하는 것입니다. JPEG 컴프레서가 균일하게 임의의 출력을 생성하는 입력을 얻을 수 있다면 아마도 다른 곳에서 유용 할 것입니다.
Sparr

답변:


4

파이썬 3 + mozjpeg + / dev / urandom, 720 × 720 : 평균. 102 % 득점

에 따라 다름 mozjpeg, 패키지 코드는가에 설치되어 가정합니다 /usr/local/opt/mozjpeg. (OS X에서는 설치하기가 쉽지만 실행하십시오 brew install mozjpeg)

또한 /dev/urandom특수 파일 에 의존하며 임의의 데이터를 생성하는 데 사용됩니다.

이 코드는 임의의 데이터를 mozjpeg압축기에 TGA 형식으로 공급하고 (cjpeg가이를 이해하고 헤더가 매우 단순하기 때문에) 최적화 된 jpeg 파일을 만들 수있게합니다. DCT 계수를 압축률이 가장 낮으므로 품질이 최대로 설정되며 압축 할 수없는 데이터를 압축하는 데 사용되는 알고리즘은 중요하지 않습니다.

jpeg-> lepton-> jpeg주기가 손실이 없는지 확인했습니다. 사실입니다.

import subprocess
from subprocess import PIPE

c_mozjpeg_path = '/usr/local/opt/mozjpeg/bin/cjpeg'
cjpeg_params = '-quality 100 -dc-scan-opt 2 -dct float -targa'
image_size = 720


def write_random_tga_image(w, h, of, rf):
    def wb(value, size):
        of.write(int.to_bytes(value, size, 'little'))

    wb(0, 2)
    wb(3, 1)
    wb(0, 9)
    wb(w, 2)
    wb(h, 2)
    wb(8, 1)
    wb(0, 1)

    data_size = w * h
    while data_size > 0:
        data_size -= of.write(rf.read(data_size))


def main():
    with open('/dev/urandom', 'rb') as rf:
        with open('oops.jpg', 'wb') as f:
            p = subprocess.Popen((c_mozjpeg_path,) + tuple(cjpeg_params.split(' ')), stdin=PIPE, stdout=f)
            write_random_tga_image(image_size, image_size, p.stdin, rf)
            p.communicate()


if __name__ == '__main__':
    main()

코드는 분명 골프가 아닙니다.

이미지 예 :

재미있는 사실 : JPEG가 손실 압축을 사용하더라도 생성 된 JPEG 파일이 소스 비 압축 TGA 이미지보다 큽니다.

재미있는 사실 2 : Imgur (SO의 기본 이미지 호스팅)는이 파일에서 매우 나쁜 작업을 수행합니다. 어떤 이유로 든 1MB 미만이지만 품질이 낮은 수준으로 다시 압축됩니다. 그래서 Github을 사용하여 예제 이미지를 업로드했습니다.

재미있는 사실 3 : 일반적으로 mozjpeg는 기존 JPEG 디코더와의 호환성을 유지하면서 JPEG 압축 성능을 향상시킵니다. 또한 JPEG 파일을 무손실로 최적화하는 도구도 있습니다 jpegtran.


크로스 플랫폼 RNG (예 : SystemRandom 클래스)를 사용할 수는 있지만 너무 게으르다. 사소하고 비슷한 결과를 제공해야합니다.
표시 이름

1

순진한 소음, 1024 × 1024 : 85.55 %

볼 롤링을 얻는 파이썬의 호환 예제. 어떤 식 으로든 최적화되지 않았습니다. 가능한 단점 :

  • 기본 품질 설정이 무엇인지 모릅니다.
  • 각 8x8 블록은 실제로 인접한 블록과 동일한 평균값 (~ 50 %)을 갖습니다. Lepton은이 정보를 사용하여 공간을 절약한다고 말합니다.
  • 완전히 기본 양자화 및 허프만 테이블 (라이브러리에서 사용하기로 결정한 모든 것)

import numpy as np
from PIL import Image

np.random.seed(0) # make sure it's repeatable.

size = 1024

imgr = np.random.randint(0, 0xFF, (size, size, 3)).astype('uint8')
pimg = Image.fromarray(imgr)
pimg.save('noise.jpg')

소음

그런 다음 몇 가지 배쉬가 일을합니다.

./lepton noise.jpg noise.lep 2>\dev\null # vomits out a lot of technobabble
./lepton noise.lep noise-out.jpg 2>\dev\null

diff -qs noise.jpg noise-out.jpg

SIZE1=$(stat -f "%z" noise.jpg) # http://superuser.com/a/570920/18931
SIZE2=$(stat -f "%z" noise.lep)
RATIO=$(bc <<< "scale=4; $SIZE2/$SIZE1")
echo "$SIZE2/$SIZE1 = $RATIO"

# Files noise.jpg and noise-out.jpg are identical
# 538817/629769 = .8555
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.