茂说 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系我既经验,所以我一般睇一本书系好快既,当睇目录甘睇

 

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