茂說 2 (調色板)

保存於:2008年11月27日 12時56分14秒

 

啊茂 14:13:37
索引圖片的顏色儲存原理你明左未?
Huang_Jian肇 14:14:31
系琴日聽你講過下,我把我的理解說下你睇下系米敢

Huang_Jian肇 14:17:00
D顏色已經編碼好,0代表咩色,1代表咩色,這色是調色版用來畫畫的色,圖片的話呢就是儲存一張圖的各個像素的色的編碼

啊茂 14:19:06

啊茂 14:19:07
是的
Huang_Jian肇 14:20:17
爲什麼黑色那張不是透明的

啊茂 14:22:09
圖片存儲的數據就像一個指針,係指向顏色既,例如位置A指向B顏色,原來B顏色系藍色,我把B顏色換成紅色既話,甘你會發覺張圖片原來藍色的地方都變成紅色了,按呢個原理,我把藍色的透明度設爲透明,那麼原來藍色的地方就都透明瞭
Huang_Jian肇 14:23:42
現在不是把黑色的地方變透明瞭嗎?

啊茂 14:24:43
之前果D代碼透明化的原理是:把圖片轉成TYPE_4BYTE_ABGR的類型,呢種類型的存儲格式和索引圖片不同(至少有乜唔同你自己再研究),雖然可以轉成透明,但因爲已經轉成TYPE_4BYTE_ABGR類型,所以不是索引了
啊茂 14:25:29
現在我再講我係點樣取到藍色既索引值,然後在調色板中找到它,並把它設爲透明的
啊茂 14:29:54
inputbig.getRaster().getPixel(10,10, (int[])null)[0]
這是取得位置10,10的顏色,如果這是TYPE_4BYTE_ABGR類型,則會返回Color[]類型,就是顏色了,但我這是TYPE_BYTE_INDEXED類型,所以它返回的不是顏色,而是顏色的索引值,因爲我事先知道那裏是藍色,且只有藍色這一純色,所以數組的第一個[0]就是我要的索引值了,位置10,10是藍色,它的索引值和整張圖片的其它藍色索引值都是一樣的,好了,現在我找到藍色的索引值了
啊茂 14:30:12
再來構造調色板
啊茂 14:32:58
本來的是想從第一次生成的BufferedImage中取出調色板,再來修改的,但我發現取出來的調色板ColorModel是無法修改的,只能讀取,但BufferedImage有一個構造類可以指定調色板,即是IndexColorModel(這是ColorModel的一個子類,專用於索引圖片和灰度圖片),現在思想出來了,就是先構造一個藍色的透明度爲0的調色板,然後用這個新構造的調色板來生成BufferedImage
Huang_Jian肇 14:34:51
聽你講左敢多,調查色板好似系重點?關鍵

Huang_Jian肇 14:38:02
你無用到了原來寫的這個函數了createImageByMaskColor

啊茂 14:38:27
新構造的調色板是以原來的調色板爲基礎,它們應該是除了藍色的透明度,其它是完全一致的,查查IndexColorMode的構造方法,可以知道,生成IndexColorModel需要r、g、b和Aplah值,這些都是數組,r[0]、g[0]、b[0]、a[0]構成調色板中的第一個顏色。
byte[] r = new byte[cmm.getMapSize()]; //紅色
   byte[] g = new byte[cmm.getMapSize()]; //綠色
   byte[] b = new byte[cmm.getMapSize()]; //藍色
   byte[] a = new byte[cmm.getMapSize()]; //透明度
   cmm.getReds(r);
   cmm.getGreens(g);
   cmm.getBlues(b);
以上是先把舊調色板的各分量讀取出來,
for(int i = 0; i<a.length; i++) {
    if(i == inputbig.getRaster().getPixel(1,1, (int[])null)[0]) {
     a[i] = 0; //透明
    } else {
     a[i] = 1;
    }
   }
然後設置各分量的透明度,如果是藍色的索引值分量,透明度爲0,其它爲1
到現在,新調色板構建好了
啊茂 14:38:44
IndexColorModel cm = new IndexColorModel(8, a.length, r, g, b, a); //用以上參數重新構建一個顏色模型,其中8是每像素佔位,這裏是
                                                                      //png8格式,故用8,a.length是顏色分量長度
啊茂 14:39:28
然後用BufferedImage的構造方法構造新的BufferedImage,並指定調色板
inputbig = new BufferedImage(1920, 1080,BufferedImage.TYPE_BYTE_INDEXED, cm);
啊茂 14:39:42
這樣就行了
Huang_Jian肇 14:40:08
r[0]、g[0]、b[0]、a[0] 是數組,那麼IndexColorModel是整張圖片的信息?

啊茂 14:40:21
不是,是圖片的調色板
啊茂 14:40:41
inputbig.getRaster()得出來的纔是圖片的數據
Huang_Jian肇 14:41:34
IndexColorModel是圖片的調查色板,是整張圖片說的?還是一個像素點?

啊茂 14:41:44
整張圖片
Huang_Jian肇 14:42:19
對應一個像點信息是不是在它的數組中會反映?

啊茂 14:43:03
==,我畫個圖給你
Huang_Jian肇 14:44:31
if(i == inputbig.getRaster().getPixel(1,1, (int[])null)[0])   這是怎樣的邏輯?

啊茂 14:45:17
如果調色板數組的序號 == 藍色的索引值
Huang_Jian肇 14:46:23
inputbig.getRaster().getPixel(1,1, (int[])null)[0] 是 藍色的索引值?

