半色调
目前半色调技术最普遍的分类法是按照它的处理方式分为:抖动法,误差扩散法,迭代法三大类。
半色调技术可以将一幅真彩图,处理为单色、8色、16色或者256色的图片。针式打印机只打印黑白图片,通过半色调处理的单色图片比直接用二值化处理的单色图,整体视觉效果更好。

Atkinson误差扩散算法
- 24位真彩色图片转换为24位的黑白图片
- 再进行误差扩散处理
Atkinson 算法矩阵:
X 1 1
1 1 1
1
(1/8)
C语言代码实现
//扫描原始图片数据
for (int row = 0; row < height; row++)
{
//3字节 = 一像素
for (int col = 0; col < 3*width; col+=3)
{
int index;
index = row * 3*width + col; //像素起始下标索引
//原始像素值
unsigned char r = data24[index];
unsigned char g = data24[index+1];
unsigned char b = data24[index+2];
//像素转黑白数据,获取转换后的像素
unsigned char n_r, n_g,n_b;
int gPiex = r*0.299 + g*0.587 + b*0.114;
if(gPiex<nThreshold)
{
n_r = 0;
n_g = 0;
n_b = 0;
}
else
{
n_r = 255;
n_g = 255;
n_b = 255;
}
//新像素重置原始像素
data24[index] = n_r;
data24[index+1] = n_g;
data24[index+2] = n_b;
//======开始误差扩散=====
int r_error = r-n_r;
int g_error = g-n_g;
int b_error = b-n_g;
//对应算法矩阵模型
for (int y = 0; y < 3; y++)
{
int offsetY;
offsetY = row + y; //像素行索引 + 矩阵模型行
for (int x = 0; x < 4; x++)
{
int coefficient;
int offsetX;
coefficient = matrix[y][x]; //矩阵系数值
offsetX = col + (x - 2); //像素列索引 + (矩阵列-2)
//误差偏移条件判断
if (coefficient != 0 && offsetX > 0 && offsetX < 3*width && offsetY > 0 && offsetY < height)
{
int offsetIndex = offsetY * 3*width + offsetX; //偏移索引
//获取偏移像素的原始RGB值
unsigned char originalR = data24[offsetIndex];
unsigned char originalG = data24[offsetIndex+1];
unsigned char originalB = data24[offsetIndex+2];
//计算需要调整的RGB
int offsetR = (r_error*coefficient)>>3;
int offsetG = (g_error*coefficient)>>3;
int offsetB = (b_error*coefficient)>>3;
//重置调整过的原始RGB像素值
data24[offsetIndex] = toByte(originalR + offsetR);
data24[offsetIndex+1] = toByte(originalG + offsetG);
data24[offsetIndex+2] = toByte(originalB + offsetB);
}
}
}
}
}
更多扩散算法参考:
http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/