摘 要 该文描述了在vga16色图形模式下显示256色及全彩色图像的抖动算法,并给出了显示bitmap图像的c语言程序。

在编写有关图像显示的软件时,有时为了软件的兼容性和通用性,不得不采用vga标准的图形模式,这就涉及到如何在16色图形模式下显示256色及全彩色图像的问题。解决这一问题有两种方法。一种是采用色彩近似的方法,即根据需要显示的全部颜色,经过寻优来选择16种最具代表性的颜色,每一种颜色都用这16种颜色中最接近的一种来代替。《计算机世界月刊》1994年第1期的《用集群方法进行颜色选择》一文详细描述了该方法。但事实上,该方法仅对于某些理想的情况适用,而对于更普遍的情况,该方法无论从运算速度还是从处理效果来讲,都不可能令人感到满意,因而不宜在实际中运用。另一种方法是被众多商品化软件所广泛采用的抖动技术,其原理是利用多种可见颜色的组合来模拟一种不可见的颜色。目前,关于彩色图像抖动算法的资料不多。笔者通过对灰度图像处理算法及windows环境下一些图像处理软件的剖析,得出了抖动算法的一般原理和实现方法。

一、抖动算法原理

我们知道,在256色及全彩色图像中,每一种颜色均由r、g、b三个颜色分量组成,而每一个分量又一般由一个字节表示。这样,每一个颜色分量可有256级亮度变化。

本算法的关键在于引入亮度矩阵的概念,即采用一个16×16的矩阵来表示每一个颜色分量的亮度值,不同亮度值对应着矩阵的不同排列。矩阵全为0时对应亮度0,全为255时对应亮度255。

当亮度值为l时,亮度矩阵中将有[l255×256]个255及[(1-l255)×256]个0,此时,矩阵的平均亮度值为l'={[l/255×256]×255+[(1-l/255)×256]×0}/256=l这就是说,矩阵的平均亮度正好为颜色分量的实际亮度。

假设某一颜色c的r、g、b三个颜色分量的亮度矩阵分别为:

@@01a04600.gif;公式一@@其中rmn、gmn、bmn(0≤m, n≤15)取值为0或15。

将上述三个矩阵作叠加运算,得@@01a04601.gif;公式二@@其中的cmn为表1中由rmn、gmn、bmn所确定的颜色值。表1为vga16色图形模式下的标准调色板(并非设置模式后的缺省调色板)。显然,cmn只可能为0及9~15之中的一个。由此方法得到的矩阵mc即可视为颜色c的模拟矩阵。由于颜色c的r、g、b三个颜色分量与亮度矩阵

mr、mg、mb有着相等的亮度值,所以矩阵mc从视觉效果上来讲能很好地模拟颜色c。但在显示时,不可能用整个这样的矩阵来替代一个像素点,那将导致整幅图像长宽均变成原图的16倍。实际的做法是:若该像素点距离图像原点的座标为(x,y),则令:

m=y mod 16

n=x mod 16 (1)

此时,可用mc中的颜色cmn来显示该像素。

@@01a04602.gif;表1 16色图形模式标准调色板@@

二、算法实现

1.亮度矩阵的表示

算法中要用到257个16×16的亮度矩阵,如果对每一个都分别表示的话,将占用很大的内存空间(大于64k)。由于亮度矩阵的排列及增长均有一定的规律性,我们只需要采用一个16×16的矩阵即可。该矩阵中256个元素的取值分别为0~255,按一定规律排列。令其为:

@@01a04603.gif;公式三@@亮度为l时的矩阵可由h变化而来,其中@@01a04604.gif;公式四@@2.颜色查找表算法中只用到了颜色0及9~15,我们可以忽略其他项并将有用部分表示为一个三维数组形式的颜色查找表,如表2所示。此时,r, g, b值作为数组下标,取值为0或1。

与之相应,我们将(2)式变为@@01a04605.gif;公式三@@

3.每一像素的显示步骤

①对256色图像,由颜色索引值查颜色映射表获取r、g、b值;对全彩色图像,直接读取r、g、b值;

②根据像素座标(x,y),由(1)式求得m, n;

③根据r、g、b值,由(3)式求得rmn、gmn、bmn;

④由rmn、gmn、bmn查表2得颜色值c;

⑤将像素以颜色c显示于(x,y)处。

本文所附程序用于在16色图形模式下显示256色及全彩色bitmap图像。

关于bitmap图像的格式及读取方法,许多资料均有介绍,这里不再赘述。

该程序由turbo c 2.0及borland c 3.1编译,在386兼容机上运行通过。运行方法为:

show文件名.bmp

@@01a04606.gif;公式三表2 颜色查找表@@事实证明,采用本文所描述的算法,可以得到与许多商品化软件相似的处理速度和处理效果。

源程序:

#include

#include

#include

#include

#define noerror 0

#define errorfileopen1

#define errorfiletype 2

#define errorimagecolor 3

typedef struct tagbitmapfileheader {

unsigned int bftype;

unsigned longbfsize;

unsigned intbfreserved1; unsigned intbfreserved2;

unsigned longbfoffbits;

} bitmapfileheader;

typedef struct tagbitmapinfoheader {

unsigned longbisize;

unsigned long biwidth;

unsigned longbiheight;

unsigned intbiplanes;

unsigned intbibitcount;

unsigned long bicompression;

unsigned long bisizeimage;

unsigned long bixpelspermeter;

unsigned long biypelspermeter;

unsigned long biclrused;

unsigned long biclrimportant;

} bitmapinfoheader;

typedef struct tagrgbquad {

unsigned char rgbblue;

unsigned char rgbgreen;

unsigned charrgbred;

unsigned char rgbreserved;

} rgbquad;

void main(int argc,char *argv[]);int showbmp(char *filename);

int getcolor(unsigned char r,unsigned char g, unsigned char b,int x,int y)

;

void setvideomode(unsigned char mode);

void setpalreg(unsigned char *palreg);

void setdacreg(unsigned char *dacreg, int color, int count);

void putpixel(int x, int y,unsigned char color);

unsigned char palreg[17]= { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};

unsigned char standardpal[48]= {

0, 0, 0, 32, 0, 0, 0,32, 0, 32,32, 0, 0, 0,32, 32, 0,32, 0,32,32, 32,32,

32, 48,48,48, 63, 0, 0, 0,63, 0, 63,63, 0, 0, 0,63, 63, 0,63, 0,63,63, 63,6

3,63,};

unsigned char lightnessmatrix [16][16]= {

{ 0,235,59,219,15,231,55,215,2,232,56,217,12,229,52,213},

{128,64,187,123,143,79,183,119,130,66,184,120,140,76,180,116},

{33,192,16,251,47,207,31,247,34,194,18,248,44,204,28,244},

{161,97,144,80,175,111,159,95,162,98,146,82,172,108,156,92},

{8,225,48,208,5,239,63,223,10,226,50,210,6,236,60,220},

{136,72,176,112,133,69,191,127,138,74,178,114,134,70,188,124},

{41,200,24,240,36,197,20,255,42,202,26,242,38,198,22,252},

{169,105,152,88,164,100,148,84,170,106,154,90,166,102,150,86},

{3,233,57,216,13,228,53,212,1,234,58,218,14,230,54,214},

{131,67,185,121,141,77,181,117,129,65,186,122,142,78,182,118},

{35,195,19,249,45,205,29,245,32,193,17,250,46,206,30,246},

{163,99,147,83,173,109,157,93,160,96,145,81,174,110,158,94},

{11,227,51,211,7,237,61,221,9,224,49,209,4,238,62,222},

{139,75,179,115,135,71,189,125,137,73,177,113,132,68,190,126},

{43,203,27,243,39,199,23,253,40,201,25,241,37,196,21,254},

{171,107,155,91,167,103,151,87,168,104,153,89,165,101,149,85},

};

unsigned char colortable[2][2][2]= {

{{0,12},{10,14}},{{9,13},{11,15}}};

