Emboss Laplacian

This is an image processing algorithm in which in which each pixel of an image is replaced either by a highlight or a shadow, depending on light/dark boundaries on the original image.

   



									class ConvolutionMatrix
{
	public ConvolutionMatrix()
	{
		Pixel = 1;
		Factor = 1;
	}

	public void Apply(int Val)
	{
		TopLeft = TopMid = TopRight = MidLeft = MidRight = BottomLeft = BottomMid = BottomRight = Pixel = Val;
	}

	public int TopLeft { get; set; }

	public int TopMid { get; set; }

	public int TopRight { get; set; }

	public int MidLeft { get; set; }

	public int MidRight { get; set; }

	public int BottomLeft { get; set; }

	public int BottomMid { get; set; }

	public int BottomRight { get; set; }

	public int Pixel { get; set; }

	public int Factor { get; set; }

	public int Offset { get; set; }
}

class Convolution
{
	public void Convolution3x3(ref Bitmap bmp)
	{
		int Factor = Matrix.Factor;

		if (Factor == 0) return;

		int TopLeft = Matrix.TopLeft;
		int TopMid = Matrix.TopMid;
		int TopRight = Matrix.TopRight;
		int MidLeft = Matrix.MidLeft;
		int MidRight = Matrix.MidRight;
		int BottomLeft = Matrix.BottomLeft;
		int BottomMid = Matrix.BottomMid;
		int BottomRight = Matrix.BottomRight;
		int Pixel = Matrix.Pixel;
		int Offset = Matrix.Offset;

		Bitmap TempBmp = (Bitmap)bmp.Clone();

		BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
		BitmapData TempBmpData = TempBmp.LockBits(new Rectangle(0, 0, TempBmp.Width, TempBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

		unsafe
		{
			byte* ptr = (byte*)bmpData.Scan0.ToPointer();
			byte* TempPtr = (byte*)TempBmpData.Scan0.ToPointer();

			int Pix = 0;
			int Stride = bmpData.Stride;
			int DoubleStride = Stride * 2;
			int Width = bmp.Width - 2;
			int Height = bmp.Height - 2;
			int stopAddress = (int)ptr + bmpData.Stride * bmpData.Height;

			for (int y = 0; y < Height; ++y)
				for (int x = 0; x < Width; ++x)
				{
					Pix = (((((TempPtr[2] * TopLeft) + (TempPtr[5] * TopMid) + (TempPtr[8] * TopRight)) +
					  ((TempPtr[2 + Stride] * MidLeft) + (TempPtr[5 + Stride] * Pixel) + (TempPtr[8 + Stride] * MidRight)) +
					  ((TempPtr[2 + DoubleStride] * BottomLeft) + (TempPtr[5 + DoubleStride] * BottomMid) + (TempPtr[8 + DoubleStride] * BottomRight))) / Factor) + Offset);

					if (Pix < 0) Pix = 0;
					else if (Pix > 255) Pix = 255;

					ptr[5 + Stride] = (byte)Pix;

					Pix = (((((TempPtr[1] * TopLeft) + (TempPtr[4] * TopMid) + (TempPtr[7] * TopRight)) +
						  ((TempPtr[1 + Stride] * MidLeft) + (TempPtr[4 + Stride] * Pixel) + (TempPtr[7 + Stride] * MidRight)) +
						  ((TempPtr[1 + DoubleStride] * BottomLeft) + (TempPtr[4 + DoubleStride] * BottomMid) + (TempPtr[7 + DoubleStride] * BottomRight))) / Factor) + Offset);

					if (Pix < 0) Pix = 0;
					else if (Pix > 255) Pix = 255;

					ptr[4 + Stride] = (byte)Pix;

					Pix = (((((TempPtr[0] * TopLeft) + (TempPtr[3] * TopMid) + (TempPtr[6] * TopRight)) +
						  ((TempPtr[0 + Stride] * MidLeft) + (TempPtr[3 + Stride] * Pixel) + (TempPtr[6 + Stride] * MidRight)) +
						  ((TempPtr[0 + DoubleStride] * BottomLeft) + (TempPtr[3 + DoubleStride] * BottomMid) + (TempPtr[6 + DoubleStride] * BottomRight))) / Factor) + Offset);

					if (Pix < 0) Pix = 0;
					else if (Pix > 255) Pix = 255;

					ptr[3 + Stride] = (byte)Pix;

					ptr += 3;
					TempPtr += 3;
				}
		}

		bmp.UnlockBits(bmpData);
		TempBmp.UnlockBits(TempBmpData);
	}

	public ConvolutionMatrix Matrix { get; set; }
}

public static void ApplyEmbossLaplacian(ref Bitmap bmp)
{
	ConvolutionMatrix m = new ConvolutionMatrix();
	m.Apply(-1);
	m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0;
	m.Pixel = 4;
	m.Offset = 127;

	Convolution C = new Convolution();
	C.Matrix = m;
	C.Convolution3x3(ref bmp);
}
								


Example

									Bitmap b = (Bitmap)Image.FromFile("rose.jpg");
ApplyEmbossLaplacian(ref b);