public static WpGrayscaleImage NormalizeImage(WpGrayscaleImage texture) { byte[] origPixels = texture.GetPixels(); byte[] resPixels = texture.GetPixels(); float maxBrightness = 0.0f; float minBrightness = 1.0f; //Get max brightness for (int x = 0; x < texture.Width; x++) { for (int y = 0; y < texture.Height; y++) { maxBrightness = Mathf.Max(maxBrightness, origPixels[y * texture.Width + x] / 255.0f); minBrightness = Mathf.Min(minBrightness, origPixels[y * texture.Width + x] / 255.0f); } } //Normalize for (int x = 0; x < texture.Width; x++) { for (int y = 0; y < texture.Height; y++) { resPixels[y * texture.Width + x] = (byte) (255.0f * (resPixels[y * texture.Width + x] / 255.0f - minBrightness) / (maxBrightness - minBrightness)); } } WpGrayscaleImage resultTexture = new WpGrayscaleImage(texture.Width, texture.Height, resPixels); return(resultTexture); }
public static WpGrayscaleImage Blur(WpGrayscaleImage texture, int blurSize, WpBlurType blurType) { //Build weight table float[,] blurWeightTable = new float[blurSize + 1, blurSize + 1]; for (int x = 0; x <= blurSize; x++) { for (int y = 0; y <= blurSize; y++) { switch (blurType) { case WpBlurType.Box: blurWeightTable[x, y] = GetBoxBlurWeight(blurSize); break; case WpBlurType.Expand: blurWeightTable[x, y] = GetExpandBlurWeight(blurSize); break; default: blurWeightTable[x, y] = GetGaussianWeight(blurSize, x, y); break; } } } byte[] srcPixels = texture.GetPixels(); byte[] resPixels = WpGrayscaleImage.ValuePixels(texture.Width, texture.Height, 0); // look at every pixel in the blur rectangle for (int x = 0; x < texture.Width; x++) { for (int y = 0; y < texture.Height; y++) { //Keep alpha intact float blurredColor = 0.0f; for (int xx = x - blurSize; xx <= x + blurSize; xx++) { if (xx < 0 || xx >= texture.Width) { continue; } for (int yy = y - blurSize; yy <= y + blurSize; yy++) { if (yy < 0 || yy >= texture.Height) { continue; } float blurWeight = blurWeightTable[Mathf.Abs(xx - x), Mathf.Abs(yy - y)]; blurredColor += blurWeight * srcPixels[yy * texture.Width + xx] / 255.0f; } } resPixels[y * texture.Width + x] = (byte)(blurredColor * 255.0f); } } return(new WpGrayscaleImage(texture.Width, texture.Height, resPixels)); }
public static WpGrayscaleImage Gradient(WpGrayscaleImage borderMask, int gradientSize, float gradientMin, float gradientMax, WpGradientType gradientType) { byte[] resPixels = WpGrayscaleImage.ValuePixels(borderMask.Width, borderMask.Height, 255); //Colorize (start from the end, i.e. most expanded borders). for (int i = gradientSize; i >= 0; i--) { WpGrayscaleImage dilatedBorder = ExpandBorder(borderMask, i); byte[] currentBorderPixels = dilatedBorder.GetPixels(); for (int x = 0; x < borderMask.Width; x++) { for (int y = 0; y < borderMask.Height; y++) { if (currentBorderPixels[y * borderMask.Width + x] < 255) { continue; } float gradientAmount = i / (float)gradientSize; switch (gradientType) { default: gradientAmount = 1.0f - gradientAmount; break; case WpGradientType.OneMinusSqr: gradientAmount = 1.0f - gradientAmount * gradientAmount; break; case WpGradientType.SqrOfOneMinusG: gradientAmount = 1.0f - gradientAmount; gradientAmount = gradientAmount * gradientAmount; break; } gradientAmount = gradientAmount * (gradientMax - gradientMin) + gradientMin; resPixels[y * borderMask.Width + x] = (byte)(gradientAmount * 255.0f); } } GC.Collect(); } WpGrayscaleImage resTexture = new WpGrayscaleImage(borderMask.Width, borderMask.Height, resPixels); return(resTexture); }
public static WpGrayscaleImage ExpandBorder(WpGrayscaleImage borderMask, int expandByPixels) { byte[] borderMaskPixels = borderMask.GetPixels(); byte[] resPixels = WpGrayscaleImage.ValuePixels(borderMask.Width, borderMask.Height, 0); //Fill with black for (int x = 0; x < borderMask.Width; x++) { for (int y = 0; y < borderMask.Height; y++) { //Keep only border pixels if (borderMaskPixels[y * borderMask.Width + x] < 255) { continue; } for (int xx = x - expandByPixels; xx <= x + expandByPixels; xx++) { if (xx < 0 || xx >= borderMask.Width) { continue; } for (int yy = y - expandByPixels; yy <= y + expandByPixels; yy++) { if (yy < 0 || yy >= borderMask.Height) { continue; } resPixels[yy * borderMask.Width + xx] = 255; } } } } WpGrayscaleImage resTexture = new WpGrayscaleImage(borderMask.Width, borderMask.Height, resPixels); return(resTexture); }
public static WpGrayscaleImage ResizeImage(WpGrayscaleImage texture, int width, int height, WpFilteringMethod filteringMethod) { if (texture == null) { Debug.LogWarning("ResizeImage: input texture is null"); return(null); } byte[] srcPixels = texture.GetPixels(); byte[] dstPixels = new byte[width * height]; float xRatio = texture.Width / (float)width; float yRatio = texture.Height / (float)height; //Resize using bilinear interpolation for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { float xx = x * xRatio; float yy = y * yRatio; //Get neighbour pixels in the original image var x0 = Mathf.FloorToInt(xx); var x1 = Mathf.CeilToInt(xx); var y0 = Mathf.FloorToInt(yy); var y1 = Mathf.CeilToInt(yy); //Avoid having the same pixel if (x1 == x0) { x1 = x0 + 1; } if (y1 == y0) { y1 = y0 + 1; } //Avoid crossing the image borders if (x1 < 0) { x1 = 0; } if (x1 >= texture.Width) { x1 = texture.Width - 1; } if (y1 < 0) { y1 = 0; } if (y1 >= texture.Height) { y1 = texture.Height - 1; } float b1 = srcPixels[y0 * texture.Width + x0]; float b2 = srcPixels[y0 * texture.Width + x1] - (float)srcPixels[y0 * texture.Width + x0]; float b3 = srcPixels[y1 * texture.Width + x0] - (float)srcPixels[y0 * texture.Width + x0]; float b4 = srcPixels[y0 * texture.Width + x0] - (float)srcPixels[y0 * texture.Width + x1] - srcPixels[y1 * texture.Width + x0] + srcPixels[y1 * texture.Width + x1]; var interpolatedColor = (byte)((b1 + b2 * (xx - x0) + b3 * (yy - y0) + b4 * (xx - x0) * (yy - y0))); dstPixels[y * width + x] = interpolatedColor; } } WpGrayscaleImage resTexture = new WpGrayscaleImage(width, height, dstPixels); return(resTexture); }
public static Texture2D MakeTexture2D(WpGrayscaleImage r, WpGrayscaleImage g, WpGrayscaleImage b, WpGrayscaleImage a) { bool doDimensionsMatch = true; if (r != null && g != null) { if (r.Width != g.Width || r.Height != g.Height) { doDimensionsMatch = false; } } if (g != null && b != null) { if (g.Width != b.Width || g.Height != b.Height) { doDimensionsMatch = false; } } if (b != null && r != null) { if (b.Width != r.Width || b.Height != r.Height) { doDimensionsMatch = false; } } if (!doDimensionsMatch) { Debug.LogError("Cannot make a texture - dimensions mismatch."); g = null; b = null; a = null; } if (r == null) { return(null); } Texture2D resultTexture = new Texture2D(r.Width, r.Height, TextureFormat.ARGB32, false); Color[] resPixels = new Color[r.Width * r.Height]; byte[] gPixels = null; byte[] bPixels = null; byte[] aPixels = null; var rPixels = r.GetPixels(); if (g != null) { gPixels = g.GetPixels(); } if (b != null) { bPixels = b.GetPixels(); } if (a != null) { aPixels = a.GetPixels(); } for (int i = 0; i < r.Width * r.Height; i++) { resPixels[i].r = rPixels[i] / 255.0f; if (g != null) { resPixels[i].g = gPixels[i] / 255.0f; } else { resPixels[i].g = 0.0f; } if (b != null) { resPixels[i].b = bPixels[i] / 255.0f; } else { resPixels[i].b = 0.0f; } if (a != null) { resPixels[i].a = aPixels[i] / 255.0f; } else { resPixels[i].a = 1.0f; } } resultTexture.SetPixels(resPixels); resultTexture.Apply(); return(resultTexture); }