The result is an elliptical or circular shape that is Vortex-like, depending on the original image.
In general, the processing speed of this code is very slow. If Unsafe code is used, the performance will be greatly improved.
Private void button#click (Object sender, eventargs E)
{
Bitmap image = new Bitmap (@ "C:/dsc_0096_s.jpg ");
Int X, Y;
Float X1, Y1;
Float FX, fy, xmid, ymid, Ar;
Bitmap image2 = new Bitmap (image );
Xmid = (float) (image. width/2.0 );
Ymid = (float) (image. Height/2.0 );
AR = (float) (image. Height)/(float) (image. width );
For (y = 0; y <image. height; y ++)
{
For (x = 0; x <image. width; X ++)
{
Computepixel (AR * (X-xmid), Y-ymid, out FX, out FY );
X1 = xmid + FX/Ar;
Y1 = ymid + FY;
Image2.setpixel (X, Y, getpixelcolorinterpolated (ref image, X1, Y1 ));
}
}
This. picturebox1.image = image2;
}
Static int computepixel (float X, float y, out float X1, out float Y1)
{
Double R, nn;
If (x = 0 & Y = 0)
{
X1 = X;
Y1 = y;
Return 1;
}
Nn = math. SQRT (x * x + y * y );
R = (math. Abs (x)> math. Abs (y ))? Math. Abs (NN/X): Math. Abs (NN/y );
X1 = (float) (R * X );
Y1 = (float) (R * y );
Return 1;
}
Static color getpixelcolorinterpolated (ref bitmap image, float X, float y)
{
Int xi = (INT) (X );
If (x <0) XI --;
Int YI = (INT) (y );
If (Y <0) Yi --;
If (xi <-1 | xi> = image. Width | Yi <-1 | Yi> = image. Height)
{
Return getpixelcolorwithoverflow (ref image,-999,-999 );
}
// Get four neighbouring pixels
If (XI + 1) <image. Width & xi> = 0 & (yi + 1) <image. Height & Yi> = 0)
{
Ushort WT1 = (ushort) (X-xi) * 256.0f), WT2 = (ushort) (Y-yi) * 256.0f );
Ushort WD = (ushort) (WT1 * WT2> 8 );
Ushort WB = (ushort) (WT1-wd );
Ushort WC = (ushort) (WT2-wd );
Ushort WA = (ushort) (256-WT1-WC );
Ushort WRR, WGG, WBB;
Color CLR = image. getpixel (XI, Yi );
WBB = (ushort) (wa * CLR. B );
WGG = (ushort) (wa * CLR. G );
WRR = (ushort) (wa * CLR. R );
CLR = image. getpixel (XI + 1, Yi );
WBB + = (ushort) (WB * CLR. B );
WGG + = (ushort) (WB * CLR. G );
WRR + = (ushort) (WB * CLR. R );
CLR = image. getpixel (XI, yi + 1 );
WBB + = (ushort) (WC * CLR. B );
WGG + = (ushort) (WC * CLR. G );
WRR + = (ushort) (WC * CLR. R );
CLR = image. getpixel (XI + 1, yi + 1 );
WBB + = (ushort) (WD * CLR. B );
WGG + = (ushort) (WD * CLR. G );
WRR + = (ushort) (WD * CLR. R );
Return color. fromargb (255, WRR> 8, WGG> 8, WBB> 8 );
}
Else
{
Float T1 = x-xi, T2 = Y-yi;
Float d = T1 * t2;
Float B = T1-D;
Float c = t2-D;
Float a = 1-T1-C;
Color rgb11, rgb21, rgb12, rgb22;
Rgb11 = getpixelcolorwithoverflow (ref image, XI, Yi );
Rgb21 = getpixelcolorwithoverflow (ref image, Xi + 1, Yi );
Rgb12 = getpixelcolorwithoverflow (ref image, XI, yi + 1 );
Rgb22 = getpixelcolorwithoverflow (ref image, Xi + 1, yi + 1 );
// Calculate linear interpolation
Return color. fromargb (255,
(Byte) (A * rgb11.r + B * rgb21.r + C * rgb12.r + D * rgb22.r ),
(Byte) (A * rgb11.g + B * rgb21.g + C * rgb12.g + D * rgb22.g ),
(Byte) (A * rgb11. B + B * rgb21. B + C * rgb12. B + D * rgb22. B ));
}
}
Static color getpixelcolorwithoverflow (ref bitmap image, long X, long y)
{
If (! Isinside (ref image, x, y ))
{
Return color. fromargb (255,255,255,255 );
}
Return image. getpixel (INT) x, (INT) y );
}
Static bool isinside (ref bitmap image, long X, long y)
{
Return (0 <= Y & Y <image. Height & 0 <= x & x <image. width );
}