可否完全由代碼表示一張手機拍攝的照片?

用手機拍一張照片,這張照片顯示在電腦上,他由像素構成,每個像素都是唯一的顏色,那麼是否可以理解為,一張圖片,是由無數同一個顏色的像素組成的?

那麼,是否可以把每一個像素的的顏色用代碼顯示,比如第一行第一列是第一個像素,他是紅色,就用「color:#FF0000」表示,第一行第二列是第二個像素,他是灰色,就用「color:#666666」,然後把每一個像素的顏色按照一定的排列順序組合起來,重新組成一張圖片,這樣是否可行?

我覺得,這樣做,圖片存儲網站,就可以把圖片全部分解為顏色值,把需要保存的圖片的像素數字信息保存下來,分類歸檔,等到需要的時候,搜索他們,伺服器再把按照原有的圖片數字信息組合起來,顯示給使用者,減少伺服器的存儲空間,網頁也可以更快的載入出來。

問題:

1、如果這樣做了,存在的問題是什麼?是不能減少存儲空間?還是技術問題,或者是其他的原因?

2、現有的伺服器存儲圖片的技術的原理是什麼?優點與缺點在哪裡?

題主只是一個計算機小白,對這些東西不了解,也不了解圖片的相關知識,只是有一些想法,若問題比較幼稚,還請輕噴。


哦……題主的確很聰明,一下子就快摸到圖片存儲原理的邊了。

但是……你以為現在的圖片都是怎麼存儲的?


你說的類似方法,業界叫BMP格式(bitmap)。但並不像你說的還color#什麼一坨,而是直接用三個連續位元組分別表示一個像素的RGB分量,比如全黑就是00 00 00——光color這個單詞佔用的空間就足夠存1又2/3個像素了。

BMP是諸多圖片格式中,佔用空間最大的一個大類。


仔細觀察的話,很容易發現,圖片上往往會有一些區域是同一顏色的;那麼連續20個黑色點是60位元組,黑色點*20隻需4個位元組,這顯然可以減少很多空間佔用。這個叫行程壓縮。

更進一步的,一幅圖片顏色再紛繁,往往也不會覆蓋整個RGB顏色空間;那麼我們就可以先弄個編碼轉換表,把rgb編碼轉換成短一些的編碼,這樣也能節約空間。
更進一步的,我們甚至可以用1個位表示圖片中出現最多的那種顏色、而出現極少的顏色就可以給一個長編碼;甚至,如果圖片上有很多重複出現的顏色序列,我們也可以給它一個編碼……

這個就叫哈夫曼編碼。


以上做法叫做「無損壓縮演算法」。常見的很多圖片格式,如TIFF.GIF.RAW.PCX.TAG.PNG.BMP等,都支持無損壓縮。

無損壓縮可以把一幅圖片的大小壓縮到原來的1/2~1/5.


這遠遠不夠。

研究發現,人眼對物體的輪廓非常敏感;但對一整塊顏色的漸變極為遲鈍。
所以,我們可以想辦法識別出物體輪廓部分、以最高精度保存它的信息;而對色彩漸變的部分,不妨丟棄一些細節——比如,相鄰的A點的R分量是210,B點則是208,其它分量也相差很小;那麼就把它們都當成同一個顏色得了。

對圖片做快速傅里葉變換,那麼低頻分量就剛好對應漸變信息、高頻分量對應邊緣細節。很容易就能做到「保留人眼容易注意到的細節、拋棄人眼不敏感的過度信息」。

這樣處理以後,圖片體積自然是可以更小了;但也損失了很多信息,再也無法還原了。所以叫有損壓縮演算法。

常見的jpeg、jpg等圖片就是有損壓縮的,可以把一幅圖片壓縮到原來佔用空間的1/10到1/40左右。
一般來說,jpeg圖片壓縮到原始圖片的1/10左右,質量仍然很好,並不會有人眼明顯可察覺的瑕疵。


靜態圖像壓縮業界研究很多年了,相關著作可謂汗牛充棟。以上只不過是些連入門都談不上的簡單介紹而已。


題主自己想出來的話還是很有創造力的……可是我很好奇題主你之前認為照片是怎麼儲存的?


思而不學則殆

