Najmniejszy możliwy obraz URI danych dla przezroczystego obrazu

125

Używam przezroczystego obrazu 1x1 z obrazem tła, aby móc używać sprite'ów i nadal podawać alternatywny tekst dla niektórych ikon.

Chcę użyć identyfikatora URI danych dla obrazu, aby zmniejszyć liczbę żądań HTTP, ale jaki byłby najmniejszy możliwy ciąg znaków, aby uzyskać przezroczysty obraz ?

Zdaję sobie sprawę, że mógłbym użyć URI danych do rzeczywistych obrazów zamiast sprite'ów, ale łatwiej jest to utrzymać, gdy wszystko jest przechowywane w CSS zamiast rozproszonego.

Jacob Rask
źródło
1
Czy nie byłoby lepiej użyć rzeczywistego obrazu 1x1 z konfiguracją buforowania? Nie masz więcej żądań http, a w sumie narzut danych na adres URL obrazu może być mniejszy niż 78 bajtów identyfikatora URI danych.
Redzarf
1
@Redzarf: właściwie nie, prawdopodobnie nie byłoby lepiej. małe, rzadko zmieniające się zasoby wpływają na czas wczytywania strony nie ze względu na rozmiar pliku, ale z powodu ruchu w obie strony żądania HTTP. Inną subtelnością jest to, że większość przeglądarek znacznie bardziej agresywnie podchodzi do buforowania CSS niż inne zasoby, więc przeglądarka rzadziej eksperymentuje z odświeżaniem css (i zawartością w ten sposób osadzoną), oszczędzając więcej połączeń HTTP.
SingleNegationElimination

Odpowiedzi:

167

Po zabawie z różnymi przezroczystymi GIF-ami, niektóre są niestabilne i powodują błędy CSS. Na przykład, jeśli masz <img>i używasz najmniejszego możliwego przezroczystego GIF-a, działa dobrze, jednak jeśli chcesz, aby przezroczysty GIF miał znak background-image, jest to niemożliwe. Z jakiegoś powodu niektóre pliki GIF, takie jak poniższe, uniemożliwiają wyświetlanie tła CSS (w niektórych przeglądarkach).

Krótszy (ale niestabilny - 74 bajty)

data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

Radziłbym użyć nieco dłuższej i stabilniejszej wersji w następujący sposób:

⇊ Stabilny ⇊ (ale nieco dłuższy - 78 bajtów)

data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7

Jako kolejna wskazówka, nie pomijaj, image/gifjak sugeruje jeden komentarz. To się zepsuje w kilku przeglądarkach.

Layke
źródło
1
+1 dzięki! Zauważyłem, że to się przydaje. Użyłem twoich danych do stworzenia tej wtyczki, więc mogę używać responsywnych obrazów natywnie z okładką w tle lub zawierać-
Jason Sebring
1
Dlaczego krótszy jest „niestabilny”? Widzę, że czasami powoduje to czarny obraz, jestem po prostu ciekawy, czy ktoś wie dlaczego.
jvenema
Po wielu kłopotach stwierdziłem, że „krótsza” wersja faktycznie powodowała awarię przeglądarki na niektórych (nie wszystkich) stronach mojej witryny w starszych przeglądarkach z systemem Android (HTC One S, OS 4.1).
WebSeed
Świetna odpowiedź, ale jak dotąd nie najmniejsza .
Josh Habdas
22
data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E

Ostateczna długość zależy od tego, z czym jest spakowany.

Adria
źródło
3
Czy są jakieś argumenty przeciwko używaniu SVG? Czy są przypadki, w których to nie jest dobry pomysł?
tremby
Plik SVG jest odpowiedni w wielu przypadkach, ale w połączeniu z width: auto;plikiem SVG przyjmuje szerokość swojego elementu nadrzędnego. Obraz statyczny, taki jak GIF lub PNG, po ustawieniu automatycznej stałej wysokości i szerokości, zachowa współczynnik proporcji.
snazzybouche
14

Najmniejszy PNG - 114 bajtów:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=
joshcarr
źródło
Warto wspomnieć, że można to łatwo wygenerować za pomocą GIMP. Plik wynikowy będzie miał rozmiar 68 bajtów (jak dotąd najmniejszy możliwy).
Ismael Miguel
@AminahNuraini to jest plik PNG.
joshcarr
2
@AminahNuraini: A co z tą odpowiedzią mówi ci „SVG”?
Wyścigi lekkości na orbicie
10

Ten facet rozwiązuje problem za pomocą specyfikacji GIF. Jego rozwiązanie dla tego transparent.gifbyłoby 37 bajtów:

data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

Zbiera się jeszcze mniej, usuwając najpierw przezroczystość, a następnie tabelę kolorów ...


