private static void PadBorders(PNM image, int padding) { // copy top and bottom for (int i = 0; i < padding; i++) { Buffer.BlockCopy(image.raster, 3 * (padding * image.Width + padding), image.raster, 3 * (i * image.Width + padding), (image.Width - padding * 2) * 3); Buffer.BlockCopy(image.raster, 3 * ((image.Height - padding - 1) * image.Width + padding), image.raster, 3 * ((i + image.Height - padding) * image.Width + padding), (image.Width - padding * 2) * 3); } // pad right and left for (int i = 0; i < image.Height - (2 * padding); i++) { byte r, g, b; image.GetPixel(padding, padding + i, out r, out g, out b); for (int j = 0; j < padding; j++) { image.SetPixel(j, padding + i, r, g, b); } image.GetPixel(image.Width - padding - 1, padding + i, out r, out g, out b); for (int j = 0; j < padding; j++) { image.SetPixel(image.Width - j - 1, padding + i, r, g, b); } } }
private static PNM ApplyConvolutionMatrixCore(PNM image, float[] matrix, int matrixLength, float weight, float shift) { PNM newImage = new PNM(image.Width, image.Height); int padding = matrixLength / 2; int maxHeight = newImage.Height - padding; int maxWidth = newImage.Width - padding; int width = newImage.Width; Parallel.For(padding, maxHeight, i => { for (int j = padding; j < maxWidth; j++) { float sumR = 0; float sumG = 0; float sumB = 0; // current index position int position = i * width + j; for (int m = 0; m < matrixLength; m++) { for (int n = 0; n < matrixLength; n++) { byte r, g, b; image.GetPixel(position - ((padding - m) * width) - (padding - n), out r, out g, out b); float coeff = matrix[(m * matrixLength) + n]; sumR += (r * coeff * weight); sumG += (g * coeff * weight); sumB += (b * coeff * weight); } } newImage.SetPixel(position, Coerce(sumR + shift), Coerce(sumG + shift), Coerce(sumB + shift)); } }); return(newImage); }
private static void PadCorners(PNM image, int padding) { byte r, g, b; // pad top left image.GetPixel(padding, padding, out r, out g, out b); for (int i = 0; i < padding; i++) { for (int j = 0; j < padding; j++) { image.SetPixel(i, j, r, g, b); } } // pad top right image.GetPixel(image.Width - padding - 1, padding, out r, out g, out b); for (int i = image.Width - padding; i < image.Width; i++) { for (int j = 0; j < padding; j++) { image.SetPixel(i, j, r, g, b); } } // pad bottom left image.GetPixel(padding, image.Height - padding - 1, out r, out g, out b); for (int i = 0; i < padding; i++) { for (int j = image.Height - padding; j < image.Height; j++) { image.SetPixel(i, j, r, g, b); } } // pad bottom right image.GetPixel(image.Width - padding - 1, image.Height - padding - 1, out r, out g, out b); for (int i = image.Width - padding; i < image.Width; i++) { for (int j = image.Height - padding; j < image.Height; j++) { image.SetPixel(i, j, r, g, b); } } }
public static PNM ApplyPointProcessing(this PNM oldImage, Func <byte, byte, byte, Pixel> filter) { PNM newImage = new PNM(oldImage.Width, oldImage.Height); byte r, g, b; int size = oldImage.Width * oldImage.Height; for (int i = 0; i < size; i++) { oldImage.GetPixel(i, out r, out g, out b); Pixel pixel = filter(r, g, b); newImage.SetPixel(i, pixel.Red, pixel.Green, pixel.Blue); } ; return(newImage); }
// poor man's pixel shader private static PNM ApplyConvolutionFunctionCore(PNM image, int matrixLength, Func <PNM, int, Pixel> func) { PNM newImage = new PNM(image.Width, image.Height); int padding = matrixLength / 2; int maxHeight = newImage.Height - padding; int maxWidth = newImage.Width - padding; int width = newImage.Width; Parallel.For(padding, maxHeight, i => { for (int j = padding; j < maxWidth; j++) { // current index position int position = i * width + j; newImage.SetPixel(position, func(image, position)); } }); return(newImage); }
private static PNM ApplyHeightMapFunctionCore(int imgWidth, int imgHeight, float[] heightmap, int matrixLength, Func <int, int, float[], int, Pixel> func) { PNM newImage = new PNM(imgWidth, imgHeight); int padding = matrixLength / 2; int maxHeight = imgHeight - padding; int maxWidth = imgWidth - padding; int width = imgWidth; Parallel.For(padding, maxHeight, i => { for (int j = padding; j < maxWidth; j++) { // current index position int position = i * width + j; newImage.SetPixel(position, func(imgWidth, imgHeight, heightmap, position)); } }); return(newImage); }
private static void MarkPixel(PNM image, int index) { int x = index % image.Width; int y = index / image.Width; for (int x0 = -1; x0 <= 1; x0++) { for (int y0 = -1; y0 <= 1; y0++) { if (x0 == 0 && y0 == 0) { continue; } int currentY = y + y0; int currentX = x + x0; if (currentX < 0 || currentX >= image.Width || currentY < 0 || currentY >= image.Height) { continue; } image.SetPixel(x + x0, y + y0, 0, 255, 0); } } }
//this should be rewritten to ApplyConvolutionFunction public static PNM ApplyGradientEdgesDetection(this PNM image) { PNM workImage = PNM.Copy(image); Pad(workImage, 1); Tuple <float[], float[], float[]> xraster = ApplyConvolutionUnbound(workImage, new float[] { -1, 0, 1, -1, 0, 1, -1, 0, 1 }, 3); Tuple <float[], float[], float[]> yraster = ApplyConvolutionUnbound(workImage, new float[] { 1, 1, 1, 0, 0, 0, -1, -1, -1 }, 3); PNM newImage = new PNM(image.Width, image.Height); int size = image.Width * image.Height; Parallel.For(0, size, i => { byte r = Coerce(Math.Sqrt(Math.Pow(xraster.Item1[i], 2) + Math.Pow(yraster.Item1[i], 2))); byte g = Coerce(Math.Sqrt(Math.Pow(xraster.Item2[i], 2) + Math.Pow(yraster.Item2[i], 2))); byte b = Coerce(Math.Sqrt(Math.Pow(xraster.Item3[i], 2) + Math.Pow(yraster.Item3[i], 2))); newImage.SetPixel(i, r, g, b); }); return(newImage); }
private static void MarkPixel(PNM image, int index) { int x = index % image.Width; int y = index / image.Width; for (int x0 = -1; x0 <= 1; x0++) { for (int y0 = -1; y0 <= 1; y0++) { if(x0 == 0 && y0 == 0) continue; int currentY = y + y0; int currentX = x + x0; if(currentX < 0 || currentX >= image.Width || currentY < 0 || currentY >= image.Height) continue; image.SetPixel(x + x0, y + y0, 0, 255, 0); } } }