#!/usr/bin/env python
""" Floyd-Steinberg Dithering algorithm, see:
http://en.wikipedia.org/wiki/Floyd-Steinberg
"""
import sys
import os
from math import sqrt
from Numeric import *
fs_coeffs = [7.0,3.0,5.0,1.0]
class Dither:
def __init__(self,pixels,xl,yl):
self.pixels = pixels
self.xl = xl
self.yl = yl
self.fs_dither()
def _find_closest_palette_color(self, oldpixel):
return int(oldpixel + 0.5)
def fs_dither(self):
A,B,G,S = map(lambda x : float(x)/16.0, fs_coeffs)
for y in xrange(self.yl):
for x in xrange(self.xl):
oldpixel = self.pixels[x][y]
newpixel = self._find_closest_palette_color(oldpixel)
self.pixels[x][y] = float(newpixel)
quant_error = float(oldpixel - newpixel)
if (x < self.xl - 1):
self.pixels[x+1][y] += (A * quant_error)
if (x > 0) and (y < self.yl - 1):
self.pixels[x-1][y+1] += (B * quant_error)
if (y < self.yl - 1):
self.pixels[x][y+1] += (G * quant_error)
if (x < self.xl - 1) and (y < self.yl - 1):
self.pixels[x+1][y+1] += (S * quant_error)
if __name__=='__main__':
""" Form an xl-by-yl array """
xl = yl = 20
initpixels = reshape((0.5,) * xl * yl ,[xl,yl])
""" Dither """
D = Dither(initpixels,xl,yl)
print D.pixels
""" Import the R stats package libraries
and create a matrix of the dither pixels
"""
import rpy as R
z_lst = []
[z_lst.extend(i) for i in D.pixels]
z = R.r.matrix(z_lst, byrow=R.r.FALSE, ncol=xl)
""" Create a plot of the dithered image """
R.r.pdf("dither_plot.pdf")
R.r.image(range(xl),range(yl),z)
R.r.dev_off()