
抖动意味着当以低分辨率观看高分辨率图像并在低色模式下显示更多颜色模式时(例如在VGA16×××形状模式下显示256色和全色×××图像)颜色和图像失真的发生.
解决此问题的算法是抖动算法. 以下是这方面的文字,对您有帮助.
在16色模式下显示256色和全色
本文介绍了在VGA 16×××形状模式下显示256色和全色×××图像的抖动算法,并提供了用于显示BitMap图像的C语言程序.
关键字抖动算法亮度矩阵显示
在编写与图像显示相关的软件时,有时为了软件的兼容性和性,必须采用VGA标准图形模式,该模式涉及如何在16×××形状模式下显示256色和全色× ××图像问题. 有两种方法可以解决此问题. 一种是颜色逼近的方法,即根据需要显示的所有颜色,通过优化选择16种最具代表性的颜色,然后将每种颜色替换为这16种颜色中最接近的一种. 《计算机世界月刊》 1994年第1期“用于颜色选择的群集方法”一文详细介绍了该方法. 但实际上,该方法仅适用于一些理想情况,对于更一般的情况,该方法在操作速度或处理效果上均不能令人满意,因此不适合实际应用. 另一种方法是许多商业软件广泛采用的抖动技术. 其原理是使用多种可见颜色的组合来模拟不可见颜色. 目前,关于色彩抖动算法的信息还很少. 通过对Windows环境下的灰度图像处理算法和一些图像处理软件的分析,得出了抖动算法的一般原理和实现方法.
首先,抖动算法的原理
我们知道,在256色和全色XX图像中,每种颜色都由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;公式4 @@
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兼容计算机上运行. 运行方法是: 显示文件名.BMP
@@ 01A04606.GIF;公式3表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;
未签名的intbiPlanes;
unsigned intbiBitCount;
unsigned long biCompression;
无符号长biSizeImage;
未签名的长biXPelsPerMeter;
unsigned long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
未签名的char rgbGreen;
未签名的charrgbRed;
unsigned char rgbReserved;
} RGBQUAD;
void main(int argc,char * argv []);
int ShowBmp(char * FileName);
int GetColor(无符号字符R,无符号字符G,无符号字符B,int X,int Y)
;
void SetVideoMode(无符号字符模式);
void SetPalReg(无符号char * palReg);
void SetDacReg(无符号字符* DacReg,整数颜色图像抖动算法,整数计数);
void PutPixel(int X,int Y,无符号字符颜色);
unsigned char PalReg [17] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
无符号字符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,};
无符号字符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},
};
无符号字符ColorTable [2] [2] [2] = {
{{0,12},{10,14}},{{9,13},{11,15}}};
未签名的char ColorMap [256] [3];
void main(int argc,char * argv [])
{
if(argc!= 2){
printf(“用法: \ n \ tSHOW Filename.BMP \ n”);
退出(1);
}
ShowBmp(argv [1]);
}
int ShowBmp(字符*文件名)
{
文件* Fp;
BITMAPFILEHEADER FileHead;
BITMAPINFOHEADER InfoHead;
RGBQUAD RGB;
int N,W,Y,X,C,颜色;
无符号字符缓冲区[4096];
if(!(Fp = fopen(FileName,“ rb”)))
返回(ErrorFileOpen);
fread(&FileHead,siazeof(BITMAPFILEHEADER),1,Fp);

如果(FileHead.bfType!='BM')
返回(ErrorFileType);
fread(&InfoHead,sizeof(BITMAPFILEHEADER),1,Fp);
如果(InfoHead.biBitcount!= 8 && InfoHead.biBitCount!= 24){
fclose(Fp);
返回(ErrorImageColor);
}
SetVideoMode(0x12);
SetPalReg(PalReg);
SetDacReg(StandardPa1,0,16);
如果(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;
对于(Y = InfoHead.biHeight-1; Y> = 480; Y-)
fread(缓冲区,sizeof(无符号字符),W,Fp);
for(; Y> 0; Y--){
fread(缓冲区,sizeof(无符号字符),w,FP);
for(X = 0; X C =缓冲区[X]; Color = GetColor(ColorMap [C] [0],ColorMap [C] [1],C olorMap [C] [2],X,Y); PutPixel(X,Y,彩色); } } } 其他{ W =(infoHead.biWidth * 3 + 3)/ 4 * 4; 对于(Y = InfoHead.biHeight-1; Y> 639; Y-) fread(缓冲区,sizeof(无符号字符),W,Fp); for(; Y> = 0; Y--){ fread(缓冲区,sizeof(无符号字符),W,Fp); for(X = 0; X C = X * 3; Color = GetColor(缓冲区[C + 2],缓冲区[C +1],缓冲区[ C],X,Y); PutPixel(X,Y,彩色); } } } getch(); fclose(Fp); SetVideoMode(0x03); 返回(NoError); } int GetColor(无符号字符R,无符号字符G,无符号字符B,整数X, int Y){ unsigned int L = LightnessMatrix [Y&0x0F] [X&0x0F]; 返回(colorTable [( unsigned int)R * 256/255> L] [( unsigned int)G * 256/255> L] [( unsigned int)B * 256/255> L]);} void SetVideoMode(无符号字符模式){ -H = 0x00; -AL =模式; geninterrupt(0x10); } voidSetPalReg(无符号字符* PalReg){ -ES = FP-SEG((unsigned char far *)PalReg); -DX = FP-OFF((unsigned char far *)PalReg; -AX = 0x1002; geninterrupt(0x10); } void SetDacReg(无符号字符* DacReg,int颜色,int计数){ -ES = FP-SEG((unsigned char far *)DacReg); -DX = FP-OFF((unsigned char far *)DacReg); -AX = 0x1012; -BX =颜色; -CX =计数; geninterrupt(0x10); } void PutPixel(整数X,整数Y,无符号charColor){ -AH = 0x0C; -AL =颜色; -CX = X; -DX = Y; geninterrupt(0x10); } }
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-193435-1.html
人家那演双簧
马云个数学都考不及格的主儿随便说几句话那么就当回事来听