哪里有比较好的算法,把16位的BMP转换成256色的?
只需要在内存里转换,不需要的读写文件。谢谢。
效率不是很重要,主要是稳定,效果好。
问题点数:50、回复次数:7Top
1 楼sjcode(愚者)回复于 2005-04-01 12:18:05 得分 2
如果从256到16,好转,反过来,好像没意义吧Top
2 楼heweixing_77(何足道)回复于 2005-04-01 12:30:25 得分 0
为了传输减少带宽。Top
3 楼vcPlayer(没有星星,努力做太阳!)回复于 2005-04-01 13:57:52 得分 2
first:遍历16位BMP,找出其中最重要的256种颜色;
second:将这些颜色编码成PALETTE;
third:转换点阵数据,将其变成256色的BMP。
接分喽!:)Top
4 楼AthlonxpX86(一坨屎)回复于 2005-04-01 14:10:36 得分 2
256色的话,要用计算调色板的哦,Top
5 楼sxshao(sxshao)回复于 2005-04-02 11:30:03 得分 2
> first:遍历16位BMP,找出其中最重要的256种颜色;
说的简单,做起来效率太低。
MS 照片编辑器就不行,不如 ACDSEE。
Top
6 楼sxshao(sxshao)回复于 2005-04-02 11:30:40 得分 2
调色板计算还是比较复杂的。Top
7 楼AthlonxpX86(一坨屎)回复于 2005-04-03 16:20:36 得分 40
http://asp.6to23.com/iseesoft/devdoc/imgdoc/dit.htm
转载一文章,效果非常不错哦,不过16位色的话可能要改一改,(16位通常是555或 565格式,而不是888)
VCHelp coPathway ISee project
作者: YZ
电邮: yzfree@sina.com
日期: 2004-2-2
真彩RGB图象转256色图象算法的一些探索
-对颤动算法的一些改进
● 背景
先澄清一些名词,下面内容中出现的‘真彩图’是指R、G、B份量各占8位的图象。256色图则是指8位的调色板图象。在真彩图所占比例越来越多的时候,调色板图渐渐的被人淡忘了,但在某些特殊的领域,调色板图仍有很强的生命力。近一段时间因为要改进ISee插件保存调色板图的效果代码,所以对真彩图转256色图的算法进行了一些研究、有了一些结果。我感觉转换后的效果可以与ACDSee转换效果相媲美。
当然,这个算法仍有改进的余地,如果哪位有兴趣可自行改写。
下面是这个算法的效果图,大家可以注意一下腿部渐变色的过渡。
● 代码
如果讲算法原理的话,可能要写一大篇,我想对于那些临时抱佛脚的人来说也没兴趣看。所以原理我就不写了,我想对于研究过颤动算法的人应该可以看懂。下面直接给出函数代码:
unsigned char BayerPattern[8][8]={0,32, 8,40, 2,34,10,42,
48,16,56,24,50,18,58,26,
12,44, 4,36,14,46, 6,38,
60,28,52,20,62,30,54,22,
3,35,11,43, 1,33, 9,41,
51,19,59,27,49,17,57,25,
15,47, 7,39,13,45, 5,37,
63,31,55,23,61,29,53,21};
#define ISPAL_PATTERN_SIZE 64 /* 离散数据最大尺寸 */
#define ISPAL_BEGIN 64 /* 调色板分量起始量 */
#define ISPAL_END 224 /* 调色板分量最高值 */
#define ISPAL_STEP 32 /* 调色板分量间隔 */
/* 创建调色板(调色板是固定内容的)*/
int Creat256Palette(unsigned long *pal)
{
unsigned long r, g, b;
int cnt = 0;
/* 标准调色板 */
for (r=ISPAL_BEGIN; r<256; r+=ISPAL_STEP)
{
for (g=ISPAL_BEGIN; g<256; g+=ISPAL_STEP)
{
for (b=ISPAL_BEGIN; b<256; b+=ISPAL_STEP)
{
pal[cnt++] = b|(g<<8)|(r<<16);
}
}
}
/* 返回调色板使用项个数 */
return cnt;
}
/* 将指定真彩象素转换为调色板索引 */
unsigned long CnvTo256PalIndex(
int x, /* 该象素在图象中的水平位置 */
int y, /* 该象素在图象中的垂直位置 */
unsigned char ucr, /* 象素的R份量 */
unsigned char ucg, /* 象素的G份量 */
unsigned char ucb /* 象素的B份量 */
)
{
unsigned long pix = 0;
if (ucb > ISPAL_BEGIN)
{
ucb = (((ISPAL_PATTERN_SIZE*((unsigned int)ucb%ISPAL_STEP))/ISPAL_STEP) <
BayerPattern[y&7][x&7]) ? ((unsigned int)ucb/ISPAL_STEP)*ISPAL_STEP :
min(((unsigned int)ucb/ISPAL_STEP)*ISPAL_STEP+ISPAL_STEP, ISPAL_END);
}
else
{
ucb = ISPAL_BEGIN;
}
if (ucg > ISPAL_BEGIN)
{
ucg = (((ISPAL_PATTERN_SIZE*((unsigned int)ucg%ISPAL_STEP))/ISPAL_STEP) <
BayerPattern[y&7][x&7]) ? ((unsigned int)ucg/ISPAL_STEP)*ISPAL_STEP :
min(((unsigned int)ucg/ISPAL_STEP)*ISPAL_STEP+ISPAL_STEP, ISPAL_END);
}
else
{
ucg = ISPAL_BEGIN;
}
if (ucr > ISPAL_BEGIN)
{
ucr = (((ISPAL_PATTERN_SIZE*((unsigned int)ucr%ISPAL_STEP))/ISPAL_STEP) <
BayerPattern[y&7][x&7]) ? ((unsigned int)ucr/ISPAL_STEP)*ISPAL_STEP :
min(((unsigned int)ucr/ISPAL_STEP)*ISPAL_STEP+ISPAL_STEP, ISPAL_END);
}
else
{
ucr = ISPAL_BEGIN;
}
pix = ((unsigned long)ucr<<16)|((unsigned long)ucg<<8)|((unsigned long)ucb);
/* 返回该象素在调色板中的索引值 */
return (((pix&0xff)-ISPAL_BEGIN)/ISPAL_STEP)+
(((((pix&0xff00)>>8)-ISPAL_BEGIN)/ISPAL_STEP)*6)+
(((((pix&0xff0000)>>16)-ISPAL_BEGIN)/ISPAL_STEP)*36);
}
● 用法
使用方法很简单,先申请一个256×sizeof(RGBQUAD)字节的内存,然后传入Creat256Palette()函数来创建调色板。然后将图象的所有象素都调用过一次CnvTo256PalIndex()函数,并记录所有的返回值,这样就得到了一幅对应的256色调色板图。
<完>
YZ 2004-2-2日下午2:50
最后修改于 2004-2-2日
Top




