Czy można zmniejszyć rozmiar pliku SVG, aby był bliższy jego odpowiednikowi w formacie JPEG?

Jak już zauważył Wrzlprmft, ponad 50% rozmiaru pliku SVG jest pobierane przez osadzony bitmapowy obraz PNG, który jest używany do tworzenia raczej subtelnego efektu cieniowania na kontrolerze. Wystarczy pozbyć się tego obrazu i zastąpić go prostym gradientem radialnym, aby zmniejszyć SVG do około 10 KB.


Oryginalny obraz z fantazyjnym kreskowaniem po lewej stronie, wersja edytowana z prostym gradientem radialnym po prawej stronie.

Podczas wykonywania tej czynności powinieneś również sprawdzić swoje ścieżki, aby sprawdzić, czy istnieje coś, co można tam uprościć. Nie znalazłem wiele, ale kontur kontrolera ma kilka sąsiednich węzłów (w pobliżu górnej i dolnej środkowej części), które można łączyć bez widocznej różnicy.

To oszczędność 50%, ale nie zatrzymujmy się jeszcze. Jeśli wiesz trochę o Format SVG Możesz to zrobić znacznie lepiej.

Najpierw uruchom „Vacuum Defs” w Inkscape, aby pozbyć się zbędnych definicji, a następnie zapisz obraz jako „zwykły SVG”. Teraz nadszedł czas, aby otworzyć go w edytorze tekstu i zobaczyć, czego możemy się pozbyć. Najlepiej byłoby, gdybyś użył edytora z wbudowanym podglądem SVG, abyś mógł szybko zobaczyć, jak Twoje zmiany (miejmy nadzieję, że nie) wpłyną na wygląd obrazu. Używam do tego emacs ale jest inne edytory o podobnych funkcjach .

