Search code examples
javaandroidcolorfilter

How to swap red and blue in a drawable in Android?


can anyone tell me an efficient way of applying a colour filter to a Drawable in Android that will basically turn blue red and red blue?

I have a functioning example in Java, but this is not compatible in Android:

public class ColourSwapTest extends JFrame {

    private JPanel panel;
    private boolean altImageOnShow = false;

    public static void main(String[] args){
        new ColourSwapTest();
    }

    public ColourSwapTest(){
        init();

        Container container = this.getContentPane();

        panel = new JPanel(){
            @Override
            public void paint(Graphics g){
                if (altImageOnShow){
                    g.drawImage(img, 0, 0, null);
                }
                else {
                    g.drawImage(src, 0, 0,  null);
                }
            }
        };
        panel.addMouseListener(new MouseAdapter(){
            @Override
            public void mouseClicked(MouseEvent arg0){
                // alternate between original and filtered image
                if (altImageOnShow){
                    altImageOnShow = false;
                }
                else {
                    altImageOnShow = true;
                }
                repaint();
            }
        });
        container.add(panel, BorderLayout.CENTER);

        this.setSize(800,600);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    private String dir = "c:/Test Images/2.jpg";
    private Image src;
    private ImageFilter colourFilter;
    private Image img;

    /**
     * init()
     */
    private void init(){
        try {  
            src = ImageIO.read(new File(dir));  
        }
        catch (IOException e) {  
            e.printStackTrace();
        }
        colourFilter = new RedBlueSwapFilter();
        // apply filter to new image
        img = createImage(new FilteredImageSource(src.getSource(), colourFilter));
    }

    /**
     * CLASS
     * RedBlueSwapFilter
     */
    class RedBlueSwapFilter extends RGBImageFilter {
        public RedBlueSwapFilter() {
            canFilterIndexColorModel = true;
        }

        public int filterRGB(int x, int y, int rgb) {
            return ((rgb & 0xff00ff00)
                    | ((rgb & 0xff0000) >> 16)
                    | ((rgb & 0xff) << 16));
        }
    }
}

This will just load in the image found at C:\Test Images\2.jpg and switch between its original and altered states when you click on it.

If anyone can advise on how to get this into Android, I would be most appreciative. Thanks.

EDIT: I should add, the clicking on the image to toggle it is totally unimportant, that was just what I did to demonstrate it working. The key thing I need is to PROGRAMMATICALLY flip the colours red and blue at runtime, as efficiently as possible.


Solution

  • I've solved it, chaps. The method is as follows:

    private Drawable invertImage(Drawable inputDrawable){
        Bitmap bitmap = ((BitmapDrawable) inputDrawable).getBitmap();
    
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
    
        int[] pixels = new int[width * height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    
        int[] finalArray = new int[width * height];
    
        for(int i = 0; i < finalArray.length; i++) {
            int red = Color.red(pixels[i]);
            int green = Color.green(pixels[i]);
            int blue = Color.blue(pixels[i]);
            finalArray[i] = Color.rgb(blue, green, red);
        }
        bitmap = Bitmap.createBitmap(finalArray, width, height, Bitmap.Config.ARGB_8888);
    
        return new BitmapDrawable(getResources(),bitmap);
    }