ひきぷろのプログラミング日記

プログラミングの日記です。

(C#) モザイクフィルタを実装してみた

PixelManipulator クラスの実装が不十分なおかげで端っこが塗られませんが、ひとまずモザイク処理はできたのでコードを貼り付けてみます。

using System.Drawing;

class MosaicFilter {
	// 引数で渡されたビットマップ画像にモザイクフィルタを適用します
	public static Bitmap Apply(Bitmap source, int size = 6) {
		// ビットマップ画像から全てのピクセルを抜き出す
		PixelManipulator s = PixelManipulator.LoadBitmap(source);
		PixelManipulator d = s.Clone();

		// 範囲チェック
		if (size < 1) {
			size = 1;
		}
		if (size > 32) {
			size = 32;
		}

		int w = size * 2 + 1;

		// 全てのピクセルを巡回する
		s.EachPixel((x, y) => {
			// 塗り終わったところを飛ばす
			if (x % w != 0 || y % w != 0) {
				return;
			}

			// 周囲のピクセルの平均値で塗りつぶす
			byte r = _SMA(s.RangeR(x, y, size));
			byte g = _SMA(s.RangeG(x, y, size));
			byte b = _SMA(s.RangeB(x, y, size));
			_Fill(d, x, y, size, r, g, b);
		});

		// 新しいビットマップ画像を作成して、ピクセルをセットする
		return d.CreateBitmap();
	}

	// 周囲のピクセルの平均値を出す処理
	private static byte _SMA(byte[,] pixels) {
		int color = 0;
		int size = pixels.GetLength(0);
		for (int y = 0; y < size; y++) {
			for (int x = 0; x < size; x++) {
				color += pixels[x, y];
			}
		}
		color /= size * size;
		return (byte)color;
	}

	// 範囲を塗りつぶす処理
	private static void _Fill(PixelManipulator d, int dx, int dy, int size, byte r, byte g, byte b) {
		for (int y = -size; y <= size; y++) {
			for (int x = -size; x <= size; x++) {
				d.SetPixel(dx + x, dy + y, r, g, b);
			}
		}
	}
}

PixelManipulator クラスは、前の記事で作成しました。
次のリンク先を確認してみてください。

hikipuro.hatenadiary.jp

使い方
// PictureBox に設定された画像へフィルタを適用する場合
Bitmap bitmap = new Bitmap(pictureBox1.Image);
bitmap = MosaicFilter.Apply(bitmap);
pictureBox1.Image = bitmap;