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);