-----
有人說對題主沒有幫助

高票已經授人以魚了,我不過授人以漁。


看到這個坑,忍不住就要跳進來了。我將試著從不那麼涉及代碼的角度,來說說到底怎麼回事。

1. 圖像到底是怎麼存儲的
拿我頭像這張圖舉例,大眾視角是這樣的。

左邊為原圖,右邊為放大到1600%。其實我相信你已經看出來了,圖像,就是這樣的。我們所看到的圖像,還有個便於理解的名字,點陣圖,或者說,點陣圖。
只是這些小點,真的是很小,肉眼難以察覺。平常我們覺得一副圖像比較模糊,不高清,其實大體我們的意思就是,這個小點不夠多,不夠小,很多細節沒有被呈現出來。

再來深挖下右邊這張圖

講這種圖前,先得了解個小知識,那就是,灰度圖--也就是沒有顏色的圖。沒有顏色,從白到黑,我們將它等分為255份,每一份代表一種灰色。其實講道理,上面那種圖,我只開了藍色通道,上圖就應該全顯示藍色,不是灰白。但是ps就是這樣玩,它有它的想法,讓它去吧。

開兩個通道給你們感受下(這個就符合我們認知了)

開了紅,綠倆通道,也就是說上圖,是完全沒有藍色的。再加上藍色,就是原圖了。
至於為啥要這樣玩,有沒其他套路來表示顏色,當然是有的,那就複雜了,你可以看看下鏈接。
顏色模型 | Garan no dou

回歸到之前的ps通道圖,大體就是,顏料的配置。你有紅,綠,藍,三種顏料。每一種按照顏色深淺等分為255份,所以上圖的意思就是,藍色燃料的配置。比如在這個點位,是純粹白色,那等會兒上染料的時候,就配255的藍色,純正藍!
紅色,綠色通道同理。現實世界的印刷工藝很多就是這樣的,可以類比。不信就拉開你的印表機瞅瞅,當然印刷是CMYK

在計算機裡面,我們就可以這樣存儲一張圖的信息了。
搞個大矩陣來表示位置
A00 = 【255,255,255】.....
這樣,一個個給點賦值,就存儲下來了。其實,現在存儲的大體思想也就是這樣的,讓我們來看看這樣存儲的大小。
比如我們剛才上面那張圖,尺寸是 100*100,每個點位3位元組(表示3個顏色),其實計算機是按照4個位元組給的。那就是 100*100*4/1024 = 39K
再複雜,像素高一些的圖,那需要的就更多了。比如 1024 * 960 * 4 / 1024 = 3840K = 3.8M
但是實際上我們平常接觸的那些圖都沒那麼大啊,這個就要涉及到壓縮編碼了。

2. 圖像壓縮(這個坑太大)
有損:
無損:

3. 矢量圖
估計這個就是很困擾大家的。的確,計算機是能存儲矢量圖的,而且,存儲起來,比點陣圖不知道要方便到哪兒去了。估計幾K就存儲完所有信息了。但是,這玩意不通用啊,畢竟還是自然界圖占絕大多數,自然界圖,轉不了矢量圖啊。這裡面要說的話,又得說上幾天了。坑真的太大了。。。填不動啊


3. 視頻
其實不光圖像,連視頻都是這樣一張張圖存儲下來的,一般的每秒24張。所以你可以算算,這得多大的量啊。所以,視頻也是有各種壓縮演算法的。


總之,很多人知道計算機的能力很強,然後憑自己想像力形成了計算機運算能力超強的形象。其實計算機想的是,MDZZ,這人想像力真有限。


你說的類似方法,業界叫BMP格式(bitmap)。但並不像你說的還color#什麼一坨,而是直接用三個連續位元組分別表示一個像素的RGB分量,比如全黑就是00 00 00——光color這個單詞佔用的空間就足夠存1又2/3個像素了。
引用自invalid s的回答

