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

1.1k views Asked by At

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.

3

There are 3 answers

0
HomerPlata On BEST ANSWER

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);
}
0
MariusBudin On

You could get the Bitmap from your drawable and set a color filter, check out this link:

How to change Bitmap image color in android?

I use this approach when I need multiple color shades of a drawable, just draw it black and then apply color filters

0
K Roobroeck On

You need to make a selector xml file which is described here http://developer.android.com/guide/topics/resources/drawable-resource.html

Possible implementation would look like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_focused_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/button_focused" android:state_focused="true"/>
    <item android:drawable="@drawable/button_disabled" android:state_enabled="false"/>
    <item android:drawable="@drawable/button_normal"/>

For each supported button state you will need to make a new .png . Save this file in drawable folder of your resources (for instance button.xml) and apply it to your button as you would apply a normal png.