Sphere

This algorithm processes an image creating the effect of the image being wrapped around a ball.

   



									public static void ApplySphere(ref Bitmap bmp)
{
	int bmpWidth = bmp.Width;
	int bmpHeight = bmp.Height;
	int bmpStride = 0;

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

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

	bmpStride = bmpData.Stride;

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

		int stopAddress = (int)ptr + bmpStride * bmpHeight;

		int Val = 0;
		int MidX = bmpWidth / 2;
		int MidY = bmpHeight / 2;
		int i = 0, X = 0, Y = 0;
		int TrueX = 0, TrueY = 0;
		int NewX = 0, NewY = 0;

		double NewRadius = 0;
		double Theta = 0, Radius = 0;

		while ((int)ptr != stopAddress)
		{
			X = i % bmpWidth;
			Y = i / bmpWidth;

			TrueX = X - MidX;
			TrueY = Y - MidY;

			Theta = Math.Atan2(TrueY, TrueX);
			Radius = Math.Sqrt(TrueX * TrueX + TrueY * TrueY);
			NewRadius = Radius * Radius / Math.Max(MidX, MidY);

			NewX = (int)(MidX + (NewRadius * Math.Cos(Theta)));
			NewY = (int)(MidY + (NewRadius * Math.Sin(Theta)));

			if (!(NewY >= 0 && NewY < bmpHeight && NewX >= 0 && NewX < bmpWidth))
				NewX = NewY = 0;

			if (NewY >= 0 && NewY < bmpHeight && NewX >= 0 && NewX < bmpWidth)
			{
				Val = (NewY * bmpStride) + (NewX * 3);

				ptr[0] = TempPtr[Val];
				ptr[1] = TempPtr[Val + 1];
				ptr[2] = TempPtr[Val + 2];
			}

			ptr += 3;
			i++;
		}
	}

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


Example

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