這個頁面的程式碼沒跑起來。

直接從資料夾裡開啟 index.html,瀏覽器會攔下 JavaScript 模組,於是你選好圖片之後,頁面不會有任何反應。改用 http 把這個資料夾提供出去:

powershell -ExecutionPolicy Bypass -File serve.ps1

然後開啟 http://localhost:8080/。

圖片轉 Data URI 圖片 base64 編碼,給 CSS 和 HTML 用

整張圖變成一行文字,直接貼進 CSS 或者 HTML。

語言: 繁體中文
檢視原始碼
你的圖片不會上傳。這裡根本沒有伺服器。

編碼在你自己的瀏覽器裡、用你自己的硬體完成。它就是對頁面手上已有的位元組做算術,沒有編碼器,沒有伺服器,也沒有哪一步聯網可以省。這個工具沒有任何聯網功能,不取東西,也不發東西。就算真有,這個頁面的另一頭也沒有伺服器能接住一張圖。

即時檢查: 檢查中…

離線: 檢查中…

別信我們嘴上說的。開啟開發者工具,盯著「網路」面板,丟一張圖進來。沒有一條請求帶著圖片、縮圖、檔名,或者你選中內容裡的任何一個位元組。或者乾脆拔掉網線,照編不誤。

1 選圖片

2 說清楚它要貼到哪裡

光給一串 data URI,其實很少有人真想要。大家要的是能直接貼進樣式表的那一行。所以先挑好這一行的樣子,圖片進去時引號已經加好了。引號這東西最容易弄錯,偏偏還只有 SVG 會因此出事。

alt 是故意留空的。這張圖到底有實際含義還是純裝飾,只有你知道。拿檔名瞎猜一句描述,對用螢幕閱讀器的人來說,比沒有描述更糟。

SVG 也用 base64 預設關著,因為 SVG 是文字,而 base64 是給位元組用的。百分號編碼能讓標記在樣式表裡還看得懂,通常還短五分之一。個別工具鏈非要 ;base64 不可,才把這個開啟。

SVG

3 複製

還沒選東西。往上面丟一張圖,能貼出去的那一行就出現在這裡。

以 Markdown 檢視

圖片怎麼轉成 data URI

  1. 選好你的圖片。拖到下面的方框裡,或者點開自己挑。瀏覽器直接從你的硬碟上讀,這期間沒有東西發出去。
  2. 說清楚這行要貼到哪裡。光要 URI,要一條 CSS 規則,要一個自定義屬性,要 <img> 標籤,還是要 Markdown。每一種都替你把 URI 的引號加好了,而引號正是最容易弄錯的地方,弄錯了偏偏只有 SVG 會出事。
  3. 看看代價有多大。每個結果都寫明它變成了多少個字元、比原檔案大出多少,以及這麼大的東西內聯進去到底合不合算。base64 會多出三分之一,這三分之一值不值一次省下的請求,完全看檔案多大,所以頁面直接告訴你落在界線的哪一邊。
  4. 看一眼那些提醒。圖片要是帶著 EXIF、色彩配置檔案或者 XMP,頁面會點名,並算出你這串結果裡有多少位元組是它們。副檔名跟實際格式對不上時,按實際格式來,並告訴你一聲。瀏覽器畫不出這個結果,它也會直說。
  5. 複製,或者下載。每個結果一個按鈕,另外還有一個把全部結果一次拿走。選自定義屬性時,輸出外面已經套好一個 :root 塊,貼到樣式表開頭就能用。

說得更細的版本

什麼時候該把圖片塞進 CSS,什麼時候不該 data URI 的代價在哪裡,base64 為什麼多出三分之一而 gzip 又還不回來,SVG 為什麼絕不該用 base64,以及那個只坑內聯 SVG、還一聲不吭的引號問題。

常見問題

我的圖片會傳到什麼地方去嗎?

不會。讀取和編碼都由你自己的瀏覽器在你自己的硬體上完成,用的是瀏覽器早就有的兩個函式。這個工具沒有任何聯網功能,不取東西,也不發東西。頁面的 Content-Security-Policy 把它可能聯的地址全列了出來,沒有一個是本站的。

data URI 是什麼?

一種把整個檔案寫在「本該寫網址的地方」的辦法。原來寫 url("logo.png"),瀏覽器就得跑一趟去取;改寫成 url("data:image/png;base64,iVBORw0..."),圖片本身就在這串字裡,瀏覽器當場解出來。實際效果是少一次請求,圖片跟著樣式表或者頁面一起到,而不是等它們到了之後再去取。

為什麼我的 SVG 沒走 base64?

