說明

我有一次看到一張圖片發現他在黑底與白底中顯現出來的畫面會不同,我就開始自己研究做法,我是在做完之後才發現之前有人也有做過類似線上工具的。

示範圖片(P->89453018)

你們可以嘗試把這張圖下載下來,並且在不同底色的地方查看,最方便的應該就是Messenger的白色模式了,在點開圖片後會變成黑底的,就可以查看兩種底色下的圖片表現。

線上工具

建議使用Chrome或Firefox(行動裝置或電腦都行)
https://tools.incognitas.net/hiddenimg

2020/1/2更新:
在我做好工具一陣子後,我終於找到另一個比我早做這技術的線上工具的人了:深海異音(hbl917070)
這是他的文章:https://forum.gamer.com.tw/C.php?bsn=60076&snA=4936349
但他的工具有缺點,在下面會指出。

使用說明

  1. 先選擇白底時和黑底時要顯現出來的圖片。
  2. 增加邊框以符合原圖比例:能選擇輸出圖片大小哪張圖,並且在兩圖的大小差距間用底色填滿邊框。
    • 跟隨白底圖:輸出的圖片大小跟隨白底圖。
    • 跟隨黑底圖:輸出的圖片大小跟隨黑底圖。
    • 自動(建議選項):輸出的圖片長、寬各別會跟隨來源較大的長、寬(也有可能長跟寬跟隨不同張圖)。
    • 沒有勾選「增加邊框以符合原圖比例」(不建議):輸出圖片大小會跟隨白底圖,且黑底圖會被壓縮/拉長到大小符合白底圖(比例會失真)。
  3. 色彩深度(2020/1/4更新)
    • 固定色彩深度(預設):黑底圖和白底圖都固定是7bit(128色)
    • 自訂色彩深度(安全模式):滑桿能調整黑底圖和白底圖分配總共8bit(256色)的比例,滑桿右方會寫出目前黑底圖和白底圖分配到的色彩深度(單位:種顏色),在此模式下不會出現殘影。
    • 個別調整兩圖色彩深度:滑桿能個別調整兩圖的色彩深度,但注意如果調整結果不符合下述特殊的條件有可能會出現殘像
  4. 點選「開始」並等待。

工具我是用網頁HTML和Javascript做工具的,因為這樣在瀏覽器上就能運作(但外觀懶得管,很簡陋)
2020/3/1更新:UI更新了,看起來好看多了。

圖片特性

這種圖片的特性是在白色背景和黑色背景顯現出來的畫面會不同,但畫面只能是單色色階的,而且在正常均分色彩深度的情況下白色背景下最黑只能到128,黑色背景下最白也只能到127,就是一個色彩深度只有7bit(128色)的意思,如果黑白底圖色彩深度兩者加起來超過256色就會影響另一底色圖的呈現(出現殘像之類的),但有某些特殊的條件,例如該像素的白底圖沒有比該像素的黑底圖更黑(意思就是C+C¹-127 < 255),在這情況下能將圖片的色彩深度在特殊的條件範圍內增加,能讓圖片更鮮豔,並且不會出現殘像。

2020/1/2更新:
在深海異音的工具中,他的黑底圖的色彩深度是一律使用8bit(256色)的,雖然比較鮮豔,但會導致他的工具產生的圖片在黑底情況下,且原圖不符合上述特殊條件時,會有白底圖的殘像。

關於技術名稱的部分,因為我不知道這技術要叫什麼名字,所以我就先叫他「隱圖」或「數位雙變圖」。(深海異音稱它為「偽裝圖片」)

原理

png格式的圖片除了RGB以外還有一個參數:透明度
這種圖使用的是透明度,讓半透明的像素與背景顏色混合就能產生新的顏色,我在計算的時候是使用二元一次聯立方程式。

變數說明:
為了方便說明,以下數字都是用0~1表示,但實際上計算時除了α以外都是0~255。
B:背景顏色(0~1)(在這裡只有黑(0)或白(1))
X:白色背景時圖片該像素預期的顏色(0~1)(灰階,所以RGB都是X)
Y:黑色背景時圖片該像素預期的顏色(0~1)(灰階,所以RGB都是Y)
C:輸出的顏色(0~1)(灰階,所以RGB都是C)
α:輸出的不透明度(0~1)

這是一個顏色和背景混合的公式:
最終顯示在螢幕上的顏色=B(1-α)+Cα

最終顯示的顏色我們預期他是X(白背景時)或Y(黑背景時)
所以我們就能列出聯立方程式:
X=1(1-α)+Cα
Y=0(1-α)+Cα

移項後:
X=1-α+Cα
Y=Cα

我們就能求出Cα
α=Y+1-X
C=Y/α=Y/(Y+1-X)

先定義像素點參數為:
C – 顏色,0是黑,1是白
α – 不透明度,0是完全透明,1是完全不透明

當像素(C,α)和背景色B混合時,顯示的顏色是(1-α)B+αC
也就是說,最終顯示在螢幕上的顏色=(1-α)B+αC

若像素(C,α)需要在全黑背景時顯示為C,全白背景時顯示為C¹,可以列出兩組等式:
C = (1-α)0+αC = αC
C¹ = (1-α)1+αC = 1-α+αC

簡化後得出:
α = 1+C-C¹
C = C/α = C/(1+C-C¹)

由0≤α≤1可以得到C≤C¹的限制,因此在沒有特別要求的情況下,通常會限制0≤C≤½≤C¹≤1,保持兩張圖片的色彩深度是平衡的。

備註

實際上的圖片像素點範圍並非0~1,而是是0~255,所以實際上工具在運算時會把公式量化成0~255。
而且因為計算時最終的四捨五入會造成一些像素有誤差值1的存在。

常見問題

Q:這工具會不會因為圖比較大吃比較多網路?
A:不會,這工具(網頁)共約29KB,網頁載入完成後就不會再用到網路,所有運算都是在本機運算,不會傳回伺服器,所以吃的流量和圖的大小無關。

Q:執行起來怎麼那~麼慢?
A:執行速度和效能有關,圖片的大小和裝置的效能都會影響圖片生成速度。所以放棄IE吧,雖然我試過IE不支援這工具XDDD

Q:在windows 10的相片檢視器上結果看起來不符合預期?
A:那是windows 10的相片檢視器的應該是bug,會在白色模式的時候在圖片白底圖的黑色部分破出黑底圖的樣子,黑色模式時則是相反。總之,這顯然是廠商的疏失

更新記錄(2020/3/4更新)

2020/1/4更新:
加入自訂色彩深度選項,能調整黑底圖和白底圖分配總共8bit(256色)彩深度的比例,因為黑底圖色彩深度加深時白底圖色彩深度會變淺,反之亦然,所以不會有殘像。
用法參考:使用說明

2020/1/5更新:
加入個別調整兩圖色彩深度選項,能個別調整兩圖的色彩深度,但如果調整結果不符合上述特殊的條件有可能會出現殘像。

2020/3/1更新:
將網頁工具的UI更新,讓整體更美觀。

2020/3/4更新:
修正UI的部分bug,並將舊版外觀的工具另外上傳在這裡,如果有比較老舊(前提是支援工具使用技術)或效能差的裝置可以使用舊版外觀的工具。