2010-12-14 27 views
4

我正在更新几个月前制作的Paint.net插件,它被称为模拟颜色深度,它将图像中的颜色数量减少到所选的BPP,并且很长一段时间它已经具有包括抖动,但从未订购抖动,我认为这将是一个很好的补充,所以我开始在互联网上搜索一些有用的东西,我结束了在这里的维基页面http://en.wikipedia.org/wiki/Ordered_dithering,并试图做的写在伪代码Bayer Ordered Dithering

for (int y = 0; x < image.Height; y++) 
{ 
    for (int x = 0; x < image.Width; x++) 
    { 
     Color color = image.GetPixel(x, y); 
     color.R = color.R + bayer8x8[x % 8, y % 8]; 
     color.G = color.G + bayer8x8[x % 8, y % 8]; 
     color.B = color.B + bayer8x8[x % 8, y % 8]; 
     image.SetPixel(x, y, GetClosestColor(color, bitdepth); 
    } 
} 

但结果是太亮,所以我决定再次检查wiki页面,然后我看到有一个“1/65”的门槛地图这让我想到两个错误的权利扩散(是的,我知道,奇怪吧?),并将我从bayer8x8[x % 8, y % 8]得到的值与65相乘,然后将该值与颜色通道相乘,但是结果很乱或者仍然太亮(因为我记得它),但结果与我无关在其他地方看过,无论是太亮,太高对比度还是太乱,我还没有发现任何通过互联网搜索真正有用的东西,所以有谁知道我可以如何让这个拜耳抖动正常工作?

由于提前,饼干

+0

你有问题吗? – dtb 2010-12-14 16:23:44

+0

woops,在写其他东西时忘了它:S – 2010-12-14 17:39:07

+1

这不能回答你的问题,但数字半色调(http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=4433)可能是一个很好的资源来咨询。本教材是维基百科文章中大部分材料的父母参考资料。 – 2010-12-14 17:49:59

回答

1

试试这个:

color.R = color.R + bayer8x8[x % 8, y % 8] * GAP/65; 

这里GAP应该是两个最接近的颜色阈值之间的距离。这取决于每个像素的位数。

例如,如果要将图像转换为每个像素的红色分量使用4位,则共有16级红色总数。它们是:R = 0,R = 17,R = 34,... R = 255。所以GAP将是17.

+0

我试过了,结果只有在高BPP得到更好,如果它低BPP结果太亮,但如果我编辑它可能工作,生病让你知道 – 2010-12-15 06:56:45

1

找到了一个解决方案,levels是目标图像应该有的颜色数量和d是除数(这是从我的代码(它使用paint.net类)到简单的位图编辑GetPixel和SetPixel)

private void ProcessDither(int levels, int d, Bitmap image) 
    { 
     levels -= 1; 
     double scale = (1.0/255d); 
     int t, l; 

     for (int y = rect.Top; y < rect.Bottom; y++) 
     { 
      for (int x = rect.Left; x < rect.Right; x++) 
      { 
       Color cp = image.GetPixel(x, y); 

       int threshold = matrix[y % rows][x % cols]; 

       t = (int)(scale * cp.R * (levels * d + 1)); 
       l = t/d; 
       t = t - l * d; 
       cp.R = Clamp(((l + (t >= threshold ? 1 : 0)) * 255/levels)); 

       t = (int)(scale * cp.G * (levels * d + 1)); 
       l = t/d; 
       t = t - l * d; 
       cp.G = Clamp(((l + (t >= threshold ? 1 : 0)) * 255/levels)); 

       t = (int)(scale * cp.B * (levels * d + 1)); 
       l = t/d; 
       t = t - l * d; 
       cp.B = Clamp(((l + (t >= threshold ? 1 : 0)) * 255/levels)); 

       image.SetPixel(x, y, cp); 
      } 
     } 
    } 

    private byte Clamp(int val) 
    { 
     return (byte)(val < 0 ? 0 : val > 255 ? 255 : val); 
    } 
+1

但是,尽管听起来俗套,什么是矩阵?什么是生成矩阵的好算法? – 2012-01-03 13:16:07

5

我不认为你的原始算法(来自维基百科)有什么问题。亮度差异可能是监视器伽马的伪像。检查Joel Yliluoma's Positional Dithering Algorithm,附录关于伽马校正从这篇文章中关于由Joel Yliluoma(http://bisqwit.iki.fi/story/howto/dither/jy/#Appendix%201GammaCorrection)发明的抖动算法以查看效果的解释(注意:页面相当图形重)。

顺便说一句,也许是本文介绍的(显然是公共领域)算法可以解决你的问题......