Lepton sıkıştırmasını önleyin


17

Dropbox kısa süre önce JPEG görüntülerini gidiş- dönüşte kayıpsız bir şekilde sıkıştıran ve ortalama% 22 tasarruf sağlayan bir yöntem olan Lepton'u ( GitHub ) piyasaya sürdü .

Güvercin deliği prensibi nedeniyle , herhangi bir genel sıkıştırma algoritması daha küçük bir dosyaya neden garanti edilemez ( genel , belirli bir formatla kısıtlanmış girişler için geçerli değildir). Lepton, JPEG'lerle ilgili ortak özelliklerden yararlanır; bu, altta bırakılırsa, kaynaktan daha büyük bir dosya oluşturmak için güvercin deliğine neden olabilir.

Gereksinimler

Üreten bir program yazın:

  • Geçerli bir JPEG / JFIF görüntüsü,
  • 0,5 MB ile 1 MB arasında bir boyuta sahip,
  • 256 × 256 pikselden daha küçük değil,
  • en fazla 4096 × 4096 piksel,
  • Lepton tarafından tanınabilir (başarılı bir şekilde "sıkıştırabilir" .lep görüntüye ) ve
  • Bir için açar özdeş .jpg (giriş olarak) .
  • APPx, COM ve diğer meta verilerde, grafiksel olmayan işaretleyici bölümleri JPEG'de sınırlandırılmıştır (asimtotik olarak 1: 1 sıkıştırma yaklaşması için görüntüye rastgele miktarda rastgele bayt enjekte edilir.)
    • Bir APP0JFıF markör izin verilir ancak küçük (tam olarak 16 bayt olmalıdır) bırakılır
    • tl; dr Meta verileri bir EXIF ​​segmentine kasıtlı olarak sokmuyorsanız ve tercih ettiğiniz dil kitaplığınızın resme koymak istediği herhangi bir küçük resmi devre dışı bırakırsanız, bu tamam olmalıdır.

Kodu ve resmi yayınlayın.

Dönüştürüldüğünde kriterleri karşılayan bir JPEG veren bir Lepton görüntüsü üreten bir program yazmak istiyorsanız , sorun değil. Rastgele birçok JPEG → Lepton → JPEG → ... döngüsünde aynı kalmalıdır.

puanlama

Lepton görüntüsünün bayt boyutunun kaynak JPEG görüntüsüne bölümü. Daha yüksek (daha kötü Lepton sıkıştırması) daha iyidir. Lepton'u varsayılan bayraklar ve anahtarlarla çalıştırın.


Lepton Başlarken

Lepton'u inşa etmek için 5 saniyelik bir çarpışma rotası:

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

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

O zaman ./lepton --helpsize bir şeyler söylemeliyiz.


Bu en azından bazı sabit tarafından sıkıştırma başarısız bir görüntü üreten kodu yazdığınız bir kod golf meydan okuma için retooled düşünüyorum. Aslında, sadece jpeg'i kodlamak için boyuttan çok daha küçük olan, ancak makul bir program için yeterince büyük olan kod boyutuna bir üst sınır koymak yeterli olabilir.
xnor

3
Düzgün rasgele piksellerin en iyi yanıt olmasını beklemek için herhangi bir neden var mı?
feersum

@feersum tıpkı benim örneğim gibi mi demek istiyorsun?
Nick T

1
Ayrıca, JPEG kayıplı bir format olduğundan, belirli bir görüntüyü sıkıştırmanın birçok, çok yolu vardır (örneğin, diğer şeyler arasında "kalite"). Her JPEG dosyası, görüntünün geri kalanının kodunun nasıl çözüldüğünü belirleyen birkaç tablo içerir ve bu tablolar temelde ne olursa olsun olabilir. Bir BMP görüntüsünü farklı programlara kaydederseniz, muhtemelen aynı olacaktır. Bir JPG'yi aynı arka uç kütüphanesini kullanmadıkları sürece farklı programlara kaydederseniz, muhtemelen değil.
Nick T

2
@feersum bir JPEG kompresörüne tekdüze rastgele giriş, tekdüze rastgele çıktı ile sonuçlanmaz ve bu çıktı lepton üzerinde çalışır. Bir JPEG kompresörün eşit olarak rasgele çıktı üretmesine neden olan bir giriş bulabilirseniz, bu muhtemelen burada ve başka yerlerde faydalı olacaktır.
Sparr

Yanıtlar:


4

Python 3 + mozjpeg + / dev / urandom, 720 × 720: ort. puan 102%

Bağlıdır mozjpeg, paketin kod içine yüklü varsayar /usr/local/opt/mozjpeg. (OS X'te kurulumu önemsizdir, sadece çalıştırın brew install mozjpeg)

Ayrıca /dev/urandomözel dosyaya bağlıdır, rastgele veri oluşturmak için kullanılır.

Kod sadece rasgele verileri mozjpegkompresöre besler (cjpeg bunu anladığı ve çok basit bir başlığı olduğu için TGA formatında) ve optimize edilmiş bir jpeg dosyası oluşturmasına izin verir. Kalite maksimuma ayarlanmıştır çünkü DCT katsayılarını en az sıkıştırılabilir yapar ve sıkıştırılamaz verileri sıkıştırmak için hangi algoritmanın kullanıldığı önemli değildir.

Jpeg-> lepton-> jpeg döngüsünün kayıpsız olduğunu kontrol ettim - bu doğru.

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()

Açıkçası kod golf değil.

Örnek resim:

Eğlenceli gerçek: JPEG kayıplı sıkıştırma kullansa bile, oluşturulan JPEG dosyası kaynak sıkıştırılmamış TGA görüntüsünden daha büyük.

Eğlenceli gerçek 2: Imgur (SO için barındırma varsayılan görüntüsü) bu dosyada çok kötü bir iş çıkarıyor - bir nedenden dolayı 1MB'den daha az olsa bile daha düşük kaliteye yeniden sıkıştırıyor. Bu yüzden örnek görüntüyü yüklemek için Github kullandım.

Eğlenceli gerçek 3: Genel olarak, mozjpeg gerçekten mevcut JPEG kod çözücülerle uyumlu kalırken daha iyi JPEG sıkıştırması yapar. Ayrıca JPEG dosyalarını da kayıpsız bir şekilde optimize etmek için bir araç var - jpegtran.


Bir platformlar arası RNG (örneğin SystemRandom sınıfı) kullanabilirdim ama çok tembeltim. Önemsizdir ve benzer sonuçlar vermelidir.
Görünen Ad

1

Saf Gürültü, 1024 × 1024: puan 85.55%

Topu yuvarlamak için Python'da uyumlu bir örnek. Hiçbir şekilde optimize edilmemiştir; olası eksiklikler:

  • Varsayılan kalite ayarının ne olduğu hakkında hiçbir fikrim yok.
  • Her 8x8 bloğu, hemen hemen bitişik değerle aynı ortalama değere (~% 50) sahiptir: Lepton, bu bilgileri yer kazanmak için kullandıklarını söylüyor.
  • Tamamen varsayılan nicemleme ve Huffman tabloları (kitaplık kullanmaya ne karar verirse verin).

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')

gürültü, ses

Sonra bazı bash şeyi yapmak için:

./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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.