unsigned char colormap[256][3];

void main (int argc, char *argv[])

{

if(argc!=2) {

printf("usage:\n\tshow filename.bmp\n");

exit(1);

}

showbmp(argv[1]);

}

int showbmp(char *filename)

{

file *fp;

bitmapfileheader filehead;

bitmapinfoheader infohead;

rgbquad rgb;

int n, w,y,x,c,color;

unsigned char buffer[4096];

if (!(fp=fopen(filename,"rb")))

return(errorfileopen);

fread(&filehead,siazeof(bitmapfileheader),1,fp);

if(filehead.bftype!='bm')

return(errorfiletype);

fread(&infohead,sizeof(bitmapfileheader),1,fp);

if(infohead.bibitcount!=8 && infohead.bibitcount!=24) {

fclose(fp);

return(errorimagecolor);

}

setvideomode(0x12);

setpalreg(palreg);

setdacreg(standardpa1,0,16);

if(infohead.bibitcount==8) {

for (n=0;n<256;n++) {

fread(&rgb, sizeof(rgbquad),1,fp);

colormap[n][0]=rgb.rgbred;

colormap[n][1]=rgb.rgbgreen;

colormap[n][2]=rgb.rgbblue;

}

w=(infohead.biwidth+3)/4*4;

for(y=infohead.biheight-1;y>=480;y--)

fread(buffer,sizeof(unsigned char),w,fp);

for(;y>0;y--) {

fread(buffer, sizeof(unsigned char),w,fp);

for (x=0;x

c=buffer[x];

color=getcolor(color

map[c][0],colormap[c][1],c

olormap[c][2],x,y);

putpixel (x,y,color);

}

}

}

else {

w=(infohead.biwidth*3+3)/4*4;

for(y=infohead.biheight-1;y>639;y--)

fread(buffer,sizeof(unsigned char),w,fp);

for(;y>=0;y--) {

fread(buffer,sizeof(unsigned char),w,fp);

for (x=0;x

c=x*3;

color=getcolor(buffer[c+2],buffer[c+1],buffer[

c],x,y);

putpixel(x,y,color);

}

}

}

getch();

fclose(fp);

setvideomode(0x03);

return(noerror);

}

int getcolor(unsigned char r, unsigned char g,unsigned char b, int x,

int y){

unsigned int l=lightnessmatrix[y & 0x0f][x & 0x0f];

return(colortable[(

unsigned int)r*256/255>l][(

unsigned int)g*256/255>l][(

unsigned int)b*256/255>l]);}

void setvideomode(unsigned char mode){

-h=0x00;

-al=mode;

geninterrupt(0x10);

}

voidsetpalreg(unsigned char *palreg){

-es=fp-seg((unsigned char far*)palreg);

-dx=fp-off((unsigned char far*)palreg;

-ax=0x1002;

geninterrupt(0x10);

}

void setdacreg(unsigned char *dacreg,int color,int count){

-es=fp-seg((unsigned char far*)dacreg);

-dx=fp-off((unsigned char far*)dacreg);

-ax=0x1012;

-bx=color;

-cx=count;

geninterrupt(0x10);

}

void putpixel(int x, int y, unsigned charcolor){

-ah=0x0c;

-al=color;

-cx=x;

-dx=y;

geninterrupt(0x10);

}

}

参考文献马建波.c语言图像处理程序集.北京:海洋出版社,1992.

