0xAA55 发表于 2016-7-16 00:26:53

【VB】简单扩散抖动算法实例(附源码)(Floyd–Steinberg dithering Demo, download)

比起规则抖动,扩散抖动能避免产生规则抖动带来的规则斑点。原理是将像素的误差值扩散到邻近像素。

首先我们看看不经过抖动,只单纯降级为256色的图像,是下面这样的:(严重失真)


经过抖动之后,图像画面好多了。


算法的伪代码如下:for each y from top to bottom
        for each x from left to right
                oldpixel:= pixel
                newpixel:= find_closest_palette_color(oldpixel)
                pixel:= newpixel
                quant_error:= oldpixel - newpixel
                pixel := pixel + quant_error * 7/16
                pixel := pixel + quant_error * 3/16
                pixel := pixel + quant_error * 5/16
                pixel := pixel + 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
大小: 353807 字节
SHA1: DBDDB08E0B09FCB57979FE75D53CD71DF69A33F8

参考资料:
https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering

图片来源:
涼宮ハルヒの憂鬱 第08話 「笹の葉ラプソディ」
第12分09秒时的截图,图中的角色是朝比奈实玖瑠。

Ink_Hin_fifteen 发表于 2019-5-10 20:38:22

参考资料地址已经打不开了,收藏一下,这是通用的吗?

0xAA55 发表于 2019-5-11 09:59:22

Ink_Hin_fifteen 发表于 2019-5-10 20:38
参考资料地址已经打不开了,收藏一下,这是通用的吗?

参考资料我依然能打开,请学会科学上网。

另外,我不知道你说的通用是哪方面。

gujin163 发表于 2024-4-8 09:59:41

终于找到了,多谢分享 +++
页: [1]
查看完整版本: 【VB】简单扩散抖动算法实例(附源码)(Floyd–Steinberg dithering Demo, download)