W każdym przypadku, gdy plik SVG jest otwarty w edytorze tekstu, zacznijmy go upraszczać!

  • W prawym górnym rogu znajduje się duży bezużyteczny <! - komentarz ->. Po prostu go usuń.

  • Jeśli edytujesz SVG bezpośrednio z Illustratora, jest też niepotrzebna linia <! DOCTYPE ...>. Usuń go też.

  • Inkscape nalega na wstawienie niepotrzebnego bloku metadanych RDF do obrazu. Po prostu znajdź <metadata ...> i usuń go wraz ze wszystkim przed i łącznie z zamknięciem </ metadanych>.

  • Ponadto, nawet jeśli plik zostanie zapisany jako „zwykły SVG”, Inkscape nadal będzie go blokował wieloma atrybutami użytkownika. Znajdź wszystkie atrybuty zaczynające się od inkscape: lub sodipodi: i usuń je.

  • Po usunięciu metadanych i atrybutów specyficznych dla Inkscape można usunąć wszystkie nieużywane atrybuty przestrzeni nazw XML z <svg>. Powinno być bezpiecznie usunąć co najmniej xmlns: rdf, xmlns: dc, xmlns: cc, xmlns: inkscape i xmlns: sodipodi. Jeśli istnieje zbędny atrybut xmlns: svg, również go usuń. Jedyne atrybuty przestrzeni nazw, które powinieneś zostawić na teraz:

    xmlns = "http://www.w3.org/2000/svg" xmlns: xlink = "http://www.w3.org/1999/xlink"
  • Znacznik <svg> ma również wiele innych niepotrzebnych atrybutów, które można bezpiecznie usunąć, takich jak włącz tło i xml: space = „zachowaj”. (Są one wstawiane przez eksportera SVG programu Illustrator, a Inkscape nie jest wystarczająco inteligentny, aby zrozumieć, że są bezużyteczne). Pole viewBox można również bezpiecznie usunąć z tego obrazu, ponieważ po prostu powtarza atrybuty x, y, width i height.

  • Możesz także bezpiecznie usunąć atrybuty kodowania i samodzielny z <? xml ...?>.

  • Teraz spójrzmy na dane obrazu. Z jakiegoś powodu Inkscape nalega na przypisywanie atrybutów id do każdego elementu, nawet jeśli nigdy się do nich nie odwołują. Dowolny atrybut id, którego wartość nigdy nie powtarza się nigdzie indziej w pliku (szukaj go!) Można bezpiecznie usunąć. W rzeczywistości jedynymi identyfikatorami, które należy zachować, są identyfikatory dla gradientów i ewentualnie dla innych obiektów (na przykład ścieżek) znalezionych w <defs>.

  • Ponadto Inkscape lubi generować długie identyfikatory, takie jak linearGradient4277. Zastanów się nad zmniejszeniem wszelkich identyfikatorów, których nie możesz po prostu usunąć w krótkiej wersji, np. Lg1.

  • Istnieje również kilka sekcji <defs> za sobą. Łączenie ich zapisuje kilka bajtów (i upraszcza strukturę dokumentu jako całości).

  • Na końcu pliku znajdują się także puste grupy (elementy <g>). Pozbądź się ich. Może również istnieć kilka kolejnych grup z tym samym atrybutem transformacji (lub w ogóle nikogo); bezpieczne jest także ich łączenie.

  • Z jakiegoś dziwnego powodu Inkscape zachowuje zbędną ścieżkę Beziera (atrybut d) dla elementów <circle>. Zajmuje miejsce bez powodu, więc po prostu je usuń. (Pozostaw d atrybutów w elementach <path>; są one rzeczywiście używane do czegoś.)

  • Inkscape lubi także używać CSS w atrybutach stylów, gdzie bardziej specyficzne atrybuty będą krótsze, na przykład przepisać fill = "# 4888fa" na bardziej szczegółowy styl = "fill: # 4888fa". Możesz zapisać kilka bajtów, przerywając te style na osobne atrybuty (i usuwając te, które po prostu niepotrzebnie powtarzają ustawienia domyślne), ale które są nieco bardziej zaznajomione z formatem SVG niż większość zmian opisanych powyżej.

  • Dodatkowo, jeśli są jakieś elementy <use ...>, możesz zapisać kilka bajtów, zastępując je rzeczywistym elementem, do którego się odnoszą. (Oczywiście, oszczędza to miejsce tylko wtedy, gdy powiązane elementy są używane tylko raz.) Wydaje się również, że Inkscape lubi pośrednio definiować gradienty kołowe, najpierw definiuje zatrzymania w <linearGradient>, a następnie odwołuje się do nich w <radialGradient>; Możesz to uprościć, przesuwając przystanki bezpośrednio do gradientu radialnego i pozbywając się nieużywanego gradientu liniowego. Jako bonus, jeśli po wykonaniu tego, udało ci się pozbyć wszystkich xlink: href, możesz usunąć atrybut xmlns: xlink z <svg>.

  • Jeśli naprawdę chcesz wycisnąć każdy dodatkowy bajt, znajdź wartości liczbowe ze zbyt dużą liczbą miejsc dziesiętnych i zaokrąglij je do czegoś bardziej rozsądnego. Tutaj podgląd w czasie rzeczywistym naprawdę pomaga, ponieważ pozwala zobaczyć, ile możesz zaokrąglić wartość, zanim stanie się widoczna. Nawet jeśli nie chcesz dokładnie sprawdzać każdego numeru, aby zobaczyć, jak można go zaokrąglić, możesz przynajmniej wybrać nisko wiszące owoce, na przykład zaokrąglając wartość 1,0000859 pikseli do 1.

  • Na koniec usuń wcięcia i spacje w pliku. Aby zminimalizować liczbę bajtów, musisz umieścić wszystko w jednej linii (lub przynajmniej wstawić podziały wierszy przed atrybutami, gdzie i tak jest wymagane miejsce), ale naprawdę trudno jest to odczytać. Jednak przyzwoitą równowagę między czytelnością i zwartością można uzyskać za pomocą prostego, konserwatywnego wcięcia.

W każdym razie udało mi się edytować ręcznie w obrazie SVG:

