- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
比起规则抖动,扩散抖动能避免产生规则抖动带来的规则斑点。原理是将像素的误差值扩散到邻近像素。
首先我们看看不经过抖动,只单纯降级为256色的图像,是下面这样的:(严重失真)
经过抖动之后,图像画面好多了。
算法的伪代码如下:- for each y from top to bottom
- for each x from left to right
- oldpixel := pixel[x][y]
- newpixel := find_closest_palette_color(oldpixel)
- pixel[x][y] := newpixel
- quant_error := oldpixel - newpixel
- pixel[x+1][y ] := pixel[x+1][y ] + quant_error * 7/16
- pixel[x-1][y+1] := pixel[x-1][y+1] + quant_error * 3/16
- pixel[x ][y+1] := pixel[x ][y+1] + quant_error * 5/16
- pixel[x+1][y+1] := pixel[x+1][y+1] + quant_error * 1/16
复制代码
说白了就是把误差值往右扩散7/16,往左下扩散3/16,往正下扩散5/16,再往右下扩散1/16。
我用VB实现了一个实例。关键代码:- Private Sub cmdDither1_Click()
- Dim ThisPix As Color_t '当前像素颜色值
- Dim NextPix As Color_t '下一个像素的误差扩散值
- Dim Down3(2) As Color_t '下一行三个像素的误差扩散值
- Dim LinePix() As Color_t '计算好的一整行像素的误差扩散值
- Dim PixErr As Color_t '误差
- Dim LU!, T!
- Dim X&, Y&, C&, I&
- '如果之前运行了算法,先将图片框中的图像恢复
- picSrc.Cls
- '处理图片数据
- ReDim LinePix(picSrc.ScaleWidth - 1)
- For Y = 0 To picSrc.ScaleHeight - 1
- For X = 0 To picSrc.ScaleWidth - 1
- C = picSrc.Point(X, Y) '取当前点颜色值
- '颜色是用3个字节存储RGB通道的,将其拆开为3个Long
- ThisPix.R = (C And &HFF&)
- ThisPix.G = (C And &HFF00&) \ &H100
- ThisPix.B = (C And &HFF0000) \ &H10000
-
- '计算新的颜色值
- ThisPix.R = ThisPix.R + NextPix.R + LinePix(X).R
- ThisPix.G = ThisPix.G + NextPix.G + LinePix(X).G
- ThisPix.B = ThisPix.B + NextPix.B + LinePix(X).B
-
- '取得调色板最接近颜色值
- I = GetNearestCol(ThisPix)
-
- '取得误差值
- PixErr.R = ThisPix.R - Pal(I).R
- PixErr.G = ThisPix.G - Pal(I).G
- PixErr.B = ThisPix.B - Pal(I).B
-
- '向右扩散误差值
- NextPix.R = PixErr.R * 7 \ 16
- NextPix.G = PixErr.G * 7 \ 16
- NextPix.B = PixErr.B * 7 \ 16
-
- '然后将误差值向下扩散
- If X >= 1 Then LinePix(X - 1) = Down3(0)
- Down3(0).R = Down3(1).R + PixErr.R * 3 \ 16
- Down3(0).G = Down3(1).G + PixErr.G * 3 \ 16
- Down3(0).B = Down3(1).B + PixErr.B * 3 \ 16
- Down3(1).R = Down3(2).R + PixErr.R * 5 \ 16
- Down3(1).G = Down3(2).G + PixErr.G * 5 \ 16
- Down3(1).B = Down3(2).B + PixErr.B * 5 \ 16
- Down3(2).R = PixErr.R * 1 \ 16
- Down3(2).G = PixErr.G * 1 \ 16
- Down3(2).B = PixErr.B * 1 \ 16
-
- '显示到图片框
- picSrc.PSet (X, Y), RGB(Pal(I).R, Pal(I).G, Pal(I).B)
- Next
- LinePix(X - 1) = Down3(1)
-
- T = Timer
- If T - LU > 0.1 Then
- LU = T
- If DoEvents = 0 Then Exit For
- End If
- Next
- End Sub
复制代码 附件:Attachment(source code)
扩散抖动算法.rar
(345.51 KB, 下载次数: 36, 售价: 1 个宅币)
名称: 扩散抖动算法.rar
大小: 353807 字节
SHA1: DBDDB08E0B09FCB57979FE75D53CD71DF69A33F8
参考资料:
https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
图片来源:
涼宮ハルヒの憂鬱 第08話 「笹の葉ラプソディ」
第12分09秒时的截图,图中的角色是朝比奈实玖瑠。 |
|