You can create two different Bitmaps:
- one that includes your normal background, lines, shapes and any draw you want (be sure to stay INSIDE your choosed bounds)
- one that is the shape used to CUT the previous one via "Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.xxxxxxx))" method (do a "PorterDuffXfermode" search on Google Images to see all mixes possibilities)
In this way you are free to draw what you want in a normal rectangular/squared Bitmap, and at the end you apply a Mask (over the whole Bitmap) using a free shape (triangular, circular, etc..). Same tecnique is used to create a circular picture starting from the original rectangular version.
For example this code creates a rounded version of a rectangular Bitmap:
@Nullable
public static Bitmap getRoundedBitmap(@Nullable final Bitmap bmp, final int radius) {
if ((bmp == null) || (radius < 1)) return null;
Bitmap cBitmap;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float cSmallest = Math.min(bmp.getWidth(), bmp.getHeight());
float cFactor = cSmallest / radius;
try {
cBitmap = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / cFactor), (int)(bmp.getHeight() / cFactor), true);
} catch (Exception e) {
cBitmap = null;
}
} else cBitmap = bmp;
if (cBitmap == null) return null;
final Bitmap cOutput = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
final Canvas cCanvas = new Canvas(cOutput);
final Paint cPaint = new Paint();
final Rect cRect = new Rect(0, 0, radius, radius);
cPaint.setAntiAlias(true);
cPaint.setFilterBitmap(true);
cPaint.setDither(true);
cPaint.setStyle(Paint.Style.FILL);
cCanvas.drawARGB(0, 0, 0, 0);
cPaint.setColor(Color.BLACK);
cCanvas.drawCircle(radius / 2f, radius / 2f, radius / 2f, cPaint);
cPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//draws the rectangular Bitmap and use the special Paint object that has the circular "mask" set
cCanvas.drawBitmap(cBitmap, cRect, cRect, cPaint);
return cOutput;
}