Esempio n. 1
0
        public static void Blur(Bitmap original, Bitmap blurred, int radius)
        {
            if (radius < 1)
            {
                throw new ArgumentOutOfRangeException("radius", "Radius must be > 0.");
            }

            int width = original.Width;
            int height = original.Height;
            int wm = width - 1;
            int hm = height - 1;
            int wh = width * height;
            int div = radius + radius + 1;
            int[] a = new int[wh];
            int[] r = new int[wh];
            int[] g = new int[wh];
            int[] b = new int[wh];
            int asum, rsum, gsum, bsum;
            int x, y, i;
            int p1, p2;
            int[] vmin = new int[Math.Max(width, height)];
            int[] vmax = new int[Math.Max(width, height)];
            int[] dv = new int[256 * div];
            for (i = 0; i < 256 * div; i++)
            {
                dv[i] = i / div;
            }

            int[] blurredBitmap = new int[wh];
            original.GetPixels(blurredBitmap, 0, width, 0, 0, width, height);
            Premultiply(blurredBitmap);

            int yw = 0;
            int yi = 0;

            for (y = 0; y < height; y++)
            {
                asum = 0;
                rsum = 0;
                gsum = 0;
                bsum = 0;
                for (i = -radius; i <= radius; i++)
                {
                    int p = blurredBitmap[yi + Math.Min(wm, Math.Max(i, 0))];
                    asum += A(p);
                    rsum += R(p);
                    gsum += G(p);
                    bsum += B(p);
                }
                for (x = 0; x < width; x++)
                {
                    a[yi] = dv[asum];
                    r[yi] = dv[rsum];
                    g[yi] = dv[gsum];
                    b[yi] = dv[bsum];

                    if (y == 0)
                    {
                        vmin[x] = Math.Min(x + radius + 1, wm);
                        vmax[x] = Math.Max(x - radius, 0);
                    }
                    p1 = blurredBitmap[yw + vmin[x]];
                    p2 = blurredBitmap[yw + vmax[x]];

                    asum += A(p1) - A(p2);
                    rsum += R(p1) - R(p2);
                    gsum += G(p1) - G(p2);
                    bsum += B(p1) - B(p2);

                    yi++;
                }
                yw += width;
            }

            for (x = 0; x < width; x++)
            {
                asum = rsum = gsum = bsum = 0;
                int yp = -radius * width;
                for (i = -radius; i <= radius; i++)
                {
                    yi = Math.Max(0, yp) + x;
                    asum += a[yi];
                    rsum += r[yi];
                    gsum += g[yi];
                    bsum += b[yi];
                    yp += width;
                }
                yi = x;
                for (y = 0; y < height; y++)
                {
                    blurredBitmap[yi] = (dv[asum] << 24) | (dv[rsum] << 16) | (dv[gsum] << 8) | (dv[bsum]);
                    if (x == 0)
                    {
                        vmin[y] = Math.Min(y + radius + 1, hm) * width;
                        vmax[y] = Math.Max(y - radius, 0) * width;
                    }
                    p1 = x + vmin[y];
                    p2 = x + vmax[y];

                    asum += a[p1] - a[p2];
                    rsum += r[p1] - r[p2];
                    gsum += g[p1] - g[p2];
                    bsum += b[p1] - b[p2];

                    yi += width;
                }
            }

            Unpremultiply(blurredBitmap);
            blurred.SetPixels(blurredBitmap, 0, width, 0, 0, width, height);
        }
        private static Bitmap ChangeColor(Bitmap bitmap, Color fromColor, Color targetColor, float tolerance = 20)
        {
            int width = bitmap.Width;
            int height = bitmap.Height;
            int[] pixels = new int[width * height];

            float[] redRange = new float[2]{
                (float)Math.Max(fromColor.R - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.R + (tolerance / 2), 255.0)};

            float[] greenRange = new float[2]{
                (float)Math.Max(fromColor.G - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.G + (tolerance / 2), 255.0)};

            float[] blueRange = new float[2]{
                (float)Math.Max(fromColor.B - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.B + (tolerance / 2), 255.0)};

            bitmap.GetPixels(pixels, 0, width, 0, 0, width, height);

            for (int i = 0; i < pixels.Length; i++)
            {

                if (pixels[i] == fromColor)
                {
                    pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1);
                }

                int red = Color.GetRedComponent(pixels[i]);
                int green = Color.GetGreenComponent(pixels[i]);
                int blue = Color.GetBlueComponent(pixels[i]);
                int alpha = Color.GetAlphaComponent(pixels[i]);

                if (((red >= redRange[0]) && (red <= redRange[1])) &&
                    ((green >= greenRange[0]) && (green <= greenRange[1])) &&
                    ((blue >= blueRange[0]) && (blue <= blueRange[1])) &&
                    ((alpha > 0 && alpha < 254)))
                {
                    pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1);
                }
            }

            if (bitmap.IsMutable)
            {
                bitmap.SetPixels(pixels, 0, width, 0, 0, width, height);
                return bitmap;
            }
            else
            {
                var mutableBitmap = bitmap.Copy(bitmap.GetConfig(), true);
                mutableBitmap.SetPixels(pixels, 0, width, 0, 0, width, height);
                return mutableBitmap;
            }
        }