Drawableのコピーを作成する(Android)

Android で Drawableを使っているとシャローコピーではなく、
ディープコピーが欲しくなることがあります。

wikiから引用します。

シャローコピーとは

浅いコピーを指します。
変数が値を指す場合は値がコピーされます。
もしも変数がアドレスを指すならば、シャローコピーされた変数はアドレスを持ちます。
※アドレスを指すとはAndroid JAVAで言うとオブジェクトを継承したもの全てを指します。

ディープコピーとは

深いコピーを指します。
実はディープコピーではデータはアドレスと共にもう一度コピーされます。
AからBへディープコピーした場合、お互いに影響を与えることがありません。
しかし、コピー速度はシャローコピーより遅いです。

実際のコードでは以下のようになります。
例としてここではDrawableにGrayScaleをかけています。

DrawableをシャローコピーしてGrayScale

Drawable a = 
    Drawable.createFromStream(context.getAssets().open("path/to/img");
Drawable b;
b = a;

ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
b.setColorFilter(filter); // aもグレイスケール化してしまう。

DrawableをディープコピーしてGrayScale

Drawable a = 
    Drawable.createFromStream(context.getAssets().open("path/to/img");
Drawable b;
b = a.getConstantState().newDrawable().mutate();

ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
b.setColorFilter(filter); // bのみがグレイスケール化する。

Drawableは画像を扱う場合、大変便利ですが、
中身を意識しなくなるため注意が必要な気がします。