我再說一下第一個問題,是不是會減少存儲空間?答案是不會,會增加非常非常多的空間。
拿1080P的照片來說,它的解析度是1080x1920,每一個像素會佔3個位元組,則一幅圖片所佔用空間是1 080 x 1 920 x 3 = 6 220 800 B,如果按照題主再用color什麼的這種東西表示,需要再佔用2倍的空間,也就是6 220 800 x 3 = 18 662 400 B ≈ 18 MB。而大家可以在百度裡面找找1080P的壁紙看看,通常都在400KB左右,也就是0.4MB,什麼意思很明顯了吧,如果用題主的方法存儲圖片,需要多佔用40倍的空間!

PS:有人問過我為啥相機拍出來的1080P的照片有七八M呢?這一點主要是,相機拍出來的照片為了質量,通常壓縮率很低,原圖就在6M左右了(參看上文解釋),但這還是不夠啊?
別急,還有,相機拍出來的照片還記錄了光圈、快門等等數十種信息,這些信息是為了以後P圖調光方便的,又佔了相當大的空間,不信你用PS打開一張相機拍攝的照片,哪年哪月哪什麼型號的相機這些信息都能找到。
這還沒完,部分圖片中還保存了小的預覽圖,這樣顯示預覽的時候能快一些,又佔了一些空間。前些年有種惡搞圖片很火,預覽明明顯示的熱火的美女圖,但打開大圖就成了鬼了,用的就是這種內置預覽圖的方式。


用Base64編碼BMP然後儲存在資料庫字元串欄位裡面,就是題主說得東西。。。
如果不用Base64編碼,直接把BMP儲存在資料庫的二進位欄位裡面,也是題主說得東西


我看了一下答案,感覺大部分人沒有看懂題主的意思。
題主的想法是根據每個像素點的色彩值做歸納,然後通過色盤的編號來還原。這就是我們平常使用的gif格式圖片。

(畢業多年,具體有些忘了。以下描述如果有錯請指正)

gif格式會將當前圖片的所有顏色都進行(8位)編號。也就是說,圖中的任何一個像素的顏色都可以被一個0~255的數字代替。從而在頁面上不需要保存所有的像素信息。但是同時,頁面上的顏色不能超過256種。

為了更好的理解,我拿張圖做個例子:

這是原始圖片

這是gif圖片,只用了256種顏色

看不出區別?我們仔細看看木頭部分:

由於只能使用256種顏色,相對於真色彩而言必然需要犧牲一部分的過度顏色,從而導致過度不自然的現象。好在這張照片整體顏色比較相近。所以損失的顏色並不太明顯。

假設我們對所有顏色進行編號。那麼隨著圖片的顏色增多,編號的大小也會逐漸增大。當顏色多到一定的程度時,編號本身就會變得相當佔用資源。

同時,按照題主的想法。通過顏色索引來組成圖片,勢必需要針對每張圖片建立索引。由於圖片顏色不同,你的索引庫也會變成#000000~#FFFFFF的排列組合。當編號從000000開始到FFFFFF結束時,它就成了需要同步版的BMP格式。

以上~

============================================================
拓展:
當然了,如果gif老是這麼稜角分明也很難過不是?有一種「抖動」演算法,用於淡化這種邊緣問題。

抖動通過在兩種顏色邊緣之間,通過交替顯示顏色的方式產生過度效果。使用多個像素組合,模擬出第三種顏色。這樣的好處在於不需要額外增加顏色,但是缺點在於仔細看圖片會存在顆粒感。


我小學時候就這麼想了,還以為自己發明了很厲害的東西
然後就沒有然後了


你看一本書叫《多媒體信息技術導論》就知道了,我給你來個通俗的科普。

圖片傳遞的是光信息,因此我們需要將光的信息保存為數字信息(圖片文件),然後再將數字信息還原成光信息。

如何採樣(RGB表示方法)
由一個採樣器(感光單元)的電壓變化來量化值,比如黑色電壓為1v,就是0,純白電壓為256v,就是255。這一個採樣器只能感應亮度,如果要彩色的,就需要3個這樣的採樣器,分別表示紅藍綠。這三個採樣器才能採集一個像素點的光信息。一張圖片就是由密密麻麻的這樣的像素點構成的。

上面就是我們怎麼採樣的方法,接下來我們來做數學題,怎麼把這些保存為一個圖片文件。