基于c语言256色转16色,在16色模式下显示256色及全彩色相关推荐

  1. 显示 256 色的位图

    问题 显示位图似乎相当简单.在应用程序的资源中添加一张漂亮的位图,使用函数 LoadBitmap 将位图装 入内存,然后将位图选入设备描述表,再使用函数 BitBlt 便可显示出位图.但是这样显示的位 ...

  2. R语言ggplot2可视化密度图(density plot)、改变密度图下的填充色实战

    R语言ggplot2可视化密度图(density plot).改变密度图下的填充色实战 目录 R语言ggplot2可视化密度图(density plot).改变密度图下的填充色实战

  3. R语言使用ggplot2包使用geom_violin函数绘制分组小提琴图(配置填充色)实战

    R语言使用ggplot2包使用geom_violin函数绘制分组小提琴图(配置填充色)实战 目录

  4. R语言ggplot2可视化自定义图例实战:添加自定义的图例、添加填充色的图例

    R语言ggplot2可视化自定义图例实战:添加自定义的图例.添加填充色的图例 目录

  5. dsp课程设计c语言源码,DSP课程设计-基于C语言实现256点的FFT精选.pdf

    DSP课程设计-基于C语言实现256点的FFT精选 XX 大学 J1111111 UNIVERSITY DSP 课 程 设 计 基于CCS 的FFT 算法的C 语言实现和验证 学院名称: 专业班级: ...

  6. 【githubshare】基于 C 语言编写的一款 2D 太空射击游戏,已在 Windows 10 和 Ubuntu Linux 16.04 系统上跑通测试

    基于 C 语言编写的一款 2D 太空射击游戏:space-shooter.c,已在 Windows 10 和 Ubuntu Linux 16.04 系统上跑通测试. GitHub:github.com ...

  7. C语言五子棋禁手算法的编写,基于C语言的五子棋辅助软件的设计与实现.doc

    基于C语言的五子棋辅助软件的设计与实现 广东工业大学 本科毕业设计(论文) 基于C语言的五子棋辅助软件的设计与实现 系 部 专 业 年 级 班级名称 学 号 学生姓名 指导教师 2012 年 5 月 ...

  8. python写web自动化_Web接口开发与自动化测试——基于Python语言

    目 录∣ V 目 录 第1 章 Python 学习必知 ........................................................................ ...

  9. 基于C语言Ncurse库和链表的简单贪吃蛇小游戏

    参考:基于C语言Ncurse库和链表的简单贪吃蛇小游戏 作者:三速何时sub20 发布时间:2020-09-29 10:23:51 网址:https://blog.csdn.net/weixin_44 ...

最新文章

  1. 【OpenCV】图片操作小结:RAW图转image以及image连续保存
  2. 把用户体验设计放到底层逻辑架构设计的前面去做
  3. 汇编语言笔记10-CALL和RET指令
  4. django_rest_framework之解析器、渲染器
  5. 【网络安全】Xred蠕虫再分析及修复工具编写
  6. 黑马Java架构师实战训练学习手册
  7. 一致 先验分布 后验分布_分布式事务常见解决方案与最终一致性
  8. java 注解学习_JAVA注解学习
  9. (转)windows身份验证登入数据库 iis 无法访问数据库
  10. 菠萝在线完成数千万元A轮融资,盛力投资领投
  11. java之SpringMVC的controller配置总结
  12. 天猫运动户外狂欢日来了!700多个大牌要如何回馈消费者
  13. 浅谈从一维空间到十一维空间
  14. 2021WSB-day2-4: Raffaele教授演示利用OpenCV和Python实现一个指纹识别系统 (含代码) part6
  15. tyvj P1179 飘飘乎居士数列游戏
  16. 方框加对勾怎么输入_word里如何往方框中加对号?带方框的对号怎么弄,原来是这样的...
  17. 爬虫如何爬取猫眼电影TOP榜数据
  18. 新瑞鹏“狂飙”,宠物医疗是门好生意吗?
  19. mysql sql日期截取年月日_sql截取日期/时间的单独部分,比如年、月、日、小时、分钟等等...
  20. EDA软件—Cadence学习笔记分享(内含安装教程)

热门文章

  1. LeetCode160.相交链表
  2. Extmail修改模板
  3. nodejs 前端生成csv 直接下载记录
  4. html5 u3m8,U3M8短语.doc
  5. 北京华为HCIE认证网络工程师快速完成设备流量控制和风暴控制
  6. ESP32外壳设计 云图三维:在线SOLIDWORKS 教程
  7. SQL语言和T-SQL语言简介
  8. dinic 最大流费用流模板
  9. SQL必知必会挑战题答案
  10. 不看好Twitter广告模式