<? xml version = "1.0&quot;?> <svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" x = "0" y = "0" width = "124" height = " 52 "> <g transform =" translate (1, -27.5) "> <linearGradient id =" lg1 "x1 =" 70.1063 "y1 =" 13.4122 "x2 =" 66.1994 "y2 =" -26.4368 "gradientUnits =" userSpaceOnUse " gradientTransform = "matrix (0.9997, -0.0263,0.0263,0.9997, -7.61.61.3)"> <stop offset = "0" stop-color = "# 154BBF" /> <stop offset = "1" stop-color = " # 6E8BFF "/> </ linearGradient> <ścieżka d =" M 119.198,75.836 C 115.115.80.541 7.902,78.843 3.585.74.366 -0.734,69.888 -1.322.46.938 2.746.4.233 6.842,37.53 113.821,30.047 118,137,34.524 c 4.319 , 4,477 5,143,36.609 1.061,41.312 z "id =" path3298 "fill =" url (# lg1) "/> <linearGradient id =" lg2 "x1 =" 70.4391 "y1 =" 13.5887 "x2 =" 70.4391 "y2 = "-25.3265" gradientUnits = "userSpaceOnUse" gradientTransform = "macierz (0,9997, -0,0263,0,0263,0.9997, -7,4,61.3)"> <stop offset = "0" stop-color = "# 4166FA" /> <stop offset = "1" stop-color = "# 87A4FF" /> </ linearGradient> < ścieżka d = "M 119,71.843 C 115,247,76.118 11 615 774 49 7447,70 692 3,281 666,635 2,747.45.804 6.7.41,528 z 3.953, -4.277 107.372, -11.239 111,539, -7.183 4.167.457, 4115.329, -7.183 4.167.457, 4115.33.222 0.961.37.457 "id =" path3305 "fill =" url (# lg2) "/> <path stroke =" #fff "stroke-width =" 5 "d =" m 103.734,64.225 0.0 c -0.921, -0.271 -1.661 -0,724 -2,2, -1,342 -0,917, -1,051 -0,957, -2,455 -0,88, -3,576 -1,831, -0,373 -3,866, -0,886 -7,099, -1,84 -3,233, -0,954 -5,221, -1,627 -6,961 , -2,308 -0,544,0.983 -1.34,2.14 -2.679,2.525 -0.789,0.227 -1.656,0.204 -2.577, -0.068 -1.415, -0.417 -2.876, -1.431 -3.723, -2.583 -1.731, -2.354 -1.283 , -6,55 -0,601, -9,655 0,964, -4,399 3,692, -11,662 7,252, -133,641 3,374, -1,877 12,426,0,468 16,37,13,6315 3,944,1.1635 12 873,4 1185 14,692,7.535 1,9143,3 596 0,262,111,76 -1,117,153 0,262,111,76 -1,117,153,93 - 1.113,2.978 -3.016,6.746 -5.746.7.782 -1.338.0.505 -3.117.0.564 -4.531.0.146 z "/> <ścieżka wypełnienia =" # 4888fa "d =" m 103.734.64.225 0.0 c -0.921, - 0,271 -1,661, -0,724 -2,2, -1,342 -0,917, -1,051 -0,957, -2,455 -0,88, -3,576 -1,831, -0,373 -3,866, -0,886 -7,099, -1,84 -3,233, -0,954 -2521, -1,627 -6,961, -2,308 -0,544,0.983 -1.34,2.14 -2.679.525 -0.789.227 -1.656.204 -2,577, -0,068 -1,415, -0,417 -2,876, -1,431 -3,723, -2,583 -1,731, -2,354 -1,283, -6,55 -0,601, -9,655 0,964, -4,399 3,692, -11,662 7,252, -133,641 3,374, - 1.877 12.426,0.468 16.37,1.6315 3.944,1.1635 12.873.4.1185 14.692,7.535 1.914,3.596 0.262,11.176 -1.317,1593 -1.113.2.978 -3.016.64646 -746.7.782 -1.338,0.550 -3.117.5564 -1.58.0.550 -3.117.5.564 -4.531.5505 -3.117.5.564 -4.531.0.155 z "/> <ścieżka wypełnienia =" # 87b5ff "d =" m 117,774,40.292 c -1,17, -2,155 -7,571, -4,939 -14,293, -6,921 V 33,37 c -0,023, -0,007 -0,047, -0,014 -0,07 , -0,021 -0,023, -0,007 -0,047, -0,015 -0,071, -0,02 l 0,0 s -6,723, -1,985 -13,612, -3,12 -15,761, -1,949 -4,2962,2.337 -9,198,17.315 -6,265,21.228 0.907.209 3.014,2.449 4.462.043 1.452, -0.404 2.121, -3,4 2.652, -3.174 2.518.1.077 5.601.2.117 8.744.3 3.119.0.966 6.272.1.765 8.972.229 0.569.0.097 -0.498.2.975 0.502.4.097 -0.498.2.975 0.502.4.004 1.001 , 1,128 3,443,1.232 4,861,0.709 4,586, -1,693 8,602, -16.933 6.263, -21.227 z "/> <ścieżka wypełnienia =" # 2f67c9 "d =" m 90818,42.604 c -0.097, -0.194 -0.901, -0.575 -1.999, -1.006 0.317, -1.135 0.497, -2.007 0.401, - 2,2 -0,319, -0,641 -3,681, -1,766 -4,323, -1,447 -0,192.0,096 -0,5740,9 -1.004,1.998 -1.135, -0.315 -2.006, -0.497 -2.201, -0.401 -0.64,0.319 -1.766, 3.681 -1.446.4.322 0.096.0.193 0.901.0.575 1.997,1.006 -0.316.1.134 -0.496.2.007 -0.4.2.199 0.32.064 3.682,1.767 4.323,1.447 0.193, -0.095 0.575, -0.901 1.005, -1.997 1.135.0.314 2.008,0.496 2.199,0.401 0.642, -0.32 1.767, -3.682 1.448, -4.322 z "/> <ścieżka wypełnienia =" # 4888fa "d =" m 100.282,33.311 c -0.024, -0.007 -0.046, -0.013 -0.069 , -0,02 -0,023, -0,006 -0,046, -0,013 -0,07, -0,02 l 0,0 c -2,455, -0,725 -4,932, -1,334 -7,181, -1,755 -0,275,2.073 -1 164.497 -0,789,59,91 0,627,2.363 9.764,5.059 11.574,3.414 1.096, -0.996 2.091, -3.297 2.566, -5.483 -1.876, -0.731-3.937, -1.428 -6.031, -2.046 l 0.0 z ”/> <wypełnienie koła =” # 639bff "r =" 3.427 "cy =" 46.947 "cx =" 101.382 "/> <circle fill =" # 4888fa "r =" 2.868 "cy =" 45.940 "cx = "109,28" /> <circle fill = "# 2f67c9" r = "2.868" cy = "52.538" cx = "106.287" /> <radialGradient id = "rg3" cx = "90,874" cy = "39,29" fx = "90.874" fy = "39.29" r = "19.89" gradientUnits = "userSpaceOnUse" gradientTransform = "matryca (1.7028, -0.3387,0.276,1.3872, -70.22,16.58)"> <stop stop-color = "# 1166a8" stop -opacity = "0" offset = "0" /> <stop stop-color = "# 1166a8" stop-opacity = "0,02" offset = "0,45" /> <stop stop-color = "# 1166a8" stop-krycie = "0.63" offset = "1" /> </ radialGradient> <ścieżka d = "m 103.734,64.225 0.0 c -0.921, -0.271 -1.661, -0.724 -2.2, -1.342 -0.917, -1.051 -0.957 -2,455 -0,88, -3,576 -1,831, -0,373 -3,866, -0,886 -5,973, -1,508 -0,375, -0,11-0,75, -0,233 -1,124, -0,338 -0,388, -0,107 -0,753, -0,216 -1,127 -0,326 -2,107, -0,622 -4,095, -1,295 -5,835, -1,976 -0,544,0.983 -1.34,2.14 -2.679, 525 -0,789,0.2 -1,656,0.204 -2,577 -0,068 -1,415 -0,417 -2,876 , -1,431-3,723, -2,583 -1,731, -2,354 -1,283, -6,55 -0,601, -9,655 0,964, -4,399 3,692, -11,662 7,252, -133,641 3,374, -1,877 12,4 26.0468 16.245,1.591 l 0.274.0.081 c 3.795.1.123 12.724,4.078 14,543,7.495 1.944,3.596 0.262,11.176 -1.317,1593 -1.113.2.978 -3.016.6.746 -5.746.7782 -1.338,0.505 -3.117.7.782 -1.338,0.505 -3.117.0.564 -4,531,0.146 z "fill =" url (# rg3) "/> </ g> </ svg>

Ten obraz SVG wygląda prawie nie do odróżnienia od drugiego przykładu powyżej i zajmuje tylko 5189 bajtów, czyli znacznie mniej niż obraz JPEG. Jestem pewien, że można go jeszcze zoptymalizować, ale to tylko przykład tego, co można zrobić w ciągu kilku minut w praktyce. (Wybieranie tej odpowiedzi zajęło mi znacznie więcej czasu niż rzeczywista edycja kodu SVG).

Wreszcie, skompresowanie tego kodu SVG za pomocą gzip zmniejsza go do 1846 bajtów (!), Co stanowi ponad jedną czwartą rozmiaru twojej wersji JPEG.

Quot;?