ขัดขวางการบีบอัด Lepton


17

Dropbox เพิ่งเปิดตัวLepton ( GitHub ) ซึ่งเป็นวิธีการบีบอัดภาพ JPEG แบบไปกลับโดยไม่สูญเสียความประหยัดโดยเฉลี่ย 22%

เนื่องจากหลักการของpigeonholeอัลกอริธึมการบีบอัดทั่วไปใด ๆจึงไม่สามารถรับประกันว่าจะส่งผลให้ไฟล์มีขนาดเล็กลง ( ทั่วไปเนื่องจากไม่ได้ใช้กับอินพุตที่ จำกัด รูปแบบเฉพาะ) Lepton หาประโยชน์จากลักษณะทั่วไปเกี่ยวกับ JPEG ซึ่งหากล้มล้างอาจทำให้ช่องว่างในการสร้างไฟล์มีขนาดใหญ่กว่าแหล่งที่มา

ความต้องการ

เขียนโปรแกรมที่สร้าง:

  • รูปภาพ JPEG / JFIF ที่ถูกต้อง
  • ขนาดระหว่าง 0.5 MB ถึง 1 MB
  • ไม่เล็กกว่า 256 × 256 พิกเซล
  • ไม่ใหญ่กว่า 4096 × 4096 พิกเซล
  • เลปตันเป็นที่รู้จัก (สามารถ "บีบอัด" .lepภาพ) และ
  • คลายการบีบอัดให้เหมือนกัน .jpg (เป็นอินพุต)
  • APPx, COMและข้อมูลเมตาอื่น ๆ ส่วนของตัวทำเครื่องหมายที่ไม่ใช่ภาพกราฟิกถูก จำกัด ใน JPEG (การฉีดจำนวนสุ่มของจำนวนไบต์แบบสุ่มลงในรูปภาพเพื่อให้วิธีการบีบอัดแบบ 1: 1 เป็นแบบไม่มีสัญญาณ)
    • APP0เครื่องหมาย JFIFจะได้รับอนุญาต แต่ไม่มีรูปขนาดย่อได้รับอนุญาต (ควรจะตรง 16 bytes)
    • tl; drหากคุณไม่ได้ตั้งใจที่จะผลักเมทาดาทาลงในกลุ่ม EXIF ​​และคุณปิดการใช้งานรูปขนาดย่อของไลบรารีภาษาที่คุณต้องการจะใส่ลงไปในภาพ

โพสต์รหัสและรูปภาพ

หากคุณต้องการเขียนโปรแกรมที่สร้างภาพLeptonซึ่งเมื่อแปลงแล้วให้ผล JPEG ที่ตรงกับเกณฑ์ก็ถือว่าใช้ได้ มันจะต้องยังคงเหมือนกันในหลาย ๆ JPEG → Lepton → JPEG → ... รอบ

เกณฑ์การให้คะแนน

ขนาดไบต์ของภาพ Lepton หารด้วยรูปภาพ JPEG ต้นฉบับ สูงกว่า (การบีบอัด Lepton ที่แย่กว่า) จะดีกว่า เรียกใช้ Lepton ด้วยการตั้งค่าสถานะและสวิตช์เริ่มต้น


รับ Lepton

5-second crash-course เพื่อสร้าง Lepton:

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

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

จากนั้น./lepton --helpควรบอกอะไรคุณ


ฉันคิดว่าสิ่งนี้สามารถนำไปใช้กับการแข่งขันกอล์ฟรหัสที่คุณเขียนรหัสที่สร้างภาพที่ล้มเหลวในการบีบอัดอย่างน้อยค่าคงที่ ที่จริงแล้วมันอาจพอเพียงที่จะใส่ขอบเขตบนขนาดรหัสที่เล็กกว่าขนาดเพื่อ hardcode jpeg แต่ใหญ่พอสำหรับโปรแกรมที่เหมาะสม
xnor

3
มีเหตุผลใดที่จะคาดหวังว่าพิกเซลสุ่มที่สม่ำเสมอไม่ได้เป็นคำตอบที่ดีที่สุด?
feersum

