public void filter(Filter kind, float param = -1f) { var p = new Color[texture.Width * texture.Height]; texture.GetData(p); switch (kind) { case Filter.THRESHOLD: if (param < 0f || param > 1f) { param = 0.5f; } p = p.AsParallel().AsOrdered() .Select(c => (grey: (int)((0.3 * c.R) + (0.59 * c.G) + (0.11 * c.B)), c.A)) .Select(t => (grey: t.grey / 255.0 < param ? 255 : 0, t.A)) .Select(t => Color.FromNonPremultiplied(t.grey, t.grey, t.grey, t.A)).ToArray(); break; case Filter.GRAY: p = p.AsParallel().AsOrdered() .Select(c => (grey: (int)((0.3 * c.R) + (0.59 * c.G) + (0.11 * c.B)), c.A)) .Select(t => Color.FromNonPremultiplied(t.grey, t.grey, t.grey, t.A)).ToArray(); break; case Filter.OPAQUE: p = p.AsParallel().AsOrdered().Select(c => Color.FromNonPremultiplied(c.R, c.G, c.B, 255)) .ToArray(); break; case Filter.INVERT: p = p.AsParallel().AsOrdered() .Select(c => Color.FromNonPremultiplied(255 - c.R, 255 - c.G, 255 - c.B, c.A)).ToArray(); break; case Filter.POSTERIZE: if (param < 2f) { param = 2f; } if (param > 255f) { param = 255f; } p = p.AsParallel().AsOrdered() .Select(c => Color.FromNonPremultiplied((int)Math.Min(c.R, param), (int)Math.Min(c.G, param), (int)Math.Min(c.B, param), c.A)).ToArray(); break; case Filter.BLUR: case Filter.ERODE: case Filter.DILATE: break; } texture.SetData(p); }