啊茂 14:48:07
我已經知道位置1,1是藍色了
啊茂 14:48:20
我現在是以藍色底的圖片爲基礎的
Huang_Jian肇 14:48:57
那對藍底的inputbig.getRaster().getPixel(1,1, (int[])null)[0] 是 藍色的索引值?

啊茂 14:51:23



啊茂 14:52:07
你猜猜就知道了,1,1是在左上角,那裏肯定是藍色
Huang_Jian肇 14:52:23

Huang_Jian肇 14:52:51
調查色板不是按順序的?

啊茂 14:53:12
不一定的,這個調色板是我自己建的
Huang_Jian肇 14:53:18
1 0000  2 0001  3  0002


Huang_Jian肇 14:53:35


啊茂 14:53:43
最後一個只有0和1的值
Huang_Jian肇 14:54:23
最後一個不是透明度?

啊茂 14:54:29
如果我把一張圖片最多的顏色放在第0位,那麼它查找時,是不是會最快找到呢?
Huang_Jian肇 14:54:38
透明度不是0 - - 255

啊茂 14:54:57
是透明度啊,透明度的取值範圍:0.0 - 1.0
Huang_Jian肇 14:55:04
哇~~這個問題想不到

Huang_Jian肇 14:55:20
O

Huang_Jian肇 14:55:50
好似哪果看過什麼透明可設值在0  --255

啊茂 14:55:50
有些圖片查看器不支持半透明度時,它就只會識別爲0或1
Huang_Jian肇 14:56:07
o,如此

Huang_Jian肇 14:57:19
是哪裏看到png 索引的資料的

啊茂 14:57:57
不記得了
Huang_Jian肇 14:58:09
O

啊茂 14:58:10
不但是PNG的,所以索引圖片都是這個原理
Huang_Jian肇 14:58:30
O

啊茂 14:59:48
像這些圖片的顏色這麼單一,只有三種色:藍、黑、白,你可以嘗試下把調色板只設有三種色,然後修改圖片每個像素的索引值,可能會大大減小圖片體積
啊茂 15:00:28
再按顏色的比例,把藍、白、黑按這樣的順序放到調色板中,圖片讀取將會更快
Huang_Jian肇 15:01:23

Huang_Jian肇 10:37:50
每張圖片都有一個調節版?

Huang_Jian肇 10:37:58
圖片文件

啊茂 10:38:21
其實我又覺得,系統繫有自己既調色板既,如果可以用系統既調色板,甘圖片又會細左D喔,但如果系統既調色板俾改過後,圖片就唔同樣了。。。
啊茂 10:38:23

啊茂 10:40:00
如果你地公司一般都只生成PNG圖片黎用,然後D人設計時用BMP圖片,你應該再瞭解下呢兩種格式既圖片,你問我,我講既可能系錯既
Huang_Jian肇 10:40:02
系統在在畫圖片時一定會用圖片的調色版?

Huang_Jian肇 10:40:25
O

啊茂 10:40:46
圖片相當於一個程序,在執行圖片程序時,圖片指定用乜調色板就用乜調色板,唔系由系統決定既
Huang_Jian肇 10:41:33
for(int i = 0; i<a.length; i++) {
    if(i == inputbig.getRaster().getPixel(10,10, (int[])null)[0]) {
     //0-->a.length(顏色分量長度) 看顏色是否一樣
     a[i] = 0; //透明
    } else {
     a[i] = 1;
    }
   }

Huang_Jian肇 10:41:51
if(i == inputbig.getRaster().getPixel(10,10, (int[])null)[0]) {
     //0-->a.length(顏色分量長度) 看顏色是否一樣
     a[i] = 0; //透明
    } e

Huang_Jian肇 10:42:30
爲什麼這句可以識別出哪裏要透明?

Huang_Jian肇 10:43:19
for(int i = 0; i<a.length; i++) {
在這循環中i,不是由0-->a.length嗎?

Huang_Jian肇 10:44:03
inputbig.getRaster().getPixel(10,10, (int[])null)[0]) 的值在 0 -->a.length 就會是藍色

啊茂 10:45:31
由先,調色板每一個顏色是由r g b a來決定,調色板有多少個顏色,就肯定有多少個a,即是說,調色板的長度和a的長度是完全一樣的,這裏的i既是調色板的索引,也是a的索引
啊茂 10:46:48
那麼,根據i在調色板中找到的顏色,它的alpah值,當然就是在數組a中找到的值啦
啊茂 10:47:06
這個a的數組是調色板中的alpah分量來的
啊茂 10:49:03

Huang_Jian肇 10:49:45
基本明瞭

啊茂 10:49:50
你睇呢張圖,用i在數組a中找到的東西,是不是用i在調色板中找到的顏色是對應的?
啊茂 10:50:02
調色板是由數組r g b a組成的
啊茂 10:51:36
你應該再回頭看看數據結構之類的知識
Huang_Jian肇 10:52:13
嗯,

啊茂 10:52:18
你的大腦對於數據在電腦中是如何存儲的還沒有一個形象的認識
Huang_Jian肇 10:52:45
是哦

啊茂 10:53:25
不過你唔好真系一味花時間來全部看一次,應該系針對你需要解決的問題而有目的既睇
啊茂 10:55:11
你可以先花時間來快速瀏覽一次,記住裏面大概提到有邊D內容,以後遇到問題時,再回憶果本書有無提到相關內容,有既話再回頭認真睇,呢D系我既經驗,所以我一般睇一本書系好快既,當睇目錄甘睇

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章