私は C# が初めてで、2 番目のプロジェクトでは、Floyd-Steinberg メソッドを使用してビットマップをディザリングするアルゴリズムを作成しようとしています。Coding Trains Video に従いましたが、RGB 値が範囲外である場所で多くのエラーが発生します。たとえば、値が 256 の場合もあれば、マイナスの場合もあります。
ここにコードの重要な部分があります。
static public Bitmap Imagedither(Bitmap original)
{
for (int y = 0; y < original.Height - 1; y++)
{
for (int x = 1; x < original.Width - 1; x++)
{
Color oldPixel = original.GetPixel(x, y);
Color newPixel = roundColor(oldPixel, 1);
original.SetPixel(x, y, newPixel);
Error error = new Error(oldPixel.R - newPixel.R, oldPixel.G - newPixel.G, oldPixel.B - newPixel.B);
original.SetPixel(x + 1, y , AddError(original.GetPixel(x + 1, y), error, 7 / 16.0));
original.SetPixel(x - 1, y + 1, AddError(original.GetPixel(x - 1, y + 1), error, 3 / 16.0));
original.SetPixel(x , y + 1, AddError(original.GetPixel(x, y + 1), error, 5 / 16.0));
original.SetPixel(x + 1, y + 1, AddError(original.GetPixel(x + 1, y + 1), error, 1 / 16.0));
}
}
return original;
}
static public Color roundColor(Color color, int factor)
{
double R = (double)factor * color.R / 255.0;
double newR = Math.Round(R) * (255 / factor);
double G = (double)factor * color.G / 255.0;
double newG = Math.Round(G) * (255 / factor);
double B = (double)factor * color.B / 255.0;
double newB = Math.Round(B) * (255 / factor);
return Color.FromArgb((int)newR, (int)newG, (int)newB);
}
static public Color AddError(Color pixel, Error error, double amount)
{
int R = (int)(pixel.R + (error.R * amount));
int G = (int)(pixel.G + (error.G * amount));
int B = (int)(pixel.B + (error.B * amount));
return Color.FromArgb(R > 255 ? 255 : R, G > 255 ? 255 : G, B > 255 ? 255 : B);
}
public class Error
{
public double R { get; set; }
public double G { get; set; }
public double B { get; set; }
public Error() { }
public Error(double r, double g, double b)
{
R = r;
G = g;
B = b;
}
}