Android PorterDuff.Mode.DST_IN combined with Bitmap.Config.ALPHA_8
<p>I was playing around with Bitmaps masking and occasionally found an interesting issue when trying to draw <code>ALPHA_8</code> bitmap mask with <code>PorterDuff.Mode.DST_IN</code> Paint. It just doesn't work, at least on Android 6.x and 5.x.<br>
Here is my sample drawable code:
</p>

<pre class="lang-java prettyprint-override"><code>public class MaskedDrawablePorterDuffDstIn extends Drawable {

    private Bitmap mPictureBitmap;
    private Bitmap mMaskBitmap;
    private Bitmap mBufferBitmap;
    private Canvas mBufferCanvas;
    private final Paint mPaintDstIn = new Paint();

    public MaskedDrawablePorterDuffDstIn() {
        mPaintDstIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @Override
    public void draw(Canvas canvas) {
        if (mPictureBitmap == null || mMaskBitmap == null) {
            return;
        }

        mBufferCanvas.drawBitmap(mPictureBitmap, 0, 0, null);
        mBufferCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaintDstIn);
        canvas.drawBitmap(mBufferBitmap, 0, 0, null);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        final int width = bounds.width();
        final int height = bounds.height();

        if (width &lt;= 0 || height &lt;= 0) {
            return;
        }

        mBufferBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mBufferCanvas = new Canvas(mBufferBitmap);
    }
...
</code></pre>

<p>When <code>mMaskBitmap</code> has <code>ARGB_8888</code> config it works just fine. But when I use <code>ALPHA_8</code> it doesn't. The picture is not masked at all in that case.  </p>

<p>Here is how I load resources in the Activity:  </p>

<pre class="lang-java prettyprint-override"><code>private void loadImages() {
    mPictureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.picture);
    mMaskBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mask_circle).extractAlpha();
}
</code></pre>

<p>Please note the <code>.extractAlpha()</code> which is giving me the <code>ALPHA_8</code> bitmap.</p>

<p>Here is how I use the Drawable:</p>

<pre class="lang-java prettyprint-override"><code>public void setDrawablePDDstIn(View view) {
    MaskedDrawablePorterDuffDstIn maskedDrawable = new MaskedDrawablePorterDuffDstIn();
    maskedDrawable.setPictureBitmap(mPictureBitmap);
    maskedDrawable.setMaskBitmap(mMaskBitmap);
    mImageView.setImageDrawable(maskedDrawable);
}
</code></pre>

<p>What is even more interesting, when I try an alternative approach, drawing the mask first and then drawing the picture with <code>SRC_IN</code> Paint - it works fine again, even with <code>ALPHA_8</code> mask:  </p>

<pre class="lang-java prettyprint-override"><code>public class MaskedDrawablePorterDuffSrcIn extends Drawable {

    private Bitmap mPictureBitmap;
    private Bitmap mMaskBitmap;
    private Bitmap mBufferBitmap;
    private Canvas mBufferCanvas;
    private final Paint mPaintSrcIn = new Paint();

    public MaskedDrawablePorterDuffSrcIn() {
        mPaintSrcIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    }
    @Override
    public void draw(Canvas canvas) {
        if (mPictureBitmap == null || mMaskBitmap == null) {
            return;
        }

        mBufferCanvas.drawBitmap(mMaskBitmap, 0, 0, null);
        mBufferCanvas.drawBitmap(mPictureBitmap, 0, 0, mPaintSrcIn);

        //dump the buffer
        canvas.drawBitmap(mBufferBitmap, 0, 0, null);
    }
</code></pre>

<p>...</p>

<p>Here is a link to the whole project I experimented with at <a href="https://github.com/ArkadyGamza/MaskingBitmaps" rel="noreferrer">GitHub</a>. It contains both non-working and working solution, feel free to play with.</p>

<p>Anyone has an idea why combination of <code>DST_IN</code> and <code>ALPHA_8</code> doesn't work as expected?</p>