一個採樣器採集到的,如果你量度的範圍是從0到255,於是一個像素點的顏色,我們可以這麼表示(0,100,200),紅色為0,藍色為100,綠色為200。
你知道的,計算機存儲只有0和1,我們怎麼來表示256個數值呢?沒錯!那就是用排列組合!
出題:屋子裡有8個電燈開關,可以隨意開一個燈或者關一個燈,請問屋子裡有多少種情況?
這是一道送分題,2的8次方等於256,我們用8個二進位數來表示一個數值,於是一個像素點就可以用24個二進位數表示了(稱這張圖片是24 bit/per sample)。那我們用一連串24個的01,按照紅藍綠的順序排列,就可以在電腦上存儲一個像素的值了,那我們把圖片裁剪成高為一像素的碎片,然後按照順序像電影膠片那樣連成一條,不就得到了超長的一條0和1組成的數據了嗎?把這樣一整條數據存儲到硬碟就可以了。歐耶。

有人要看圖片?那就把這一長條的數據發送給他,然後按照我們規定的規則,紅藍綠三個顏色,每個顏色八位,然後每個像素點每個像素點的取……圖片的寬度是多少來著?
(所以,我們除了圖像信息以外,還有額外的信息需要保存,長高寬位深度採樣類型等等)啊,原來500個像素就是圖片的寬度,好,我們換一行接著讀取圖片……這樣的信息有了,我們就可以用電視機把圖片放送出來了!


可是問題來了,這種原始的圖片存儲起來太占空間了,而且傳輸給其他人很費帶寬的。那我們就壓縮代碼來存儲(就像有人回答過了,採用霍夫曼編碼這種方式來壓縮代碼)
目前來說,圖片文件的格式就是圖片的壓縮類型。

說說題主的問題,你想說的是用字母A代替一長串的01序列對吧?然後在需要的時候,又補充回去。你這種方式相當於說把壓縮過程和傳輸過程結合成一個過程裡面。
原本,我們【取樣,壓縮一次,存儲,通過很簡單的IO流操作就可以把圖片文件發送給其他人,然後解壓縮,恢復成圖像】。
倘若按照你的想法,變成了【取樣,壓縮一次,存儲過程再壓縮,檢查圖片是否有這樣的序列,替換,有人要圖片,然後取出圖片,檢查圖片是否有標記,替換回原代碼,然後再通過簡單的io流發送給別人,然後解壓縮,恢復成圖像】

這種方式在每次別人要圖片的時候你都要計算,你說這種方式好不好呢?也不能說不好,只是現在沒有這樣的實現,你是用大數據採樣的方式,將龐大的圖片文件中,01序列重複出現概率最高的的那一組分析出來,然後用壓縮的方式去再壓縮存儲。目前沒有人能做到,最大的色情網站也沒有這樣做。

如果你要了解青蛙,最好的方式就是解剖它。書,可不是白讀的。

上面講的每一步,《多媒體信息技術導論》里有簡單的講,實際的商業過程中這些技術細節更加詳細。


圖片就是這麼存的。。。


這讓我想起了知乎上一個段子,如果你想了解某一方面的內容,你只需要問一個弱智的問題,然後@一堆大牛,接下來 ,等待大牛的一對一授課吧


30秒鐘之前,
對於計算機知識,
我一直以為自己是個無可救藥的小白,

然後就看到了題主


現在最常用的jpg是在題主的理論基礎上,使用生物學結論,人眼對明暗的敏感度遠高於對顏色的敏感度,所以對於一個8*8的塊顏色取均值(所以顏色數據量變為原來的1/64),亮度值保留。

其實題主應該這麼問,既然照片全都數字化了,那麼我還幹嘛要用手機拍啊,我造點數據不就變成一張照片了么?這個問題可以幫題主拓展下計算機思維。


這是lut(lookup table)喵~

關於如何存儲圖像和如何壓縮,建議多讀書。

以及有損壓縮和基於各種變換的無損壓縮等都是一大堆論文支撐著的喵~

如果是自己想到這裡的,吃個糖踩著前人腳步繼續往下深入吧喵~


