+
+ private static abstract class Filter {
+ @NotNull
+ abstract int[] convert(@NotNull int[] rgba);
+ }
+
+ private static class ColorFilter extends Filter {
+ private final float[] myBase;
+ private final boolean myKeepGray;
+
+ private ColorFilter(@NotNull Color color, boolean keepGray) {
+ myKeepGray = keepGray;
+ myBase = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+ }
+
+ @NotNull
+ @Override
+ int[] convert(@NotNull int[] rgba) {
+ float[] hsb = new float[3];
+ Color.RGBtoHSB(rgba[0], rgba[1], rgba[2], hsb);
+ int rgb = Color.HSBtoRGB(myBase[0], myBase[1] * (myKeepGray ? hsb[1] : 1f), myBase[2] * hsb[2]);
+ return new int[]{rgb >> 16 & 0xff, rgb >> 8 & 0xff, rgb & 0xff, rgba[3]};
+ }
+ }
+
+ private static class DesaturationFilter extends Filter {
+ @NotNull
+ @Override
+ int[] convert(@NotNull int[] rgba) {
+ int min = Math.min(Math.min(rgba[0], rgba[1]), rgba[2]);
+ int max = Math.max(Math.max(rgba[0], rgba[1]), rgba[2]);
+ int grey = (max + min) / 2;
+ return new int[]{grey, grey, grey, rgba[3]};
+ }
+ }