Specyfikacja GIF89a

  • Nagłówek (6 bajtów)

    Składa się z bajtów „GIF” i numeru wersji, którym zwykle jest 89a.

  • Logiczny deskryptor ekranu (7 bajtów)

    Bez wchodzenia w szczegóły ta sekcja pliku zawiera następujące informacje:

    • Plik ma rozmiar 1x1 pikseli.
    • Istnieje globalna tabela kolorów.
    • W globalnej tablicy kolorów są 2 kolory, drugi powinien być użyty jako kolor tła.
  • Globalna tablica kolorów (6 bajtów)

    Składa się z 3 bajtów na kolor, bajtu odpowiednio dla czerwonego, zielonego i niebieskiego. W naszym pliku pierwszy kolor to biały, a drugi to czarny.

  • Rozszerzenie kontroli grafiki (8 bajtów)

    Służy do wskazania, że ​​drugi kolor w tabeli kolorów powinien być traktowany jako przezroczysty (może być również użyty do parametrów animacji, ale nie ma go w tym pliku).

  • Deskryptor obrazu (10 bajtów)

    Plik GIF może w rzeczywistości zawierać wiele „obrazów”, dzięki czemu nie musisz określać danych obrazu dla części obrazu, które mają ten sam kolor co kolor tła. Każdy blok obrazu ma położenie i rozmiar w ramach ogólnego rozmiaru obrazu. W powyższym pliku pozycja wynosi 0,0, a rozmiar 1x1.

  • Dane obrazu (5 bajtów)

    Jeden blok danych obrazu zakodowany w LZW . Przedstawienie pojedynczego piksela zawartego w obrazie zajmuje 5 bajtów. Algorytm kompresji nie został zaprojektowany do bardzo dobrej kompresji pojedynczego bajtu.

  • GIF Trailer (1 bajt)

    Pojedynczy bajt z wartością szesnastkową 3B( ;w ASCII) wskazuje koniec GIF.

Opierając się na strukturach wymaganych dla przezroczystego GIF-a, okazuje się, że 43 bajty to prawie tak małe, jak to tylko możliwe.

Ale udało mi się wymyślić jedną sztuczkę, aby ją nieco zmniejszyć. W standardzie wspomniano, że globalna tabela kolorów jest opcjonalna. Oczywiście nie jest zdefiniowane, co się dzieje, gdy tworzysz GIF bez tabeli kolorów.

Kiedy masz indeks tablicy kolorów zdefiniowany jako przezroczysty, dekodery GIF nie przejmują się tym, że w rzeczywistości nie ma tabeli kolorów.

Więc zmieniłem logiczny deskryptor ekranu, aby wskazać, że nie ma globalnej tablicy kolorów, i usunąłem samą tabelę, oszczędzając w sumie sześć bajtów, zmniejszając rozmiar pliku do zaledwie 37 bajtów.

Co ciekawe, Wordpress dał mi uroczą listę komunikatów o błędach GD narzekających, że to nie jest prawidłowy plik GIF, pomimo faktu, że Firefox i GIMP zarówno otwierają, jak i wyświetlają (czy jest „wyświetlany”, gdy jest przezroczysty?) w porządku.

Aby uczynić go jeszcze mniejszym, przyjrzałem się największemu pozostałemu „opcjonalnemu” blokowi obrazu, rozszerzeniu kontroli grafiki. Jeśli nie potrzebujesz przezroczystości, ten blok nie jest już potrzebny, a to kolejne 8 bajtów, które możesz zabrać.

Źródło: Najmniejszy GIF w historii .

mckamey
źródło
1
W tym artykule odmiana 37-bajtowa opiera się na niezdefiniowanym zachowaniu, a autor wspomina, że ​​parser obrazu wordpress nie może sobie z tym poradzić. Chociaż prawdopodobnie będzie działać na większości przeglądarek, uznałbym to za ryzykowny wybór. Pozostałbym przy 43-bajtowej wariacji z tego samego artykułu. Wariant tego jest już opublikowany powyżej . Zobacz także dyskusję w komentarzach do najlepszej odpowiedzi
Brian
9

Możesz wypróbować następujące dane SVG (60 bajtów):

data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"/>

Samodzielny plik SVG wyglądałby tak (62 bajty):

<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg"/>

Zobacz też:

kenorb
źródło
2
Może być również zakodowany i użyty we właściwości favicon lub CSS . content
Josh Habdas
6

To najmniejszy, jaki znalazłem (26 bajtów):

data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=
KarasQ
źródło
To jest czarne w IE11.
tomasz86
4

Aby uzyskać pusty obraz, używam następującego identyfikatora URI: //:0

Jurgis
źródło
Firefox 44 i Internet Explorer 11 pokazują tag img alt. Musisz albo użyć jednego z powyższych, albo usunąć tag alt
PersyJack
Jest to bardziej wydajne niż żądanie / odpowiedź na obraz?
nu everest
Nie zweryfikuje jednak
Lucian Davidescu
0

W przypadku pustego obrazu:

data:null

(to się przełoży na src=(unknown))

T.Todua
źródło
Zasadniczo podoba mi się to, ale walidator w3c nie zatwierdza w praktyce: Błąd: Błędne dane wartości: null dla atrybutu src w elemencie img: Przedwczesny koniec URI.
brennanyoung