2010-02-12 5 views
21

Chciałbym przesłać jpegów pod kątem ważności, zanim wyślę je przez sieć w celu dokładniejszej inspekcji. Łatwo jest sprawdzić poprawny nagłówek i stopkę, ale jaki jest najmniejszy rozmiar (w bajtach), jaki może być poprawny jpeg?Jaki jest najmniejszy poprawny rozmiar pliku jpeg (w bajtach)?

+3

libjpeg może zrobić szybkich testów, należy rozważyć użycie go zamiast zgadywać. – Tronic

+4

Nie chcę dodawać żadnych dodatkowych bibliotek do mojej aplikacji. Ponadto, nie zgaduje, czy ktoś mi odpowie właściwą odpowiedź :) – twk

+1

Powinieneś zmienić swoje pytanie, aby "sprawdzić, czy niektóre jpeg są prawdopodobnie poprawne", chyba że masz zamiar zrobić kilka innych testów, jeśli test rozmiaru pliku Karnety. W przeciwnym razie łatwo będzie wygenerować nieprawidłowy plik JPEG o dowolnym rozmiarze powyżej minimalnego rozmiaru poprawnego pliku JPEG. – jball

Odpowiedz

16

Szara 1x1 pikseli w 125 bajtach wykorzystujących kodowanie arytmetyczne, jeszcze w standardzie JPEG nawet jeśli większość dekoderów nie może dekodować go:

ff d8 : SOI 
ff e0 ; APP0 
00 10 
4a 46 49 46 00 01 01 01 00 48 00 48 00 00 
ff db ; DQT 
00 43 
00 
03 02 02 02 02 02 03 02 
02 02 03 03 03 03 04 06 
04 04 04 04 04 08 06 06 
05 06 09 08 0a 0a 09 08 
09 09 0a 0c 0f 0c 0a 0b 
0e 0b 09 09 0d 11 0d 0e 
0f 10 10 11 10 0a 0c 12 
13 12 10 13 0f 10 10 10 
ff c9 ; SOF 
00 0b 
08 00 01 00 01 01 01 11 00 
ff cc ; DAC 
00 06 00 10 10 05 
ff da ; SOS 
00 08 
01 01 00 00 3f 00 d2 cf 20 
ff d9 ; EOI 

Nie sądzę wspomniany przykład 134 bajtów jest standardem, ponieważ brakuje EOI. Wszystkie dekodery sobie z tym poradzą, ale standard mówi, że powinien się zakończyć jednym.

+4

Które z tych bajtów można bezpiecznie zwiększyć, aby utworzyć serię małych, ale różnych plików JPEG? –

+0

Pytania dotyczące pytania w pytaniu "Kwadrat" 8x8 'w segmencie DQT to w zasadzie współczynniki skalowania, z których każdy może być wartością od 1 do 255. Myślę, że jedyną wartością używaną w segmencie DAC tego przykładu jest pierwsza wartość w lewym górnym rogu bloku 8x8. – matja

2

Oto rutynowych C++ I napisał to zrobić:

bool is_jpeg(const unsigned char* img_data, size_t size) 
{   
    return img_data && 
      (size >= 10) && 
      (img_data[0] == 0xFF) && 
      (img_data[1] == 0xD8) && 
      ((memcmp(img_data + 6, "JFIF", 4) == 0) || 
      (memcmp(img_data + 6, "Exif", 4) == 0)); 
} 

img_data punkty do buforu zawierającego dane w formacie JPEG.

Jestem pewien, że potrzebujesz więcej bajtów, aby mieć plik JPEG, który będzie dekodował do użytecznego obrazu, ale to uczciwy zakład, że jeśli pierwsze 10 bajtów przejdzie ten test, bufor prawdopodobnie zawiera plik JPEG.

EDYCJA: Możesz oczywiście wymienić 10 powyżej na wyższą wartość, gdy zdecydujesz się na jeden. 134, jak zasugerowano w innej odpowiedzi, na przykład.

0

Nie jest wymagane, aby pliki JPEG zawierały znacznik JFIF lub Exif. Ale muszą zaczynać się od FF D8 i muszą mieć po nim znacznik, abyś mógł sprawdzić FF D8 FF.

+0

To świetny komentarz, ale nie odpowiada na pytanie OP. Rozważ umieszczenie go pod inną odpowiedzią. –

0

Chociaż zdaję sobie sprawę, że jest to daleki od najmniejszego ważnego jpeg i ma niewiele lub nic wspólnego z rzeczywistym pytaniem, czułem, że powinienem się tym podzielić, ponieważ szukałem bardzo małego pliku JPEG, który faktycznie wyglądał jak coś Zrobić kilka testów, kiedy znalazłem twoje pytanie. Dzielę się tym tutaj, ponieważ jest on ważny, jest mały i sprawia, że ​​jestem ROFL.

Oto 384 bajtowy obraz JPEG, który zrobiłem w Photoshopie. Jest to ręcznie rysowane przeze mnie litery ROFL, a następnie zapisane z ustawieniami maksymalnego kompresji, a jednocześnie wciąż czytelne.

sekwencje Hex:

my @image_hex = qw{ 
FF D8 FF E0 00 10 4A 46 49 46 00 01 02 00 00 64 
00 64 00 00 FF EC 00 11 44 75 63 6B 79 00 01 00 
04 00 00 00 00 00 00 FF EE 00 0E 41 64 6F 62 65 
00 64 C0 00 00 00 01 FF DB 00 84 00 1B 1A 1A 29 
1D 29 41 26 26 41 42 2F 2F 2F 42 47 3F 3E 3E 3F 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 01 1D 29 29 
34 26 34 3F 28 28 3F 47 3F 35 3F 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 FF C0 00 
11 08 00 08 00 19 03 01 22 00 02 11 01 03 11 01 
FF C4 00 61 00 01 01 01 01 00 00 00 00 00 00 00 
00 00 00 00 00 00 04 02 05 01 01 01 01 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 02 04 10 00 02 
02 02 02 03 01 00 00 00 00 00 00 00 00 00 01 02 
11 03 00 41 21 12 F0 13 04 31 11 00 01 04 03 00 
00 00 00 00 00 00 00 00 00 00 00 00 21 31 61 71 
B1 12 22 FF DA 00 0C 03 01 00 02 11 03 11 00 3F 
00 A1 7E 6B AD 4E B6 4B 30 EA E0 19 82 39 91 3A 
6E 63 5F 99 8A 68 B6 E3 EA 70 08 A8 00 55 98 EE 
48 22 37 1C 63 19 AF A5 68 B8 05 24 9A 7E 99 F5 
B3 22 20 55 EA 27 CD 8C EB 4E 31 91 9D 41 FF D9 
}; #this is a very tiny jpeg. it is a image representaion of the letters "ROFL" hand drawn by me in photoshop and then saved at the lowest possible quality settings where the letters could still be made out :) 

my $image_data = pack('H2' x scalar(@image_hex), @image_hex); 
my $url_escaped_image = uri_escape($image_data); 

URL uciekły dane obrazu binarnego (można wkleić w prawo w adresie URL)

%FF%D8%FF%E0%00%10JFIF%00%01%02%00%00d%00d%00%00%FF%EC%00%11Ducky%00%01%00%04%00%00%00%00%00%00%FF%EE%00%0EAdobe%00d%C0%00%00%00%01%FF%DB%00%84%00%1B%1A%1A)%1D)A%26%26AB%2F%2F%2FBG%3F%3E%3E%3FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG%01%1D))4%264%3F((%3FG%3F5%3FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG%FF%C0%00%11%08%00%08%00%19%03%01%22%00%02%11%01%03%11%01%FF%C4%00a%00%01%01%01%01%00%00%00%00%00%00%00%00%00%00%00%00%00%04%02%05%01%01%01%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%02%04%10%00%02%02%02%02%03%01%00%00%00%00%00%00%00%00%00%01%02%11%03%00A!%12%F0%13%041%11%00%01%04%03%00%00%00%00%00%00%00%00%00%00%00%00%00!1aq%B1%12%22%FF%DA%00%0C%03%01%00%02%11%03%11%00%3F%00%A1~k%ADN%B6K0%EA%E0%19%829%91%3Anc_%99%8Ah%B6%E3%EAp%08%A8%00U%98%EEH%227%1Cc%19%AF%A5h%B8%05%24%9A~%99%F5%B3%22%20U%EA'%CD%8C%EBN1%91%9DA%FF%D9 
+0

To jest kod perla na wypadek, gdyby ktoś się zastanawiał. – kristianp

7

Zdaję sobie sprawę, że jest to stare pytanie, ale wydaje mi się, można zrobić progresywny jpeg z tylko współczynnikami DC, że pojedynczy szary piksel może być zakodowany w 119 bajtów. To dobrze brzmi w kilku programach, w których go wypróbowałem (Photoshop i inne).

ff d8 : SOI 
ff db ; DQT 
00 43 
00 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
ff c2 ; SOF 
00 0b 
08 00 01 00 01 01 01 11 00 
ff c4 ; DHT 
00 14 
00 
01 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
03 
ff da ; SOS 
00 08 
01 01 00 00 00 01 3F 
ff d9 ; EOI 

Główną oszczędnością miejsca jest posiadanie tylko jednego stołu Huffmana. Chociaż jest on nieco mniejszy niż 125-bajtowe kodowanie arytmetyczne podane w innej odpowiedzi, arytmetyczne kodowanie bez nagłówka JFIF byłoby jeszcze mniejsze (107 bajtów), więc nadal powinno być uważane za najmniejsze znane.

+0

Dla ciekawskich, próbując odczytać to za pomocą iOS "' [UIImage imageWithData:] 'wyprowadza:' ImageIO: JPEG Corrupt JPEG dane: 2 zewnętrzne bajty przed znacznikiem 0xda'. –

4

Spróbuj następujące (134 bajtów)

FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 48 00 48 00 00 
FF DB 00 43 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF C2 00 0B 08 00 01 00 01 01 01 
11 00 FF C4 00 14 10 01 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 FF DA 00 08 01 01 00 01 3F 10 

Źródło: Worlds Smallest, Valid JPEG? przez Jesse_hz

-1

Znaleziono "the tiniest GIF ever" tylko 26 bajtów.

47 49 46 38 39 61 01 00 01 00 
00 ff 00 2c 00 00 00 00 01 00 
01 00 00 02 00 3b 

Python dosłowny:

b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;'