/*
* Copyright (C) 2011 Cyril Mottier (http://www.cyrilmottier.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package greendroid.image;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
/**
* An {@link ImageProcessor} that masks the given Bitmap according to a shape or
* another Bitmap.
*
* @author Cyril Mottier
*/
public class MaskImageProcessor implements ImageProcessor {
private static final int CUSTOM = 1;
private static final int RECTANGLE = 2;
private int mShape;
private float mRadius;
private float[] mRadiiArray;
private Bitmap mMaskBitmap;
private final Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path mPath = new Path();
private final RectF mRect = new RectF();
/**
* Create a new MaskImageProcessor using a simple rectangle as mask.
* Specifying a radius > 0, enable clients to use a rounded rectangle,
* rather than a rectangle.
*
* @param radius The radius for the corners of the rectangle.
*/
public MaskImageProcessor(float radius) {
init();
mShape = RECTANGLE;
if (radius < 0) {
radius = 0;
}
mRadius = radius;
}
/**
* <p>
* Create a new MaskImageProcessor using a simple rectangle as mask.
* Specifying a radius > 0, enable clients to use a rounded rectangle,
* rather than a rectangle.
* </p>
* <p>
* Specify radii for each of the 4 corners. For each corner, the array
* contains 2 values, [X_radius, Y_radius]. The corners are ordered
* top-left, top-right, bottom-right, bottom-left
* </p>
*
* @param radii The radii for the corners of the rectangle
* @see Path#addRoundRect(RectF, float[], android.graphics.Path.Direction)
*/
public MaskImageProcessor(float[] radii) {
init();
mShape = RECTANGLE;
mRadiiArray = radii;
if (radii == null) {
mRadius = 0;
}
}
/**
* <p>
* Create a new MaskImageProcessor using the specified Bitmap as mask.
* </p>
*
* @param maskBitmap The Bitmap used for masking
*/
public MaskImageProcessor(Bitmap maskBitmap) {
init();
mShape = CUSTOM;
mMaskBitmap = maskBitmap;
}
private void init() {
mFillPaint.setColor(Color.RED);
mMaskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
}
public Bitmap processImage(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
mRect.set(0, 0, width, height);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
switch (mShape) {
case CUSTOM:
canvas.drawBitmap(mMaskBitmap, 0, 0, mFillPaint);
break;
case RECTANGLE:
default:
if (mRadiiArray != null) {
mPath.reset();
mPath.addRoundRect(mRect, mRadiiArray, Path.Direction.CW);
canvas.drawPath(mPath, mFillPaint);
} else {
float rad = mRadius;
float r = Math.min(width, height) * 0.5f;
if (rad > r) {
rad = r;
}
canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
}
break;
}
canvas.drawBitmap(bitmap, 0, 0, mMaskPaint);
return result;
}
}