Archive Browser
Download DitheringTest.zip version 1.0.0.0, last updated 06/06/2015 (757.89 KB)
Download- md5: 960d00ff8054b8711bf56c562a141126
/* Dithering an image using the Floyd–Steinberg algorithm in C#
* http://www.cyotek.com/blog/dithering-an-image-using-the-floyd-steinberg-algorithm-in-csharp
*
* Copyright © 2015 Cyotek Ltd.
*
* Licensed under the MIT License. See LICENSE.txt for the full text.
*/
using Cyotek.DitheringTest.Helpers;
namespace Cyotek.DitheringTest.Dithering
{
public sealed class FloydSteinbergDithering : IErrorDiffusion
{
#region IDither Interface
void IErrorDiffusion.Diffuse(ArgbColor[] original, ArgbColor originalPixel, ArgbColor transformedPixel, int x, int y, int width, int height)
{
ArgbColor offsetPixel;
int redError;
int blueError;
int greenError;
int offsetIndex;
int index;
/*
* Floyd-Steinberg Dithering
* http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
*
* Coefficients for dispersing the error (* is the current pixel):
*
* * 7/16
* 3/16 5/16 1/16
*
* As 16 is a power of two, we can use bit shifting to do the
* division which is actually faster than the division operator
*/
index = y * width + x;
redError = originalPixel.R - transformedPixel.R;
blueError = originalPixel.G - transformedPixel.G;
greenError = originalPixel.B - transformedPixel.B;
if (x + 1 < width)
{
// right
offsetIndex = index + 1;
offsetPixel = original[offsetIndex];
offsetPixel.R = (offsetPixel.R + ((redError * 7) >> 4)).ToByte();
offsetPixel.G = (offsetPixel.G + ((greenError * 7) >> 4)).ToByte();
offsetPixel.B = (offsetPixel.B + ((blueError * 7) >> 4)).ToByte();
original[offsetIndex] = offsetPixel;
}
if (y + 1 < height)
{
if (x - 1 > 0)
{
// left and down
offsetIndex = index + width - 1;
offsetPixel = original[offsetIndex];
offsetPixel.R = (offsetPixel.R + ((redError * 3) >> 4)).ToByte();
offsetPixel.G = (offsetPixel.G + ((greenError * 3) >> 4)).ToByte();
offsetPixel.B = (offsetPixel.B + ((blueError * 3) >> 4)).ToByte();
original[offsetIndex] = offsetPixel;
}
// down
offsetIndex = index + width;
offsetPixel = original[offsetIndex];
offsetPixel.R = (offsetPixel.R + ((redError * 5) >> 4)).ToByte();
offsetPixel.G = (offsetPixel.G + ((greenError * 5) >> 4)).ToByte();
offsetPixel.B = (offsetPixel.B + ((blueError * 5) >> 4)).ToByte();
original[offsetIndex] = offsetPixel;
if (x + 1 < width)
{
// right and down
offsetIndex = index + width + 1;
offsetPixel = original[offsetIndex];
offsetPixel.R = (offsetPixel.R + ((redError * 1) >> 4)).ToByte();
offsetPixel.G = (offsetPixel.G + ((greenError * 1) >> 4)).ToByte();
offsetPixel.B = (offsetPixel.B + ((blueError * 1) >> 4)).ToByte();
original[offsetIndex] = offsetPixel;
}
}
}
#endregion
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate