技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2011|回复: 0
收起左侧

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

[复制链接]

995

主题

2207

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16463 个
贡献
32446 次
宅之契约
0 份
在线时间
1565 小时
注册时间
2014-1-26
发表于 2016-7-16 00:26:53 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

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

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

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

算法的伪代码如下:
  1. for each y from top to bottom
  2.         for each x from left to right
  3.                 oldpixel  := pixel[x][y]
  4.                 newpixel  := find_closest_palette_color(oldpixel)
  5.                 pixel[x][y]  := newpixel
  6.                 quant_error  := oldpixel - newpixel
  7.                 pixel[x+1][y  ] := pixel[x+1][y  ] + quant_error * 7/16
  8.                 pixel[x-1][y+1] := pixel[x-1][y+1] + quant_error * 3/16
  9.                 pixel[x  ][y+1] := pixel[x  ][y+1] + quant_error * 5/16
  10.                 pixel[x+1][y+1] := pixel[x+1][y+1] + quant_error * 1/16
复制代码


说白了就是把误差值往右扩散7/16,往左下扩散3/16,往正下扩散5/16,再往右下扩散1/16。
我用VB实现了一个实例。关键代码:
[Visual Basic] 纯文本查看 复制代码
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, 下载次数: 10, 售价: 1 个宅币)

本帖被以下淘专辑推荐:

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-9-24 07:46 , Processed in 0.114792 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表