如果樓主進一步思考的話, 就會發現:
顯示器一個像素由紅綠藍三種顏色組成(也就是R,G,B每種顏色0-255一共256種亮度,2^8)計算機按照2進位方式存儲就是8位, 同一個像素通過紅綠藍各個顏色分量的亮度不同再組合成像素的顏色.
那麼只要算一下排列組合就知道一共可以組成2^24種色彩. 這是一個全拍列, 也就意味著: 如果想要對這個"顏色表"做一個索引的話, 那麼索引長度也是2^24.
也就是說如果圖像是"真彩"的, 那麼就無法通過顏色索引的方式來縮小體積.
例外: 一張圖片不一定會用到所有的2^24種顏色, 但是如果按照中心灰理論的話, 所有的顏色都是平均分布的, 所以即使只用到了部分顏色, 也依然數量龐大(比如使用增強色的圖片顏色總數為2^16, 但依然不使用索引色). 建立索引表的開銷足以抵消節省的存儲空間.

而GIF格式只有8位來表示顏色的時候索引表才會帶來顯著的存儲效率, 而代價就是圖像質量降低(只能直接顯示不超過256種色彩, 並且通過降低解析度的方式來抖動模擬出其他顏色),但是GIF即使採用8位色彩索引, 依然在數據存儲時採用了壓縮編碼.

常用的JPG壓縮方式,其實非常複雜,不光有演算法上的壓縮, 還有基於人類視覺心理學上的理論, 比如: 首先將RGB方式的圖像數據轉變成YUV格式, 因為人眼對於亮度和色深的敏感度不同, 然後再是DCT轉換(頻域變換)通過這個變換來得到Y,U,V三個分量的頻譜. 然後就是量化(這個可以認為是為圖像壓縮起一個閥值的作用, 閥值小了圖像質量越好, 但是壓縮率低, 大了圖像質量就越差, 但是文件體積就越小), 然後就是壓縮編碼.

樓主提到的其實就是BMP真彩色圖片的概念(並非實際存儲方式), 所以也就是無壓縮的存儲方式.
上面主要說了一些常用的圖像存儲方式, 而視頻的存儲方式還要更加複雜一些(相鄰的兩幀畫面比較接近, 只存儲差異部分等等), 為的都是降低數據量.
否則的話, 樓主計算一下: 按照25幀每秒, 1080P的視頻, 一分鐘要佔據多少空間?


數字圖像的基本概念你已經領會到了。
推薦你去看書學習下吧。


當年玩過模擬城市2還是3來著,地圖的存儲就是使用了類似模式。其結果就是,我可以用一款二進位編碼編輯軟體,直接修改地圖存儲文件從而完成城市建設。
還有一則笑話:一個清華計算機系的男生對著滿屏的二進位代碼一臉淫笑。


我比較好奇,為什麼一個電腦小白對紅色的理解恰好就是FF0000。


這個話題我不得不回答了,因為憋的好久。
大家把圖像如何存儲已經解釋的很好了。但是有沒有考慮下一步?我想跟大家聊聊我認為的下一代圖像存儲方式。
以像素信息為介質的存儲方式已經大範圍被使用了,這個在記錄過去時非常有用,可以精確到每一點信息,但是存儲和傳輸起來卻比較占帶寬。後來發明的圖像壓縮等等,會節省一部分空間,但是沒有從根本上解決問題。
當我們回想起過去某個美好的畫面時,腦子裡並不是一點一點的像素信息的集合,而是內容的集合。什麼是內容的集合,就像這樣的」就是2006年的國慶節,下午的陽光很好,我去車站送女朋友,她臨走前親了我的臉,並微笑了一下「。所以我覺得以後圖像可以不存儲點信息,應當存儲內容信息。而每一個內容信息的單位元可以是一些已經存儲好的點信息,剩下的就是組合和變換了。
這樣一來,只需要有一個公共庫,加上必要的內容就可以重構圖像信息,這樣將大大減少圖像的存儲和傳輸帶寬。
你們覺得呢?


題主啊,基本的計算機知識是很重要的
原本的圖片,一個像素需要4byte空間,換成你這種color:#FFFFFF的表示,每個字母要至少佔1byte空間,一個像素變成了12byte,空間增大了3倍


推薦閱讀:

用什麼壓縮軟體壓縮後所佔存儲空間最少?

TAG:圖片存儲 | 計算機技術 | 圖片搜索 | 電腦基礎 | 數據存儲技術 |