因為 base64 對它來說是錯的編碼。SVG 本身是文字,而網址本來就能裝文字,只有少數幾個字元需要轉義。把那幾個轉成百分號寫法、別的原樣留著,產生的 URI 通常比同一個檔案的 base64 短五分之一左右,而且在樣式表裡還看得懂,元素名、顏色、viewBox 都還在,隨手能改。個別工具鏈非要 ;base64 不可,頁面上有個勾選框可以強制。

base64 會讓圖片大多少?

大約三分之一。三個位元組的檔案變成四個字元的 base64,也就是 33%,前面還要再加上 data:image/png;base64, 這一截。這是底線,躲不掉,用網址允許的那些字元去表示任意位元組,代價就是這麼多。也正因如此,頁面把字元數擺在檔案大小旁邊,省得你等樣式表都發布了才發現。

什麼時候內聯圖片才真的划算?

又小又必須馬上出現的時候。每個頁面都要載入的樣式表裡放一個 2 KB 的圖示,這是明擺著的賺:少一次往返,CSS 一到圖就在。過了大約 10 KB,這筆帳就翻過來了。內聯進去的圖片不再是一個獨立檔案,沒法單獨快取,沒法跟別的東西並行下載,而且外面那個檔案一改,它就得整個再下一遍。樣式表裡塞一張 200 KB 的照片,等於給全站每個頁面的關鍵路徑都加了 200 KB。每個結果落在界線的哪一邊,頁面會告訴你。

gzip 能把 base64 多出來的那部分壓回去嗎?

沒大家想的那麼靈。base64 編的要是本來就壓過的檔案,PNG、JPEG、WebP 都是這種,壓出來效果很差,因為裡頭幾乎沒有冗餘留給壓縮器去找了。通常也就找回 base64 多出來那三分之一裡的十分之一,絕不是全部。百分號編碼的 SVG 正好相反,它還是文字,壓縮效果跟原來差不多,這也是不該給 SVG 上 base64 的又一個理由。

這一步會動我的圖片嗎?

不會,而且這一點跟這裡多數工具是刻意不同的。沒有哪一步把它解碼成畫素再編回去,從你硬碟上讀出來的位元組,就是進 URI 的那些位元組。JPEG 還是原來那個 JPEG,畫質一樣,尺寸一樣。也正因為如此,結果可以說就是同一個檔案,而不是它的一份副本。

那 EXIF 和 GPS 也一起進樣式表了?

是的,而這正是貼出去之前值得想一想的地方。因為什麼都不重新編碼,相機寫下的東西全都跟著畫面走:位置、時間戳、機身序列號。手機照片裡這些能佔到 30 KB,編成 base64 就是 40 KB 壓在你頁面的關鍵路徑上,同時還把一個家庭住址提交進了儲存庫。JPEG、PNG 和 WebP 裡到底帶了多少後設資料,頁面會讀出來告訴你。想先清乾淨,用 EXIF 檢視與清除。

為什麼它用的類型跟我的副檔名不一樣?

因為副檔名可能是錯的,位元組不會。一個叫 logo.png、其實是按 JPEG 匯出的檔案,常見到每個圖片工具都得應付。而一個類型宣告錯了的 data URI 根本不顯示,沒有備援,也沒有一句值得看的報錯。所以類型是從檔案開頭那幾個位元組讀出來的,這裡涉及的每種格式,開頭都說得毫不含糊。兩邊對不上時,頁面會告訴你。

預覽是空白,哪裡出問題了?

多半不是 URI 的問題。HEIC 和 TIFF 都能產生完全合法的 data URI,可除了 Safari 沒有瀏覽器畫得出來,所以你貼到哪裡它就在哪裡缺一塊。先用圖片壓縮或者圖片縮放轉成 PNG、JPEG 或 WebP 再說。要是格式本來就很普通,那多半是檔案本身壞了:預覽是拿這個頁面產生的 URI 畫的,畫不出來,就說明這張圖沒能解碼。

data URI 有長度上限嗎?

在 CSS 裡和 <img> 標籤裡,你碰不到什麼上限,現在的瀏覽器在這兩處基本沒有實際限制。瀏覽器真正限制的是把 data URI 打進位址列,稍微長一點的現在多半直接拒絕,那是出於安全考慮,跟這裡的用法沒關係。真正的限制是上面那條:早在技術上出問題之前,你這個頁面已經比老老實實放張圖片更慢了。

免費嗎?要註冊嗎?

免費,沒有帳號,不用登入,沒有試用期,也沒有水印。檔案的數量和大小同樣沒有上限,因為沒有哪臺伺服器在為它們掏錢,工作是在你自己的機器上乾的。本站帶廣告,經費就是這麼來的,廣告拿不到關於你圖片的任何資訊。

斷網能用嗎?

能。頁面開一次之後斷網,它照常運作。這也是證明「什麼都沒上傳」最省事的辦法。一個把圖片送出去編碼的工具,拔線那一刻就停了。