@feersum คุณหมายถึงเช่นเดียวกับตัวอย่างของฉัน?
Nick T

1
นอกจากนี้เนื่องจาก JPEG เป็นรูปแบบที่สูญเสียมีหลายวิธี (เช่น "คุณภาพ" เหนือสิ่งอื่นใด) เพื่อบีบอัดรูปภาพที่กำหนด ไฟล์ JPEG แต่ละไฟล์จะมีตารางสองตารางที่บอกให้รู้ว่าส่วนที่เหลือของภาพถูกถอดรหัสอย่างไรและโดยทั่วไปตารางเหล่านั้นสามารถเป็นอะไรก็ได้ หากคุณบันทึกภาพ BMP ในโปรแกรมที่แตกต่างกันมันอาจจะเหมือนกัน หากคุณบันทึก JPG ในโปรแกรมต่าง ๆ เว้นแต่ว่าพวกเขาใช้ไลบราเอนด์เดียวกันอาจไม่ใช่
Nick T

2
@feersum การป้อนข้อมูลแบบสุ่มอย่างสม่ำเสมอไปยังคอมเพรสเซอร์ JPEG ไม่ได้ส่งผลให้มีการสุ่มผลลัพธ์ที่สม่ำเสมอและเอาต์พุตนั้นเป็นสิ่งที่ lepton ใช้งานได้ หากคุณสามารถหาอินพุทที่ทำให้คอมเพรสเซอร์ JPEG สร้างเอาต์พุตสุ่มอย่างสม่ำเสมอนั่นอาจเป็นประโยชน์ที่นี่และที่อื่น ๆ
Sparr

คำตอบ:


4

Python 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 cycle นั้นไม่มีความสูญเสีย - มันเป็นความจริง

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 ที่สร้างขึ้นมีขนาดใหญ่กว่ารูปภาพ TGA ที่ไม่บีบอัดแม้ว่าในขณะที่ JPEG ใช้การบีบอัดแบบ lossy ก็ตาม

ข้อเท็จจริงที่สนุกสนาน 2: Imgur (รูปภาพเริ่มต้นที่โฮสต์ไว้สำหรับ SO) ทำงานได้ไม่ดีในไฟล์นี้ - ด้วยเหตุผลบางอย่างมันบีบอัดไฟล์ใหม่ให้มีคุณภาพต่ำลงแม้ว่าจะน้อยกว่า 1MB ดังนั้นฉันจึงใช้ Github เพื่ออัพโหลดภาพตัวอย่าง

ข้อเท็จจริงที่สนุกสนาน 3: โดยทั่วไป mozjpeg จะทำการบีบอัด JPEG ได้ดีขึ้นในขณะที่สามารถใช้งานร่วมกับตัวถอดรหัส JPEG ที่มีอยู่ได้ และก็ยังมีเครื่องมือในการเพิ่มประสิทธิภาพ losslessly ไฟล์ JPEG ด้วย jpegtran-


ฉันสามารถใช้ข้ามแพลตฟอร์ม RNG (ตัวอย่างเช่นคลาส SystemRandom) แต่ฉันขี้เกียจเกินไป มันไม่สำคัญและควรให้ผลลัพธ์ที่คล้ายกัน
ชื่อที่แสดง

1

เสียงไร้เดียงสา, 1024 × 1024: คะแนน 85.55%

ตัวอย่างที่สอดคล้องใน Python เพื่อให้ลูกบอลกลิ้ง ไม่ได้รับการปรับปรุงให้ดีที่สุด แต่อย่างใด ข้อบกพร่องน่าจะเป็น:

  • ไม่ทราบว่าการตั้งค่าคุณภาพเริ่มต้นคืออะไร
  • บล็อก 8x8 แต่ละบล็อกมีค่าเฉลี่ยที่แน่นอนเหมือนกัน (~ 50%) กับบล็อกที่อยู่ติดกัน: Lepton กล่าวว่าพวกเขาใช้ข้อมูลนั้นเพื่อประหยัดพื้นที่
  • การหาปริมาณเริ่มต้นโดยสิ้นเชิงและตาราง Huffman (สิ่งที่ไลบรารีตัดสินใจใช้)

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.