public static void gradient(ref ColorFloatImage image, float sigma) { ColorFloatImage tempImg = new ColorFloatImage(image.Width, image.Height); int n = (int)(6 * Math.Abs(sigma) + 1); n = n == 1 || n % 2 == 0 ? 3 : n; float[,] matrX = new float[n, n], matrY = new float[n, n]; float normValueX = 0, normValueY = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { matrX[i, j] = (-(i - (n - 1) / 2) / (sigma * sigma)) * (float)Math.Exp(-((i - (n - 1) / 2) * (i - (n - 1) / 2) + (j - (n - 1) / 2) * (j - (n - 1) / 2)) / (2 * sigma * sigma)); normValueX += Math.Abs(matrX[i, j]); matrY[i, j] = (-(j - (n - 1) / 2) / (sigma * sigma)) * (float)Math.Exp(-((i - (n - 1) / 2) * (i - (n - 1) / 2) + (j - (n - 1) / 2) * (j - (n - 1) / 2)) / (2 * sigma * sigma)); normValueY += Math.Abs(matrY[i, j]); } } for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { tempImg[x, y] = ColorFloatPixel.Pow(ColorFloatPixel.Pow(Conv(image, x, y, matrX, normValueX), 2.0f) + ColorFloatPixel.Pow(Conv(image, x, y, matrY, normValueY), 2.0f), 0.5f); //tempImg[x, y] = (float)Math.Pow(Math.Pow(Conv(image, x, y, matrX, normValueX),2.0f) + Math.Pow(Conv(image, x, y, matrY, normValueY), 2.0f), 0.5f); } } image = tempImg; }
GaborConversion(ColorFloatImage image, int x, int y, float[,] matr, float normValue) { ColorFloatPixel tempPixel = image[x, y]; tempPixel.r = 0; tempPixel.g = 0; tempPixel.b = 0; int n = matr.GetLength(0); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { tempPixel.r += matr[j, i] * image[((x + i - (n - 1) / 2) < 0 || (x + i - (n - 1) / 2) >= image.Width ? x : (x + i - (n - 1) / 2)), ((y + j - (n - 1) / 2) < 0 || (y + j - (n - 1) / 2) >= image.Height ? y : (y + j - (n - 1) / 2))].r; tempPixel.g += matr[j, i] * image[((x + i - (n - 1) / 2) < 0 || (x + i - (n - 1) / 2) >= image.Width ? x : (x + i - (n - 1) / 2)), ((y + j - (n - 1) / 2) < 0 || (y + j - (n - 1) / 2) >= image.Height ? y : (y + j - (n - 1) / 2))].g; tempPixel.b += matr[j, i] * image[((x + i - (n - 1) / 2) < 0 || (x + i - (n - 1) / 2) >= image.Width ? x : (x + i - (n - 1) / 2)), ((y + j - (n - 1) / 2) < 0 || (y + j - (n - 1) / 2) >= image.Height ? y : (y + j - (n - 1) / 2))].b; } } tempPixel.r = tempPixel.r / normValue; tempPixel.g = tempPixel.g / normValue; tempPixel.b = tempPixel.b / normValue; return(tempPixel); }
public static ColorFloatImage Median(ColorFloatImage image, int rad) //todo rewrite { ColorFloatImage dest = new ColorFloatImage(image.Width, image.Height); int flag_i = 1, flag_j = 1; int flag_ni = 0, flag_nj = 0; for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { float[] red = new float[(2 * rad + 1) * (2 * rad + 1)]; float[] green = new float[(2 * rad + 1) * (2 * rad + 1)]; float[] blue = new float[(2 * rad + 1) * (2 * rad + 1)]; int counter = 0; for (int i = y - rad; i <= y + rad; i++) { for (int j = x - rad; j <= x + rad; j++) { if (i < 0) { flag_i = 0; } if (j < 0) { flag_j = 0; } if (i > image.Height - 1) { flag_ni = i - image.Height + 1; } if (j > image.Width - 1) { flag_nj = j - image.Width + 1; } red[counter] = image[j * flag_j - flag_nj, i *flag_i - flag_ni].r; green[counter] = image[j * flag_j - flag_nj, i *flag_i - flag_ni].g; blue[counter] = image[j * flag_j - flag_nj, i *flag_i - flag_ni].b; ++counter; flag_i = 1; flag_j = 1; flag_ni = 0; flag_nj = 0; } } Array.Sort(red); Array.Sort(green); Array.Sort(blue); dest[x, y] = new ColorFloatPixel(blue[2 * rad * (rad - 1)], green[2 * rad * (rad - 1)], red[2 * rad * (rad - 1)], image[x, y].a); } } return(dest); }
static ColorFloatImage median(ColorFloatImage image, int rad) { if (rad <= 0) { Console.WriteLine("Radius must be positive amount of pixels"); return(image); } int window_size = 2 * rad + 1; ColorFloatImage out_img = new ColorFloatImage(image.Width, image.Height); for (int y = 0; y < image.Height - 1; y++) { for (int x = 0; x < image.Width - 1; x++) { ColorFloatPixel[] pixel_array = new ColorFloatPixel[window_size * window_size]; int n = 0; for (int j = -(window_size / 2); j <= window_size / 2; j++) { for (int i = -(window_size / 2); i <= window_size / 2; i++) { if ((x + i >= 0) && (x + i < image.Width) && (y + j >= 0) && (y + j < image.Height)) { pixel_array[n++] = image[x + i, y + j]; } } } Array.Sort(pixel_array); out_img[x, y] = pixel_array[n / 2]; } } return(out_img); }
static ColorFloatPixel InterpolateBilinear(ColorFloatPixel p0, ColorFloatPixel p1, double delta) { return(new ColorFloatPixel((float)((1 - delta) * p0.r + delta * p1.r), (float)((1 - delta) * p0.g + delta * p1.g), (float)((1 - delta) * p0.b + delta * p1.b), p1.a)); }
public static Bitmap ImageToBitmap(ColorFloatImage image) { Bitmap B = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); LockBitmapInfo lbi = LockBitmap(B); try { for (int j = 0; j < image.Height; j++) { for (int i = 0; i < image.Width; i++) { ColorFloatPixel p = image[i, j]; lbi.data[lbi.linewidth * j + i * 4] = p.b <0.0f ? (byte)0 : p.b> 255.0f ? (byte)255 : (byte)p.b; lbi.data[lbi.linewidth * j + i * 4 + 1] = p.g <0.0f ? (byte)0 : p.g> 255.0f ? (byte)255 : (byte)p.g; lbi.data[lbi.linewidth * j + i * 4 + 2] = p.r <0.0f ? (byte)0 : p.r> 255.0f ? (byte)255 : (byte)p.r; } } } finally { UnlockBitmap(lbi); } return(B); }
public static void Median(ColorFloatImage image, int rad) { float[] med = new float[(rad * 2 + 1) * (rad * 2 + 1)]; ColorFloatImage tempImg = new ColorFloatImage(image.Width, image.Height); int index = 0; for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempPixel = image[x, y]; index = 0; for (int i = -rad; i <= rad; i++) { for (int j = -rad; j <= rad; j++) { med[index] = image[((x + i) < 0 || (x + i) >= image.Width ? x : (x + i)), ((y + j) < 0 || (y + j) >= image.Height ? y : (y + j))].g; index++; } } Array.Sort(med); tempPixel.g = med[2 * rad * rad + 2 * rad + 1]; index = 0; for (int i = -rad; i <= rad; i++) { for (int j = -rad; j <= rad; j++) { med[index] = image[((x + i) < 0 || (x + i) >= image.Width ? x : (x + i)), ((y + j) < 0 || (y + j) >= image.Height ? y : (y + j))].r; index++; } } Array.Sort(med); tempPixel.r = med[2 * rad * rad + 2 * rad + 1]; index = 0; for (int i = -rad; i <= rad; i++) { for (int j = -rad; j <= rad; j++) { med[index] = image[((x + i) < 0 || (x + i) >= image.Width ? x : (x + i)), ((y + j) < 0 || (y + j) >= image.Height ? y : (y + j))].b; index++; } } Array.Sort(med); tempPixel.b = med[2 * rad * rad + 2 * rad + 1]; tempImg[x, y] = tempPixel; } } for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { image[x, y] = tempImg[x, y]; } } }
public static float BilateralPoint(int x, int y, double sigma_d, ColorFloatPixel Ix, ColorFloatPixel Iy, double sigma_r) { double mul_d = 2 * sigma_d * sigma_d; double mul_r = 2 * sigma_r * sigma_r; var a = Math.Exp(-NormSqL2(x, y) / mul_d - NormSqPixel(Ix, Iy) / mul_r); return((float)a); }
public static ColorFloatPixel operator +(ColorFloatPixel P1, ColorFloatPixel P2) { ColorFloatPixel tmp = P1; tmp.r += P2.r; tmp.g += P2.g; tmp.b += P2.b; return(tmp); }
public static ColorFloatPixel operator -(ColorFloatPixel P1, ColorFloatPixel P2) { ColorFloatPixel tmp = P1; tmp.r -= P2.r; tmp.g -= P2.g; tmp.b -= P2.b; return(tmp); }
public int CompareTo(object o) { ColorFloatPixel p = (ColorFloatPixel)o; float sum1 = this.b * this.b + this.g * this.g + this.r * this.r; float sum2 = p.b * p.b + p.g * p.g + p.r * p.r; float dif = sum1 - sum2; return(dif >= 0 ? (dif > 0 ? -1 : 0) : 1); }
public static ColorFloatPixel operator +(ColorFloatPixel P1, float P2) { ColorFloatPixel tmp = P1; tmp.r += P2; tmp.g += P2; tmp.b += P2; return(tmp); }
public static void Sobel(ColorFloatImage image, string type = "xy") { ColorFloatImage tempImg = new ColorFloatImage(image.Width + 2, image.Height + 2); ResizeImage(image, tempImg); if (type == "x") { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = SobelX(tempImg, x + 1, y + 1); /* gray substrate * tempP.a += 128; * tempP.r += 128; * tempP.g += 128; * tempP.b += 128; */ image[x, y] = tempP; } } } else if (type == "y") { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = SobelY(tempImg, x + 1, y + 1); /* gray substrate * tempP.a += 128; * tempP.r += 128; * tempP.g += 128; * tempP.b += 128; */ image[x, y] = tempP; } } } else { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempPX = SobelX(tempImg, x + 1, y + 1), tempPY = SobelY(tempImg, x + 1, y + 1), tempP; tempP.a = image[x, y].a; tempP.r = (float)Math.Sqrt(tempPX.r * tempPX.r + tempPY.r * tempPY.r); tempP.g = (float)Math.Sqrt(tempPX.g * tempPX.g + tempPY.g * tempPY.g); tempP.b = (float)Math.Sqrt(tempPX.b * tempPX.b + tempPY.b * tempPY.b); image[x, y] = tempP; } } } }
public static ColorFloatPixel operator *(ColorFloatPixel P, float n) { ColorFloatPixel tmp = new ColorFloatPixel(); tmp.a = P.a; tmp.r = P.r * n; tmp.g = P.g * n; tmp.b = P.b * n; return(tmp); }
public static ColorFloatPixel Pow(ColorFloatPixel P, float deg) { ColorFloatPixel tmp = new ColorFloatPixel(); tmp.a = P.a; tmp.r = (float)Math.Pow(P.r, deg); tmp.g = (float)Math.Pow(P.g, deg); tmp.b = (float)Math.Pow(P.b, deg); return(tmp); }
public static void Roberts(ColorFloatImage image, int type = 0) { ColorFloatImage tempImg = new ColorFloatImage(image.Width + 2, image.Height + 2); ResizeImage(image, tempImg); if (type == 1) { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = Roberts1(tempImg, x + 1, y + 1); /* tempP.a += 128; * tempP.r += 128; * tempP.g += 128; * tempP.b += 128;*/ image[x, y] = tempP; } } } else if (type == 2) { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = Roberts2(tempImg, x + 1, y + 1); /* tempP.a += 128; * tempP.r += 128; * tempP.g += 128; * tempP.b += 128;*/ image[x, y] = tempP; } } } else { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempPX = Roberts1(tempImg, x + 1, y + 1), tempPY = Roberts2(tempImg, x + 1, y + 1), tempP; tempP.a = image[x, y].a; tempP.r = (float)Math.Sqrt(tempPX.r * tempPX.r + tempPY.r * tempPY.r); tempP.g = (float)Math.Sqrt(tempPX.g * tempPX.g + tempPY.g * tempPY.g); tempP.b = (float)Math.Sqrt(tempPX.b * tempPX.b + tempPY.b * tempPY.b); image[x, y] = tempP; } } } }
public static void FlipImageY(ColorFloatImage image) { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width / 2; x++) { ColorFloatPixel p = image[x, y]; image[x, y] = image[image.Width - 1 - x, y]; image[image.Width - 1 - x, y] = p; } } }
public static ColorFloatImage InvertImage(ColorFloatImage image) //ok { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { image[x, y] = new ColorFloatPixel(255 - image[x, y].b, 255 - image[x, y].g, 255 - image[x, y].r, (image[x, y].a) / 2); } } return(image); }
public static void Prewitt(ColorFloatImage image, string type = "xy") { ColorFloatImage tempImg = new ColorFloatImage(image.Width + 2, image.Height + 2); ResizeImage(image, tempImg); if (type == "x") { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = PrewittX(tempImg, x + 1, y + 1); tempP.a += 128; tempP.r += 128; tempP.g += 128; tempP.b += 128; image[x, y] = tempP; } } } else if (type == "y") { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempP = PrewittY(tempImg, x + 1, y + 1); tempP.a += 128; tempP.r += 128; tempP.g += 128; tempP.b += 128; image[x, y] = tempP; } } } else { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel tempPX = PrewittX(tempImg, x + 1, y + 1), tempPY = PrewittY(tempImg, x + 1, y + 1), tempP; tempP.a = 128 + image[x, y].a; tempP.r = 128 + (float)Math.Sqrt(tempPX.r * tempPX.r + tempPY.r * tempPY.r); tempP.g = 128 + (float)Math.Sqrt(tempPX.g * tempPX.g + tempPY.g * tempPY.g); tempP.b = 128 + (float)Math.Sqrt(tempPX.b * tempPX.b + tempPY.b * tempPY.b); image[x, y] = tempP; } } } }
public static void FlipImageX(ColorFloatImage image) { for (int y = 0; y < image.Height / 2; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel p = image[x, y]; image[x, y] = image[x, image.Height - 1 - y]; image[x, image.Height - 1 - y] = p; } } }
public static ColorFloatImage MirrorY(ColorFloatImage image) //ok { for (int y = 0; y < image.Height / 2; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel p = image[x, y]; image[x, y] = image[x, image.Height - 1 - y]; image[x, image.Height - 1 - y] = p; } } return(image); }
public static void InvertImage(ColorFloatImage image) { for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { ColorFloatPixel p = image[x, y]; p.r = 255 - image[x, y].r; p.g = 255 - image[x, y].g; p.b = 255 - image[x, y].b; image[x, y] = p; } } }
public static void downsample(ref ColorFloatImage image, float s, string paramoff = "") { ColorFloatImage tempImg = new ColorFloatImage((int)(image.Width / s), image.Height); if (paramoff != "-off") { image = ImageProcessing.Gauss(image, (float)Math.Sqrt(Math.Abs(s * s - 1))); } float n = (image.Width * s - s) / ((float)image.Width - s); for (int y = 0; y < image.Height; ++y) { tempImg[0, y] = image[0, y]; tempImg[tempImg.Width - 1, y] = image[image.Width - 1, y]; for (int x = 1; x < tempImg.Width - 1; ++x) { ColorFloatPixel p = new ColorFloatPixel(); float x1 = (float)Math.Truncate(x * n), x2 = (int)(x * n) + 1; p.r = (x2 - (float)x * n) * image[(int)x1, y].r + ((float)x * n - x1) * image[(int)x2, y].r; p.g = (x2 - (float)x * n) * image[(int)x1, y].g + ((float)x * n - x1) * image[(int)x2, y].g; p.b = (x2 - (float)x * n) * image[(int)x1, y].b + ((float)x * n - x1) * image[(int)x2, y].b; tempImg[x, y] = p; } } image = tempImg; tempImg = new ColorFloatImage(image.Width, (int)(image.Height / s)); n = (image.Height * s - s) / ((float)image.Height - s); for (int x = 0; x < image.Width; ++x) { tempImg[x, 0] = image[x, 0]; tempImg[x, tempImg.Height - 1] = image[x, image.Height - 1]; for (int y = 1; y < tempImg.Height - 1; ++y) { ColorFloatPixel p = new ColorFloatPixel(); float y1 = (float)Math.Truncate(y * n) > image.Height - 1 ? image.Height - 1 : (float)Math.Truncate(y * n), y2 = (int)(y * n) + 1 > image.Height - 1 ? image.Height - 1 : (int)(y * n) + 1; p.r = (y2 - (float)y * n) * image[x, (int)y1].r + ((float)y * n - y1) * image[x, (int)y2].r; p.g = (y2 - (float)y * n) * image[x, (int)y1].g + ((float)y * n - y1) * image[x, (int)y2].g; p.b = (y2 - (float)y * n) * image[x, (int)y1].b + ((float)y * n - y1) * image[x, (int)y2].b; tempImg[x, y] = p; } } image = tempImg; }
private static ColorFloatPixel Conv(ColorFloatImage image, int x, int y, float[,] matr, float normValue) { ColorFloatPixel tempPixel = image[x, y]; tempPixel.r = 0; tempPixel.g = 0; tempPixel.b = 0; int n = matr.GetLength(0); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { tempPixel += matr[j, i] * image[((x + i - (n - 1) / 2) < 0 || (x + i - (n - 1) / 2) >= image.Width ? x : (x + i - (n - 1) / 2)), ((y + j - (n - 1) / 2) < 0 || (y + j - (n - 1) / 2) >= image.Height ? y : (y + j - (n - 1) / 2))]; } } tempPixel = tempPixel / normValue; return(tempPixel); }
public static void up_bilinear(ref ColorFloatImage image, float s) { ColorFloatImage tempImg = new ColorFloatImage((int)(image.Width * s), image.Height); float n = (image.Width * s - 1) / ((float)image.Width - 1); for (int y = 0; y < image.Height; ++y) { tempImg[0, y] = image[0, y]; tempImg[tempImg.Width - 1, y] = image[image.Width - 1, y]; for (int x = 1; x < tempImg.Width - 1; ++x) { ColorFloatPixel p = new ColorFloatPixel(); float x1 = (float)Math.Truncate(x / n), x2 = (int)(x / n) + 1; p.r = (x2 - (float)x / n) * image[(int)x1, y].r + ((float)x / n - x1) * image[(int)x2, y].r; p.g = (x2 - (float)x / n) * image[(int)x1, y].g + ((float)x / n - x1) * image[(int)x2, y].g; p.b = (x2 - (float)x / n) * image[(int)x1, y].b + ((float)x / n - x1) * image[(int)x2, y].b; tempImg[x, y] = p; } } image = tempImg; tempImg = new ColorFloatImage(image.Width, (int)(image.Height * s)); n = (image.Height * s - 1) / ((float)image.Height - 1); for (int x = 0; x < image.Width; ++x) { tempImg[x, 0] = image[x, 0]; tempImg[x, tempImg.Height - 1] = image[x, image.Height - 1]; for (int y = 1; y < tempImg.Height - 1; ++y) { ColorFloatPixel p = new ColorFloatPixel(); float y1 = (float)Math.Truncate(y / n), y2 = (int)(y / n) + 1; p.r = (y2 - (float)y / n) * image[x, (int)y1].r + ((float)y / n - y1) * image[x, (int)y2].r; p.g = (y2 - (float)y / n) * image[x, (int)y1].g + ((float)y / n - y1) * image[x, (int)y2].g; p.b = (y2 - (float)y / n) * image[x, (int)y1].b + ((float)y / n - y1) * image[x, (int)y2].b; tempImg[x, y] = p; } } image = tempImg; }
static ColorFloatImage mirror(ColorFloatImage image, string axis) { if (axis == "x") { ColorFloatImage out_img = image; for (int y = 0; y < out_img.Height; y++) { for (int x = 0; x < out_img.Width / 2; x++) { ColorFloatPixel p = out_img[x, y]; out_img[x, y] = out_img[out_img.Width - 1 - x, y]; out_img[out_img.Width - 1 - x, y] = p; } } return(out_img); } else if (axis == "y") { ColorFloatImage out_img = image; for (int y = 0; y < out_img.Height / 2; y++) { for (int x = 0; x < out_img.Width; x++) { ColorFloatPixel p = out_img[x, y]; out_img[x, y] = out_img[x, out_img.Height - 1 - y]; out_img[x, out_img.Height - 1 - y] = p; } } return(out_img); } else { Console.WriteLine("Wrong axis chosen"); return(image); } }
public static ColorFloatImage Gauss(ColorFloatImage image, float sigma, float gamma = 1) { ColorFloatImage tempImg = new ColorFloatImage(image.Width, image.Height); int n = (int)(6 * Math.Abs(sigma) + 1); n = n == 1 || n % 2 == 0 ? 3 : n; float[,] matr = new float[n, n]; float normValue = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { matr[i, j] = (float)Math.Exp(-((i - (n - 1) / 2) * (i - (n - 1) / 2) + (j - (n - 1) / 2) * (j - (n - 1) / 2)) / (2 * sigma * sigma)); normValue += matr[i, j]; } } for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { image[x, y] = 255.0f * ColorFloatPixel.Pow(image[x, y] / 255.0f, gamma); } } for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++) { tempImg[x, y] = 255.0f * ColorFloatPixel.Pow(Conv(image, x, y, matr, normValue) / 255.0f, 1.0f / gamma); } } return(tempImg); }
static bool IsBlankPixel(ColorFloatPixel p) { return(p.r == 0 && p.g == 0 && p.b == 0); }
public static double NormSqPixel(ColorFloatPixel x, ColorFloatPixel y) { return(Math.Pow(x.r - y.r, 2) + Math.Pow(x.g - y.g, 2) + Math.Pow(x.b - y.b, 2)); }
private static void rotate(ref ColorFloatImage image, float angle) { angle *= (float)Math.PI / 180.0f; double x1 = -image.Width / 2, y1 = -image.Height / 2, x2 = -image.Width / 2, y2 = image.Height / 2, x3 = image.Width / 2, y3 = -image.Height / 2, x4 = image.Width / 2, y4 = image.Height / 2; double tempX = x1, tempY = y1; x1 = tempX * Math.Cos(angle) - tempY * Math.Sin(angle); y1 = tempX * Math.Sin(angle) + tempY * Math.Cos(angle); tempX = x2; tempY = y2; x2 = tempX * Math.Cos(angle) - tempY * Math.Sin(angle); y2 = tempX * Math.Sin(angle) + tempY * Math.Cos(angle); tempX = x3; tempY = y3; x3 = tempX * Math.Cos(angle) - tempY * Math.Sin(angle); y3 = tempX * Math.Sin(angle) + tempY * Math.Cos(angle); tempX = x4; tempY = y4; x4 = tempX * Math.Cos(angle) - tempY * Math.Sin(angle); y4 = tempX * Math.Sin(angle) + tempY * Math.Cos(angle); int w = (int)Math.Floor(Math.Max(Math.Abs(x1 - x4), Math.Abs(x2 - x3))) + 1, h = (int)Math.Floor(Math.Max(Math.Abs(y1 - y4), Math.Abs(y2 - y3))) + 1; ColorFloatImage newIm = new ColorFloatImage(w, h); for (int i = 0; i < newIm.Width; ++i) { for (int j = 0; j < newIm.Height; ++j) { double x = (i - newIm.Width / 2) * Math.Cos(angle) + (j - newIm.Height / 2) * Math.Sin(angle), y = -(i - newIm.Width / 2) * Math.Sin(angle) + (j - newIm.Height / 2) * Math.Cos(angle); x += image.Width / 2.0; y += image.Height / 2.0; if (x < 0 || y < 0 || x > image.Width - 1 || y > image.Height - 1) { ColorFloatPixel p = new ColorFloatPixel(); p.r = 0; p.g = 0; p.b = 0; newIm[i, j] = p; } else { x1 = (int)x; y1 = (int)y; x2 = x1 + 1; y2 = y1 + 1; newIm[i, j] = image[(int)x1, (int)y1] * (float)((y2 - y) * (x2 - x)) + image[(int)x2, (int)y1] * (float)((y2 - y) * (x - x1)) + image[(int)x1, (int)y2] * (float)((y - y1) * (x2 - x)) + image[(int)x2, (int)y2] * (float)((y - y1) * (x - x1)); } } } image = newIm; }